summaryrefslogtreecommitdiff
path: root/src/tesseract/objects/Toroid.java
blob: 3150efb405581faa988059f537a6f20e90d74809 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Icosahedron.java
 * TCSS 491 Computational Worlds
 * Phillip Cardon
 */
package tesseract.objects;

import javax.media.j3d.Appearance;
import javax.media.j3d.IndexedQuadArray;
import javax.media.j3d.Material;
import javax.media.j3d.PointArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;

/**
 * Represents a Toroid, or donut like shape.
 * @author Phillip Cardon
 * @version 0.9a
 */
public class Toroid extends PhysicalObject {
	/**
	 * @param position starting position.
	 * @param mass of object.
	 * @param scale mesh scale.
	 * @param sliceRadius radius of slice "flesh."
	 * @param sliceDivisions resolution of slice "flesh" circles.
	 * @param arcRadius Radius of donut circle
	 * @param arcDivisions resolution of slices on donut.
	 */
	public Toroid(final Vector3f position, final float mass, final float scale,
			final float sliceRadius, final int sliceDivisions,
			final float arcRadius, final int arcDivisions) {
		super(position, mass);
		
		setShape(buildToroid(scale, sliceRadius, sliceDivisions,
				arcRadius, arcDivisions));
	}
	
	
	/**
	 * Creates donut.
	 * @param sliceRadius radius of slice "flesh."
	 * @param sliceDivisions resolution of slice "flesh" circles.
	 * @param arcRadius Radius of donut circle
	 * @param arcDivisions resolution of slices on donut.
	 */
	public Shape3D buildToroid(final float scale, final float sliceRadius, final int sliceDivisions,
			final float arcRadius, final int arcDivisions) {
		Point3f[][] coordinates = new Point3f[arcDivisions][sliceDivisions];
		final float arcAngle = (float) (Math.PI * 2.0);
		final float sliceDivisionAngle = 2 * (float) Math.PI / sliceDivisions;
		
		for (int i = 0; i < sliceDivisions; i++) {
			coordinates[0][i] = new Point3f(sliceRadius 
					* (float) Math.cos(i * sliceDivisionAngle), 0f, sliceRadius 
					* (float) Math.sin(i * sliceDivisionAngle));	
		}
		
		Transform3D trans3D = new Transform3D();
		trans3D.setTranslation(new Vector3f(arcRadius, 0, 0));
		Transform3D tmp = new Transform3D();
		tmp.rotZ(-arcAngle / (arcDivisions - 1));
		trans3D.mul(tmp);
		tmp.setIdentity();
		tmp.setTranslation(new Vector3f(-arcRadius, 0, 0));
		trans3D.mul(tmp);
		
		for (int j = 1; j < arcDivisions; j++) {
			for (int i = 0; i < sliceDivisions; i++) {
				coordinates[j][i] = new Point3f(coordinates[j - 1][i]);
				trans3D.transform(coordinates[j][i]);
				coordinates[j][i].scale(scale);
			}
		}
		
		IndexedQuadArray geometry = new IndexedQuadArray(arcDivisions 
				* sliceDivisions, PointArray.COORDINATES, 4 * sliceDivisions 
				* (arcDivisions - 1));
		for (int j = 0; j < arcDivisions; j++) {
			geometry.setCoordinates(j * sliceDivisions, coordinates[j]);
		}
		
		int index = 0;
		int last = 0;
		for (int j = 0; j < arcDivisions - 2; j++) {
			for (int i = 0; i < sliceDivisions; i++) {
				geometry.setCoordinateIndex(index++, j * sliceDivisions + i);
				geometry.setCoordinateIndex(index++, (j + 1) * sliceDivisions 
						+ i);
				geometry.setCoordinateIndex(index++, (j + 1) * sliceDivisions 
						+ (i + 1) % sliceDivisions);
				geometry.setCoordinateIndex(index++, j * sliceDivisions 
						+ (i + 1) % sliceDivisions);
			}
			last = j;
		}
		last++;
		for (int i = 0; i < sliceDivisions; i++) {
			geometry.setCoordinateIndex(index++, last * sliceDivisions + i);
			geometry.setCoordinateIndex(index++, (0) * sliceDivisions + i);
			geometry.setCoordinateIndex(index++, (0) * sliceDivisions + (i + 1) 
					% sliceDivisions);
			geometry.setCoordinateIndex(index++, last * sliceDivisions 
					+ (i + 1) % sliceDivisions);
		}
		
		
		GeometryInfo gInfo = new GeometryInfo(geometry);
		gInfo.convertToIndexedTriangles();
		new NormalGenerator().generateNormals(gInfo);
		
		Shape3D shape = new Shape3D(gInfo.getGeometryArray());

		Appearance app = new Appearance();
		Material mat = new Material();
		mat.setDiffuseColor(1, 0, 0);
		app.setMaterial(mat);
		shape.setAppearance(app);
	
		return shape;
	}
}