import go.*; public class GoTorus { double radius; int slices; double ringRadius; int ringSlices; GoTriangleStrip[] dataSolid; GoLineLoop[] dataWire; boolean solidDirty; boolean wireDirty; public GoTorus(double radius, int slices, double ringRadius, int ringSlices) { this.radius = radius; this.slices = slices; this.ringRadius = ringRadius; this.ringSlices = ringSlices; solidDirty = true; wireDirty = true; } void renderSolid(Go go) { int i; if(solidDirty) updateSolid(); go.push(Go.FLAGS); go.enable(Go.CULL); for(i = 0; i < ringSlices; i++) { go.render(dataSolid[i]); } go.pop(Go.FLAGS); } void renderWire(Go go) { int i; if(wireDirty) updateWire(); for(i = 0; i < ringSlices + slices + 1; i++) { go.render(dataWire[i]); } } void renderWireSlices(Go go) { int i; if(wireDirty) updateWire(); for(i = ringSlices; i < ringSlices + slices + 1; i++) { go.render(dataWire[i]); } } void updateSolid() { int i, j; // // Create the data. // double[][][] d = new double[slices + 1][ringSlices + 1][3]; double[][][] c = new double[slices + 1][ringSlices + 1][3]; double ringSliceAngleInc = 2.0 * Math.PI / ringSlices; double ringSliceAngle = 0.0; for(i = 0; i <= ringSlices; i++) { d[0][i][0] = radius + ringRadius * Math.cos(ringSliceAngle);; d[0][i][1] = 0; d[0][i][2] = ringRadius * Math.sin(ringSliceAngle); c[0][i][0] = radius; c[0][i][1] = 0; c[0][i][2] = 0; ringSliceAngle += ringSliceAngleInc; } double sliceAngleInc = 2.0 * Math.PI / slices; double sliceAngle = sliceAngleInc; for(i = 1; i <= slices; i++) { for(j = 0; j <= ringSlices; j++) { d[i][j][0] = d[0][j][0] * Math.cos(sliceAngle); d[i][j][1] = d[0][j][0] * Math.sin(sliceAngle); d[i][j][2] = d[0][j][2]; c[i][j][0] = c[0][j][0] * Math.cos(sliceAngle); c[i][j][1] = c[0][j][0] * Math.sin(sliceAngle); c[i][j][2] = c[0][j][2]; } sliceAngle += sliceAngleInc; } // // Create the triangle strips. // dataSolid = new GoTriangleStrip[ringSlices]; for(i = 0; i < ringSlices; i++) { dataSolid[i] = new GoTriangleStrip((slices + 1) * 2, Go.NORMAL); for(j = 0; j <= slices; j++) { dataSolid[i].xyz(j*2, d[j][i+1][0], d[j][i+1][1], d[j][i+1][2]); dataSolid[i].xyz(j*2+1, d[j][i][0], d[j][i][1], d[j][i][2]); dataSolid[i].ijk(j*2, d[j][i+1][0] - c[j][i+1][0], d[j][i+1][1] - c[j][i+1][1], d[j][i+1][2] - c[j][i+1][2]); dataSolid[i].ijk(j*2+1, d[j][i][0] - c[j][i][0], d[j][i][1] - c[j][i][1], d[j][i][2] - c[j][i][2]); } } solidDirty = false; } void updateWire() { int i, j; // // Create the data. // double[][][] d = new double[slices + 1][ringSlices + 1][3]; double ringSliceAngleInc = 2.0 * Math.PI / ringSlices; double ringSliceAngle = 0.0; for(i = 0; i <= ringSlices; i++) { d[0][i][0] = radius + ringRadius * Math.cos(ringSliceAngle);; d[0][i][1] = 0; d[0][i][2] = ringRadius * Math.sin(ringSliceAngle); ringSliceAngle += ringSliceAngleInc; } double sliceAngleInc = 2.0 * Math.PI / slices; double sliceAngle = sliceAngleInc; for(i = 1; i <= slices; i++) { for(j = 0; j <= ringSlices; j++) { d[i][j][0] = d[0][j][0] * Math.cos(sliceAngle); d[i][j][1] = d[0][j][0] * Math.sin(sliceAngle); d[i][j][2] = d[0][j][2]; } sliceAngle += sliceAngleInc; } // // Create the line loops. // dataWire = new GoLineLoop[ringSlices + slices + 1]; int count = 0; for(i = 0; i < ringSlices; i++) { dataWire[count] = new GoLineLoop(slices); for(j = 0; j < slices; j++) { dataWire[count].xyz(j, d[j][i][0], d[j][i][1], d[j][i][2]); } count++; } for(j = 0; j <= slices; j++) { dataWire[count] = new GoLineLoop(ringSlices); for(i = 0; i < ringSlices; i++) { dataWire[count].xyz(i, d[j][i][0], d[j][i][1], d[j][i][2]); } count++; } wireDirty = false; } }