diff options
| author | Jesse Morgan <jesse@jesterpm.net> | 2011-02-14 18:45:41 +0000 | 
|---|---|---|
| committer | Jesse Morgan <jesse@jesterpm.net> | 2011-02-14 18:45:41 +0000 | 
| commit | fd208e223b5ecc15be87d13343c1b0d55931029d (patch) | |
| tree | ee5bb168eedcbcc2eb7fd4ae2cd29ea4d34da617 /src/tesseract/objects/ChainLink2.java | |
| parent | 09c183d42b05be6677ba2f8bc373351ff16176dd (diff) | |
Here's a chainlink class!
Diffstat (limited to 'src/tesseract/objects/ChainLink2.java')
| -rw-r--r-- | src/tesseract/objects/ChainLink2.java | 214 | 
1 files changed, 214 insertions, 0 deletions
| diff --git a/src/tesseract/objects/ChainLink2.java b/src/tesseract/objects/ChainLink2.java new file mode 100644 index 0000000..e98280b --- /dev/null +++ b/src/tesseract/objects/ChainLink2.java @@ -0,0 +1,214 @@ +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; + +/** + * Chain link object. + *  + * @author Jesse Morgan + */ +public class ChainLink2 extends PhysicalObject { +	/** +	 * Default link length. +	 */ +	public static final float DEFAULT_LENGTH = 0.15f; +	 +	/** +	 * Default ratio of length to width. +	 */ +	public static final float DEFAULT_WIDTH_RATIO = 0.75f; +	 +	/** +	 * Default ratio of length to link diameter. +	 */ +	public static final float DEFAULT_DIAMETER_RATIO = 0.25f; +	 +	/** +	 * Number of slices to render. +	 */ +	protected static final int SLICE_COUNT = 40; +	 +	/** +	 * Number of points in the circumference of the circle. +	 */ +	protected static final int SLICE_DIVISIONS = 16; +	 +	/** +	 * Construct a chain link. +	 *  +	 * @param thePosition Position. +	 * @param mass Mass. +	 */ +	public ChainLink2(final Vector3f thePosition, final float mass) { +		this(thePosition, mass, DEFAULT_LENGTH * DEFAULT_DIAMETER_RATIO, +				DEFAULT_LENGTH, DEFAULT_LENGTH * DEFAULT_WIDTH_RATIO); +	} +	 +	/** +	 * Construct a chain link. +	 *  +	 * @param thePosition Position. +	 * @param mass Mass. +	 * @param length Link length. +	 * 		Width and diameter are created from the default ratios. +	 */ +	public ChainLink2(final Vector3f thePosition, final float mass, +			final float length) { +		this(thePosition, mass, length * DEFAULT_DIAMETER_RATIO, +				length, length * DEFAULT_WIDTH_RATIO); +	} +	 +	/** +	 * Construct a Chain Link. +	 *  +	 * @param thePosition Position. +	 * @param mass Mass. +	 * @param diameter Diameter of link. +	 * @param length Length of link. +	 * @param width Width of link. +	 */ +	public ChainLink2(final Vector3f thePosition, final float mass, +			final float diameter, final float length, final float width) { +		super(thePosition, mass); +		 +		setShape(createShape(SLICE_COUNT, SLICE_DIVISIONS, +				diameter, length, width)); +	} + +	/** +	 * Create the shape. +	 *  +	 * @param sliceCount Number of slices. +	 * @param sliceDivisions Number of divisions. +	 * @param diameter Diameter. +	 * @param length Length. +	 * @param width Width. +	 *  +	 * @return Chainlink shape. +	 */ +	public Shape3D createShape(final int sliceCount, final int sliceDivisions, +			final float diameter, final float length, final float width) { +		 +		Point3f[][] coords = new Point3f[sliceCount][sliceDivisions]; +		 +		// Design the first circle +		double theta = 2 * Math.PI / sliceDivisions; +		float radius = diameter / 2.0f; +		 +		// Translate the coords to the correct place. +		Transform3D t3d = new Transform3D(); +		 +		for (int i = 0; i < sliceDivisions; i++) { +			coords[0][i] = new Point3f( +					0f, +					(float) (radius * Math.cos(i * theta)), +					(float) (radius * Math.sin(i * theta))); +			 +			// Move to the right place. +			//t3d.transform(coords[0][i]); +		} +		 +		// Create the arc +		radius = (width - radius) / 2.0f; +		 +		t3d.setIdentity(); +		t3d.setTranslation(new Vector3f(0, -radius, 0)); +		 +		Transform3D tmp = new Transform3D(); +		tmp.rotZ(Math.PI / (sliceCount / 2.0 - 1)); +		t3d.mul(tmp); +		tmp.setIdentity(); +		//new Vector3f(-(length / 2.0f - radius), -width / 2.0f, 0)); +		tmp.setTranslation(new Vector3f(0, radius, 0)); +		t3d.mul(tmp); +		 +		for (int j = 1; j < sliceCount / 2; j++) { +			for (int i = 0; i < sliceDivisions; i++) { +				coords[j][i] = new Point3f(coords[j - 1][i]); +				t3d.transform(coords[j][i]); +			} +		} +		 +		// Next build second half... +		t3d.setIdentity(); +		t3d.setTranslation(new Vector3f( +				-(length  / 2.0f - radius / 2.0f), +				(width - diameter / 2.0f) / 2.0f, +				0)); +		 +		Transform3D rot = new Transform3D(); +		rot.rotY(Math.PI); +		tmp.setIdentity(); +		tmp.rotX(Math.PI); +		rot.mul(tmp); +		for (int j = 0; j < sliceCount / 2; j++) { +			for (int i = 0; i < sliceDivisions; i++) { +				t3d.transform(coords[j][i]); +				 +				coords[j + sliceCount / 2][i] = new Point3f(coords[j][i]); +				rot.transform(coords[j + sliceCount / 2][i]); +			} +		} +		 +		 +		// Build Geoemetry +		IndexedQuadArray geometry = new IndexedQuadArray( +				sliceCount * sliceDivisions, +				PointArray.COORDINATES, +				4 * sliceDivisions * sliceCount); +		 +		// TODO: Remove /2 +		for (int i = 0; i < sliceCount; i++) { +			geometry.setCoordinates(i * sliceDivisions, coords[i]); +		} +		 +		int index = 0; +		for (int j = 0; j < (sliceCount - 1); 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); +			} +		} +		 +		for (int i = 0; i < sliceDivisions; i++) { +			geometry.setCoordinateIndex(index++, +					(sliceCount - 1) * sliceDivisions + i); +			geometry.setCoordinateIndex(index++, +					i); +			geometry.setCoordinateIndex(index++, +					(i + 1) % sliceDivisions); +			geometry.setCoordinateIndex(index++, +					(sliceCount - 1) * 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;		 +	} + +} | 
