summaryrefslogtreecommitdiffstats
path: root/src/GearTest
diff options
context:
space:
mode:
authorkcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300>2004-06-09 03:28:13 +0000
committerkcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300>2004-06-09 03:28:13 +0000
commit53ebfcc5ad5554b67d2287f8b02c22ec8405af0f (patch)
tree70c8fabf4cbef5a9d2a50735c4e502d56ce156da /src/GearTest
parent4dead457a59220406dd9fcd40997d7a7b27571b0 (diff)
Initial creation of j3d-examples sources in CVS repository
Diffstat (limited to 'src/GearTest')
-rw-r--r--src/GearTest/Gear.java397
-rw-r--r--src/GearTest/GearBox.html15
-rw-r--r--src/GearTest/GearBox.java354
-rw-r--r--src/GearTest/GearBox_plugin.html39
-rw-r--r--src/GearTest/GearTest.html15
-rw-r--r--src/GearTest/GearTest.java206
-rw-r--r--src/GearTest/GearTest_plugin.html39
-rw-r--r--src/GearTest/Shaft.java196
-rw-r--r--src/GearTest/SpurGear.java556
-rw-r--r--src/GearTest/SpurGearThinBody.java185
-rw-r--r--src/GearTest/build.xml66
11 files changed, 2068 insertions, 0 deletions
diff --git a/src/GearTest/Gear.java b/src/GearTest/Gear.java
new file mode 100644
index 0000000..fbd0f03
--- /dev/null
+++ b/src/GearTest/Gear.java
@@ -0,0 +1,397 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Gear extends javax.media.j3d.TransformGroup {
+
+ // Specifiers determining whether to generate outward facing normals or
+ // inward facing normals.
+ static final int OutwardNormals = 1;
+ static final int InwardNormals = -1;
+
+ // The number of teeth in the gear
+ int toothCount;
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ double gearStartAngle;
+ // The Z-rotation angle to place the tooth center at theta = 0
+ float toothTopCenterAngle;
+ // The Z-rotation angle to place the valley center at theta = 0
+ float valleyCenterAngle;
+ // The angle about Z subtended by one tooth and its associated valley
+ float circularPitchAngle;
+
+ // Increment angles
+ float toothValleyAngleIncrement;
+
+ // Front and rear facing normals for the gear's body
+ final Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ final Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+
+
+ Gear(int toothCount) {
+ this.toothCount = toothCount;
+ }
+
+ void addBodyDisks(float shaftRadius, float bodyOuterRadius,
+ float thickness, Appearance look) {
+ int gearBodySegmentVertexCount; // #(segments) per tooth-unit
+ int gearBodyTotalVertexCount; // #(vertices) in a gear face
+ int gearBodyStripCount[] = new int[1]; // per strip (1) vertex count
+
+ // A ray from the gear center, used in normal calculations
+ float xDirection, yDirection;
+
+ // The x and y coordinates at each point of a facet and at each
+ // point on the gear: at the shaft, the root of the teeth, and
+ // the outer point of the teeth
+ float xRoot0, yRoot0, xShaft0, yShaft0;
+ float xRoot3, yRoot3, xShaft3, yShaft3;
+ float xRoot4, yRoot4, xShaft4, yShaft4;
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ double gearStartAngle = -1.0 * toothTopCenterAngle;
+
+ // Temporaries that store start angle for each portion of tooth facet
+ double toothStartAngle, toothTopStartAngle,
+ toothDeclineStartAngle, toothValleyStartAngle,
+ nextToothStartAngle;
+
+ Shape3D newShape;
+ int index;
+
+ // The z coordinates for the body disks
+ final float frontZ = -0.5f * thickness;
+ final float rearZ = 0.5f * thickness;
+
+ /* Construct the gear's front body (front facing torus disk)
+ * __2__
+ * - | - 4
+ * - /| /-
+ * / / | /| \
+ * 0\ / | / / >
+ * \ / | / | >
+ * \ / | / / |
+ * \ / ____|/ | >
+ * \-- --__/ |
+ * 1 3 5
+ *
+ */
+ gearBodySegmentVertexCount = 4;
+ gearBodyTotalVertexCount = 2 + gearBodySegmentVertexCount * toothCount;
+ gearBodyStripCount[0] = gearBodyTotalVertexCount;
+
+ TriangleStripArray frontGearBody
+ = new TriangleStripArray(gearBodyTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ gearBodyStripCount);
+
+ xDirection = (float)Math.cos(gearStartAngle);
+ yDirection = (float)Math.sin(gearStartAngle);
+ xShaft0 = shaftRadius * xDirection;
+ yShaft0 = shaftRadius * yDirection;
+ xRoot0 = bodyOuterRadius * xDirection;
+ yRoot0 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xRoot0, yRoot0, frontZ);
+ frontGearBody.setCoordinate(0, coordinate);
+ frontGearBody.setNormal(0, frontNormal);
+
+ coordinate.set(xShaft0, yShaft0, frontZ);
+ frontGearBody.setCoordinate(1, coordinate);
+ frontGearBody.setNormal(1, frontNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ xRoot3 = bodyOuterRadius * xDirection;
+ yRoot3 = bodyOuterRadius * yDirection;
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ xRoot4 = bodyOuterRadius * xDirection;
+ yRoot4 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xRoot3, yRoot3, frontZ);
+ frontGearBody.setCoordinate(index, coordinate);
+ frontGearBody.setNormal(index, frontNormal);
+
+ coordinate.set(xShaft3, yShaft3, frontZ);
+ frontGearBody.setCoordinate(index + 1, coordinate);
+ frontGearBody.setNormal(index + 1, frontNormal);
+
+ coordinate.set(xRoot4, yRoot4, frontZ);
+ frontGearBody.setCoordinate(index + 2, coordinate);
+ frontGearBody.setNormal(index + 2, frontNormal);
+
+ coordinate.set(xShaft4, yShaft4, frontZ);
+ frontGearBody.setCoordinate(index + 3, coordinate);
+ frontGearBody.setNormal(index + 3, frontNormal);
+ }
+ newShape = new Shape3D(frontGearBody, look);
+ this.addChild(newShape);
+
+ // Construct the gear's rear body (rear facing torus disc)
+ TriangleStripArray rearGearBody
+ = new TriangleStripArray(gearBodyTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ gearBodyStripCount);
+ xDirection = (float)Math.cos(gearStartAngle);
+ yDirection = (float)Math.sin(gearStartAngle);
+ xShaft0 = shaftRadius * xDirection;
+ yShaft0 = shaftRadius * yDirection;
+ xRoot0 = bodyOuterRadius * xDirection;
+ yRoot0 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xShaft0, yShaft0, rearZ);
+ rearGearBody.setCoordinate(0, coordinate);
+ rearGearBody.setNormal(0, rearNormal);
+
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ rearGearBody.setCoordinate(1, coordinate);
+ rearGearBody.setNormal(1, rearNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ xRoot3 = bodyOuterRadius * xDirection;
+ yRoot3 = bodyOuterRadius * yDirection;
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ xRoot4 = bodyOuterRadius * xDirection;
+ yRoot4 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xShaft3, yShaft3, rearZ);
+ rearGearBody.setCoordinate(index, coordinate);
+ rearGearBody.setNormal(index, rearNormal);
+
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ rearGearBody.setCoordinate(index + 1, coordinate);
+ rearGearBody.setNormal(index + 1, rearNormal);
+
+ coordinate.set(xShaft4, yShaft4, rearZ);
+ rearGearBody.setCoordinate(index + 2, coordinate);
+ rearGearBody.setNormal(index + 2, rearNormal);
+
+ coordinate.set(xRoot4, yRoot4, rearZ);
+ rearGearBody.setCoordinate(index + 3, coordinate);
+ rearGearBody.setNormal(index + 3, rearNormal);
+
+ }
+ newShape = new Shape3D(rearGearBody, look);
+ this.addChild(newShape);
+ }
+
+ void addCylinderSkins(float shaftRadius, float length,
+ int normalDirection, Appearance look) {
+ int insideShaftVertexCount; // #(vertices) for shaft
+ int insideShaftStripCount[] = new int[1]; // #(vertices) in strip/strip
+ double toothStartAngle, nextToothStartAngle, toothValleyStartAngle;
+
+ // A ray from the gear center, used in normal calculations
+ float xDirection, yDirection;
+
+ // The z coordinates for the body disks
+ final float frontZ = -0.5f * length;
+ final float rearZ = 0.5f * length;
+
+ // Temporary variables for storing coordinates, points, and vectors
+ float xShaft3, yShaft3, xShaft4, yShaft4;
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Vector3f surfaceNormal = new Vector3f();
+
+ Shape3D newShape;
+ int index;
+ int firstIndex;
+ int secondIndex;
+
+
+ /*
+ * Construct gear's inside shaft cylinder
+ * First the tooth's up, flat outer, and down distances
+ * Second the tooth's flat inner distance
+ *
+ * Outward facing vertex order:
+ * 0_______2____4
+ * | /| /|
+ * | / | / |
+ * | / | / |
+ * |/______|/___|
+ * 1 3 5
+ *
+ * Inward facing vertex order:
+ * 1_______3____5
+ * |\ |\ |
+ * | \ | \ |
+ * | \ | \ |
+ * |______\|___\|
+ * 0 2 4
+ */
+ insideShaftVertexCount = 4 * toothCount + 2;
+ insideShaftStripCount[0] = insideShaftVertexCount;
+
+ TriangleStripArray insideShaft
+ = new TriangleStripArray(insideShaftVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ insideShaftStripCount);
+ xShaft3 = shaftRadius * (float)Math.cos(gearStartAngle);
+ yShaft3 = shaftRadius * (float)Math.sin(gearStartAngle);
+
+ if (normalDirection == OutwardNormals) {
+ surfaceNormal.set(1.0f, 0.0f, 0.0f);
+ firstIndex = 1;
+ secondIndex = 0;
+ } else {
+ surfaceNormal.set(-1.0f, 0.0f, 0.0f);
+ firstIndex = 0;
+ secondIndex = 1;
+ }
+
+ // Coordinate labeled 0 in the strip
+ coordinate.set(shaftRadius, 0.0f, frontZ);
+ insideShaft.setCoordinate(firstIndex, coordinate);
+ insideShaft.setNormal(firstIndex, surfaceNormal);
+
+ // Coordinate labeled 1 in the strip
+ coordinate.set(shaftRadius, 0.0f, rearZ);
+ insideShaft.setCoordinate(secondIndex, coordinate);
+ insideShaft.setNormal(secondIndex, surfaceNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+
+ toothStartAngle = circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ if (normalDirection == OutwardNormals)
+ surfaceNormal.set(xDirection, yDirection, 0.0f);
+ else
+ surfaceNormal.set(-xDirection, -yDirection, 0.0f);
+
+ // Coordinate labeled 2 in the strip
+ coordinate.set(xShaft3, yShaft3, frontZ);
+ insideShaft.setCoordinate(index + firstIndex, coordinate);
+ insideShaft.setNormal(index + firstIndex, surfaceNormal);
+
+ // Coordinate labeled 3 in the strip
+ coordinate.set(xShaft3, yShaft3, rearZ);
+ insideShaft.setCoordinate(index + secondIndex, coordinate);
+ insideShaft.setNormal(index + secondIndex, surfaceNormal);
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ if (normalDirection == OutwardNormals)
+ surfaceNormal.set(xDirection, yDirection, 0.0f);
+ else
+ surfaceNormal.set(-xDirection, -yDirection, 0.0f);
+
+ // Coordinate labeled 4 in the strip
+ coordinate.set(xShaft4, yShaft4, frontZ);
+ insideShaft.setCoordinate(index + 2 + firstIndex, coordinate);
+ insideShaft.setNormal(index + 2 + firstIndex, surfaceNormal);
+
+ // Coordinate labeled 5 in the strip
+ coordinate.set(xShaft4, yShaft4, rearZ);
+ insideShaft.setCoordinate(index + 2 + secondIndex, coordinate);
+ insideShaft.setNormal(index + 2 + secondIndex, surfaceNormal);
+
+ }
+ newShape = new Shape3D(insideShaft, look);
+ this.addChild(newShape);
+ }
+
+ public float getToothTopCenterAngle() {
+ return toothTopCenterAngle;
+ }
+
+ public float getValleyCenterAngle() {
+ return valleyCenterAngle;
+ }
+
+ public float getCircularPitchAngle() {
+ return circularPitchAngle;
+ }
+}
diff --git a/src/GearTest/GearBox.html b/src/GearTest/GearBox.html
new file mode 100644
index 0000000..0137867
--- /dev/null
+++ b/src/GearTest/GearBox.html
@@ -0,0 +1,15 @@
+<HTML>
+<HEAD>
+<TITLE>GearBox</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<applet align=middle code="GearBox.class" width=700 height=700>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+</applet>
+</BODY>
+</HTML>
diff --git a/src/GearTest/GearBox.java b/src/GearTest/GearBox.java
new file mode 100644
index 0000000..bac308a
--- /dev/null
+++ b/src/GearTest/GearBox.java
@@ -0,0 +1,354 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import com.sun.j3d.utils.behaviors.mouse.*;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.lang.Integer;
+import com.sun.j3d.utils.behaviors.vp.*;
+
+public class GearBox extends Applet {
+
+ static final int defaultToothCount = 48;
+ private int toothCount;
+ private SimpleUniverse u = null;
+
+ public BranchGroup createGearBox(int toothCount) {
+ Transform3D tempTransform = new Transform3D();
+
+ // Create the root of the branch graph
+ BranchGroup branchRoot = createBranchEnvironment();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ branchRoot.addChild(objScale);
+
+ // Create an Appearance.
+ Appearance look = new Appearance();
+ Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ look.setMaterial(new Material(objColor, black,
+ objColor, white, 100.0f));
+
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup gearboxTrans = new TransformGroup();
+ gearboxTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ gearboxTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(gearboxTrans);
+
+ // Create a bounds for the mouse behavior methods
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Define the shaft base information
+ int shaftCount = 4;
+ int secondsPerRevolution = 8000;
+
+ // Create the Shaft(s)
+ Shaft shafts[] = new Shaft[shaftCount];
+ TransformGroup shaftTGs[] = new TransformGroup[shaftCount];
+ Alpha shaftAlphas[] = new Alpha[shaftCount];
+ RotationInterpolator shaftRotors[]
+ = new RotationInterpolator[shaftCount];
+ Transform3D shaftAxis[] = new Transform3D[shaftCount];
+
+ // Note: the following arrays we're incorporated to make changing
+ // the gearbox easier.
+ float shaftRatios[] = new float[shaftCount];
+ shaftRatios[0] = 1.0f;
+ shaftRatios[1] = 0.5f;
+ shaftRatios[2] = 0.75f;
+ shaftRatios[3] = 5.0f;
+
+ float shaftRadius[] = new float[shaftCount];
+ shaftRadius[0] = 0.2f;
+ shaftRadius[1] = 0.2f;
+ shaftRadius[2] = 0.2f;
+ shaftRadius[3] = 0.2f;
+
+ float shaftLength[] = new float[shaftCount];
+ shaftLength[0] = 1.8f;
+ shaftLength[1] = 0.8f;
+ shaftLength[2] = 0.8f;
+ shaftLength[3] = 0.8f;
+
+ float shaftDirection[] = new float[shaftCount];
+ shaftDirection[0] = 1.0f;
+ shaftDirection[1] = -1.0f;
+ shaftDirection[2] = 1.0f;
+ shaftDirection[3] = -1.0f;
+
+ Vector3d shaftPlacement[] = new Vector3d[shaftCount];
+ shaftPlacement[0] = new Vector3d(-0.75, -0.9, 0.0);
+ shaftPlacement[1] = new Vector3d(0.75, -0.9, 0.0);
+ shaftPlacement[2] = new Vector3d(0.75, 0.35, 0.0);
+ shaftPlacement[3] = new Vector3d(-0.75, 0.60, -0.7);
+
+ // Create the shafts.
+ for(int i = 0; i < shaftCount; i++) {
+ shafts[i] = new Shaft(shaftRadius[i], shaftLength[i], 25, look);
+ }
+
+ // Create a transform group node for placing each shaft
+ for(int i = 0; i < shaftCount; i++) {
+ shaftTGs[i] = new TransformGroup();
+ gearboxTrans.addChild(shaftTGs[i]);
+ shaftTGs[i].getTransform(tempTransform);
+ tempTransform.setTranslation(shaftPlacement[i]);
+ shaftTGs[i].setTransform(tempTransform);
+ shaftTGs[i].addChild(shafts[i]);
+ }
+
+ // Add rotation interpolators to rotate the shaft in the appropriate
+ // direction and at the appropriate rate
+ for(int i = 0; i < shaftCount; i++) {
+ shaftAlphas[i] = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
+ (long)(secondsPerRevolution
+ * shaftRatios[i]),
+ 0, 0,
+ 0, 0, 0);
+ shaftAxis[i] = new Transform3D();
+ shaftAxis[i].rotX(Math.PI/2.0);
+ shaftRotors[i]
+ = new RotationInterpolator(shaftAlphas[i], shafts[i],
+ shaftAxis[i],
+ 0.0f,
+ shaftDirection[i] *
+ (float) Math.PI * 2.0f);
+ shaftRotors[i].setSchedulingBounds(bounds);
+ shaftTGs[i].addChild(shaftRotors[i]);
+ }
+
+ // Define the gear base information. Again, these arrays exist to
+ // make the process of changing the GearBox via an editor faster
+ int gearCount = 5;
+ float valleyToCircularPitchRatio = .15f;
+ float pitchCircleRadius = 1.0f;
+ float addendum = 0.05f;
+ float dedendum = 0.05f;
+ float gearThickness = 0.3f;
+ float toothTipThickness = 0.27f;
+
+ // Create an array of gears and their associated information
+ SpurGear gears[] = new SpurGear[gearCount];
+ TransformGroup gearTGs[] = new TransformGroup[gearCount];
+
+ int gearShaft[] = new int[gearCount];
+ gearShaft[0] = 0;
+ gearShaft[1] = 1;
+ gearShaft[2] = 2;
+ gearShaft[3] = 0;
+ gearShaft[4] = 3;
+
+ float ratio[] = new float[gearCount];
+ ratio[0] = 1.0f;
+ ratio[1] = 0.5f;
+ ratio[2] = 0.75f;
+ ratio[3] = 0.25f;
+ ratio[4] = 1.25f;
+
+ Vector3d placement[] = new Vector3d[gearCount];
+ placement[0] = new Vector3d(0.0, 0.0, 0.0);
+ placement[1] = new Vector3d(0.0, 0.0, 0.0);
+ placement[2] = new Vector3d(0.0, 0.0, 0.0);
+ placement[3] = new Vector3d(0.0, 0.0, -0.7);
+ placement[4] = new Vector3d(0.0, 0.0, 0.0);
+
+ // Create the gears.
+ for(int i = 0; i < gearCount; i++) {
+ gears[i]
+ = new SpurGearThinBody(((int)((float)toothCount * ratio[i])),
+ pitchCircleRadius * ratio[i],
+ shaftRadius[0],
+ addendum, dedendum,
+ gearThickness,
+ toothTipThickness,
+ valleyToCircularPitchRatio, look);
+ }
+
+ // Create a transform group node for arranging the gears on a shaft
+ // and attach the gear to its associated shaft
+ for(int i = 0; i < gearCount; i++) {
+ gearTGs[i] = new TransformGroup();
+ gearTGs[i].getTransform(tempTransform);
+ tempTransform.rotZ((shaftDirection[gearShaft[i]] == -1.0) ?
+ gears[i].getCircularPitchAngle()/-2.0f :
+ 0.0f);
+ tempTransform.setTranslation(placement[i]);
+ gearTGs[i].setTransform(tempTransform);
+ gearTGs[i].addChild(gears[i]);
+ shafts[gearShaft[i]].addChild(gearTGs[i]);
+ }
+
+ // Have Java 3D perform optimizations on this scene graph.
+ branchRoot.compile();
+
+ return branchRoot;
+ }
+
+ BranchGroup createBranchEnvironment(){
+ // Create the root of the branch graph
+ BranchGroup branchRoot = new BranchGroup();
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ branchRoot.addChild(bgNode);
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ branchRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ branchRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ branchRoot.addChild(light2);
+
+ return branchRoot;
+ }
+
+ public GearBox() {
+ this(defaultToothCount);
+ }
+
+ public GearBox(int toothCount) {
+ this.toothCount = toothCount;
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create the gearbox and attach it to the virtual universe
+ BranchGroup scene = createGearBox(toothCount);
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ // add orbit behavior to the ViewingPlatform
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows GearBox to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ int value;
+
+ if (args.length > 1) {
+ System.out.println("Usage: java GearBox #teeth (LCD 4)");
+ System.exit(0);
+ } else if (args.length == 0) {
+ new MainFrame(new GearBox(), 700, 700);
+ } else
+ {
+ try{
+ value = Integer.parseInt(args[0]);
+ } catch (NumberFormatException e) {
+ System.out.println("Illegal integer specified");
+ System.out.println("Usage: java GearBox #teeth (LCD 4)");
+ value = 0;
+ System.exit(0);
+ }
+ if (value <= 0 | (value % 4) != 0) {
+ System.out.println("Integer not a positive multiple of 4");
+ System.out.println("Usage: java GearBox #teeth (LCD 4)");
+ System.exit(0);
+ }
+ new MainFrame(new GearBox(value), 700, 700);
+ }
+ }
+}
diff --git a/src/GearTest/GearBox_plugin.html b/src/GearTest/GearBox_plugin.html
new file mode 100644
index 0000000..1c6f737
--- /dev/null
+++ b/src/GearTest/GearBox_plugin.html
@@ -0,0 +1,39 @@
+<HTML>
+<HEAD>
+<TITLE>GearBox</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<!--"CONVERTED_APPLET"-->
+<!-- CONVERTER VERSION 1.3 -->
+<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+WIDTH = 700 HEIGHT = 700 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
+<PARAM NAME = CODE VALUE = "GearBox.class" >
+
+<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2">
+<PARAM NAME="scriptable" VALUE="false">
+<COMMENT>
+<EMBED type="application/x-java-applet;version=1.2.2" CODE = "GearBox.class" WIDTH = 700 HEIGHT = 700 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+</NOEMBED></EMBED>
+</OBJECT>
+
+<!--
+<APPLET CODE = "GearBox.class" WIDTH = 700 HEIGHT = 700 ALIGN = middle>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+
+</APPLET>
+-->
+<!--"END_CONVERTED_APPLET"-->
+
+</BODY>
+</HTML>
diff --git a/src/GearTest/GearTest.html b/src/GearTest/GearTest.html
new file mode 100644
index 0000000..5416cf8
--- /dev/null
+++ b/src/GearTest/GearTest.html
@@ -0,0 +1,15 @@
+<HTML>
+<HEAD>
+<TITLE>GearTest</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<applet align=middle code="GearTest.class" width=700 height=700>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+</applet>
+</BODY>
+</HTML>
diff --git a/src/GearTest/GearTest.java b/src/GearTest/GearTest.java
new file mode 100644
index 0000000..99c9e27
--- /dev/null
+++ b/src/GearTest/GearTest.java
@@ -0,0 +1,206 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class GearTest extends Applet {
+
+ static final int defaultToothCount = 24;
+
+ private int toothCount;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(int toothCount) {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objScale.addChild(bgNode);
+
+ // Set up the global lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
+ Color3f light2Color = new Color3f(0.3f, 0.3f, 0.4f);
+ Vector3f light2Direction = new Vector3f(-6.0f, -2.0f, -1.0f);
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objScale.addChild(ambientLightNode);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objScale.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objScale.addChild(light2);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(objTrans);
+
+ // Create an Appearance.
+ Appearance look = new Appearance();
+ Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ look.setMaterial(new Material(objColor, black, objColor, white, 100.0f));
+
+ // Create a gear, add it to the scene graph.
+ // SpurGear gear = new SpurGear(toothCount, 1.0f, 0.2f,
+ SpurGear gear = new SpurGearThinBody(toothCount, 1.0f, 0.2f,
+ 0.05f, 0.05f, 0.3f, 0.28f, look);
+ objTrans.addChild(gear);
+
+ // Create a new Behavior object that will rotate the object and
+ // add it into the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 8000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public GearTest() {
+ this(defaultToothCount);
+ }
+
+ public GearTest(int toothCount) {
+ this.toothCount = toothCount;
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph(toothCount);
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows GearTest to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ int value;
+
+ if (args.length > 1) {
+ System.out.println("Usage: java GearTest [#teeth]");
+ System.exit(0);
+ } else if (args.length == 0) {
+ new MainFrame(new GearTest(), 700, 700);
+ } else
+ {
+ try {
+ value = Integer.parseInt(args[0]);
+ } catch (NumberFormatException e) {
+ System.out.println("Illegal integer specified");
+ System.out.println("Usage: java GearTest [#teeth]");
+ value = 0;
+ System.exit(0);
+ }
+ if (value <= 0) {
+ System.out.println("Integer must be positive (> 0)");
+ System.out.println("Usage: java GearBox [#teeth]");
+ System.exit(0);
+ }
+ new MainFrame(new GearTest(value), 700, 700);
+ }
+ }
+}
diff --git a/src/GearTest/GearTest_plugin.html b/src/GearTest/GearTest_plugin.html
new file mode 100644
index 0000000..a2f7b06
--- /dev/null
+++ b/src/GearTest/GearTest_plugin.html
@@ -0,0 +1,39 @@
+<HTML>
+<HEAD>
+<TITLE>GearTest</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<!--"CONVERTED_APPLET"-->
+<!-- CONVERTER VERSION 1.3 -->
+<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+WIDTH = 700 HEIGHT = 700 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
+<PARAM NAME = CODE VALUE = "GearTest.class" >
+
+<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2">
+<PARAM NAME="scriptable" VALUE="false">
+<COMMENT>
+<EMBED type="application/x-java-applet;version=1.2.2" CODE = "GearTest.class" WIDTH = 700 HEIGHT = 700 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+</NOEMBED></EMBED>
+</OBJECT>
+
+<!--
+<APPLET CODE = "GearTest.class" WIDTH = 700 HEIGHT = 700 ALIGN = middle>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+
+</APPLET>
+-->
+<!--"END_CONVERTED_APPLET"-->
+
+</BODY>
+</HTML>
diff --git a/src/GearTest/Shaft.java b/src/GearTest/Shaft.java
new file mode 100644
index 0000000..f7f9d9a
--- /dev/null
+++ b/src/GearTest/Shaft.java
@@ -0,0 +1,196 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Shaft extends javax.media.j3d.TransformGroup {
+
+ /**
+ * Construct a Shaft;
+ * @return a new shaft that with the specified radius centered about
+ * the origin an laying in the XY plane and of a specified length
+ * extending in the Z dimension
+ * @param radius radius of shaft
+ * @param length shaft length shaft extends from -length/2 to length/2 in
+ * the Z dimension
+ * @param segmentCount number of segments for the shaft face
+ * @param look the Appearance to associate with this shaft
+ */
+ public Shaft(float radius, float length, int segmentCount,
+ Appearance look) {
+ // The direction of the ray from the shaft's center
+ float xDirection, yDirection;
+ float xShaft, yShaft;
+
+ // The z coordinates for the shaft's faces (never change)
+ float frontZ = -0.5f * length;
+ float rearZ = 0.5f * length;
+
+ int shaftFaceVertexCount; // #(vertices) per shaft face
+ int shaftFaceTotalVertexCount; // total #(vertices) in all teeth
+ int shaftFaceStripCount[] = new int[1]; // per shaft vertex count
+ int shaftVertexCount; // #(vertices) for shaft
+ int shaftStripCount[] = new int[1]; // #(vertices) in strip/strip
+
+ // Front and rear facing normals for the shaft's faces
+ Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+ // Outward facing normal
+ Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Shape3D newShape;
+
+ // The angle subtended by a single segment
+ double segmentAngle = 2.0 * Math.PI/segmentCount;
+ double tempAngle;
+
+ // Allow this object to spin. etc.
+ this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+
+ /* for the forward facing fan:
+ * ___3___
+ * - | -
+ * / | \
+ * 4/\ | /\2
+ * / \ | / \
+ * / \ | / \
+ * : \ | / :
+ * |--------------- *----------------|
+ * 5 0 1
+ *
+ * for backward facing fan exchange 1 with 5; 2 with 4, etc.
+ */
+
+ // Construct the shaft's front and rear face
+ shaftFaceVertexCount = segmentCount + 2;
+ shaftFaceStripCount[0] = shaftFaceVertexCount;
+
+ TriangleFanArray frontShaftFace
+ = new TriangleFanArray(shaftFaceVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ shaftFaceStripCount);
+
+ TriangleFanArray rearShaftFace
+ = new TriangleFanArray(shaftFaceVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ shaftFaceStripCount);
+
+ coordinate.set(0.0f, 0.0f, frontZ);
+ frontShaftFace.setCoordinate(0, coordinate);
+ frontShaftFace.setNormal(0, frontNormal);
+
+ coordinate.set(0.0f, 0.0f, rearZ);
+ rearShaftFace.setCoordinate(0, coordinate);
+ rearShaftFace.setNormal(0, rearNormal);
+
+ for(int index = 1; index < segmentCount+2; index++) {
+
+ tempAngle = segmentAngle * -(double)index;
+ coordinate.set(radius * (float)Math.cos(tempAngle),
+ radius * (float)Math.sin(tempAngle),
+ frontZ);
+ frontShaftFace.setCoordinate(index, coordinate);
+ frontShaftFace.setNormal(index, frontNormal);
+
+ tempAngle = -tempAngle;
+ coordinate.set(radius * (float)Math.cos(tempAngle),
+ radius * (float)Math.sin(tempAngle),
+ rearZ);
+ rearShaftFace.setCoordinate(index, coordinate);
+ rearShaftFace.setNormal(index, rearNormal);
+ }
+ newShape = new Shape3D(frontShaftFace, look);
+ this.addChild(newShape);
+ newShape = new Shape3D(rearShaftFace, look);
+ this.addChild(newShape);
+
+ // Construct shaft's outer skin (the cylinder body)
+ shaftVertexCount = 2 * segmentCount + 2;
+ shaftStripCount[0] = shaftVertexCount;
+
+ TriangleStripArray shaft
+ = new TriangleStripArray(shaftVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ shaftStripCount);
+
+ outNormal.set(1.0f, 0.0f, 0.0f);
+
+ coordinate.set(radius, 0.0f, rearZ);
+ shaft.setCoordinate(0, coordinate);
+ shaft.setNormal(0, outNormal);
+
+ coordinate.set(radius, 0.0f, frontZ);
+ shaft.setCoordinate(1, coordinate);
+ shaft.setNormal(1, outNormal);
+
+ for(int count = 0; count < segmentCount; count++) {
+ int index = 2 + count * 2;
+
+ tempAngle = segmentAngle * (double)(count + 1);
+ xDirection = (float)Math.cos(tempAngle);
+ yDirection = (float)Math.sin(tempAngle);
+ xShaft = radius * xDirection;
+ yShaft = radius * yDirection;
+ outNormal.set(xDirection, yDirection, 0.0f);
+
+ coordinate.set(xShaft, yShaft, rearZ);
+ shaft.setCoordinate(index, coordinate);
+ shaft.setNormal(index, outNormal);
+
+ coordinate.set(xShaft, yShaft, frontZ);
+ shaft.setCoordinate(index + 1, coordinate);
+ shaft.setNormal(index + 1, outNormal);
+ }
+ newShape = new Shape3D(shaft, look);
+ this.addChild(newShape);
+ }
+}
+
diff --git a/src/GearTest/SpurGear.java b/src/GearTest/SpurGear.java
new file mode 100644
index 0000000..c294503
--- /dev/null
+++ b/src/GearTest/SpurGear.java
@@ -0,0 +1,556 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class SpurGear extends Gear {
+
+ float toothTopAngleIncrement;
+ float toothDeclineAngleIncrement;
+
+ float rootRadius;
+ float outsideRadius;
+
+ //The angle subtended by the ascending or descending portion of a tooth
+ float circularToothEdgeAngle;
+ // The angle subtended by a flat (either a tooth top or a valley
+ // between teeth
+ float circularToothFlatAngle;
+
+ /**
+ * internal constructor for SpurGear, used by subclasses to establish
+ * SpurGear's required state
+ * @return a new spur gear that contains sufficient information to
+ * continue building
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ */
+ SpurGear(int toothCount, float pitchCircleRadius,
+ float addendum, float dedendum, float toothToValleyAngleRatio) {
+
+ super(toothCount);
+
+ // The angle about Z subtended by one tooth and its associated valley
+ circularPitchAngle = (float)(2.0 * Math.PI / (double)toothCount);
+
+ // The angle subtended by a flat (either a tooth top or a valley
+ // between teeth
+ circularToothFlatAngle = circularPitchAngle * toothToValleyAngleRatio;
+
+ //The angle subtended by the ascending or descending portion of a tooth
+ circularToothEdgeAngle = circularPitchAngle/2.0f -
+ circularToothFlatAngle;
+
+ // Increment angles
+ toothTopAngleIncrement = circularToothEdgeAngle;
+ toothDeclineAngleIncrement
+ = toothTopAngleIncrement + circularToothFlatAngle;
+ toothValleyAngleIncrement
+ = toothDeclineAngleIncrement + circularToothEdgeAngle;
+
+ // Differential angles for offsetting to the center of tooth's top
+ // and valley
+ toothTopCenterAngle
+ = toothTopAngleIncrement + circularToothFlatAngle/2.0f;
+ valleyCenterAngle
+ = toothValleyAngleIncrement + circularToothFlatAngle/2.0f;
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ gearStartAngle = -1.0 * toothTopCenterAngle;
+
+ // The radial distance to the root and top of the teeth, respectively
+ rootRadius = pitchCircleRadius - dedendum;
+ outsideRadius = pitchCircleRadius + addendum;
+
+ // Allow this object to spin. etc.
+ this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, gearThickness, 0.25f, null);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param look the gear's appearance
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, gearThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param look the gear's appearance
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ float toothTipThickness, Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, toothTipThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ float toothTipThickness, float toothToValleyAngleRatio,
+ Appearance look) {
+
+ this(toothCount, pitchCircleRadius, addendum, dedendum,
+ toothToValleyAngleRatio);
+
+ // Generate the gear's body disks
+ addBodyDisks(shaftRadius, rootRadius, gearThickness, look);
+
+ // Generate the gear's interior shaft
+ addCylinderSkins(shaftRadius, gearThickness, InwardNormals, look);
+
+ // Generate the gear's teeth
+ addTeeth(pitchCircleRadius, rootRadius,
+ outsideRadius, gearThickness, toothTipThickness,
+ toothToValleyAngleRatio, look);
+ }
+
+ /**
+ * Construct a SpurGear's teeth by adding the teeth shape nodes
+ * @param pitchCircleRadius radius at center of teeth
+ * @param rootRadius distance from pitch circle to top of teeth
+ * @param outsideRadius distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ void addTeeth(float pitchCircleRadius, float rootRadius,
+ float outsideRadius, float gearThickness,
+ float toothTipThickness, float toothToValleyAngleRatio,
+ Appearance look) {
+ int index;
+ Shape3D newShape;
+
+ // Temporaries that store start angle for each portion of tooth facet
+ double toothStartAngle, toothTopStartAngle,
+ toothDeclineStartAngle, toothValleyStartAngle,
+ nextToothStartAngle;
+
+ // The x and y coordinates at each point of a facet and at each
+ // point on the gear: at the shaft, the root of the teeth, and
+ // the outer point of the teeth
+ float xRoot0, yRoot0;
+ float xOuter1, yOuter1;
+ float xOuter2, yOuter2;
+ float xRoot3, yRoot3;
+ float xRoot4, yRoot4;
+
+ // The z coordinates for the gear
+ final float frontZ = -0.5f * gearThickness;
+ final float rearZ = 0.5f * gearThickness;
+
+ // The z coordinates for the tooth tip of the gear
+ final float toothTipFrontZ = -0.5f * toothTipThickness;
+ final float toothTipRearZ = 0.5f * toothTipThickness;
+
+ int toothFacetVertexCount; // #(vertices) per tooth facet
+ int toothFacetCount; // #(facets) per tooth
+ int toothFaceTotalVertexCount; // #(vertices) in all teeth
+ int toothFaceStripCount[] = new int[toothCount];
+ // per tooth vertex count
+ int topVertexCount; // #(vertices) for teeth tops
+ int topStripCount[] = new int[1]; // #(vertices) in strip/strip
+
+ // Front and rear facing normals for the teeth faces
+ Vector3f frontToothNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ Vector3f rearToothNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+
+ // Normals for teeth tops up incline, tooth top, and down incline
+ Vector3f leftNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
+ Vector3f rightNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+ Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+ Vector3f inNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate1 = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate2 = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate3 = new Point3f(0.0f, 0.0f, 0.0f);
+ Vector3f tempVector1 = new Vector3f(0.0f, 0.0f, 0.0f);
+ Vector3f tempVector2 = new Vector3f(0.0f, 0.0f, 0.0f);
+
+ /* Construct the gear's front facing teeth facets
+ * 0______2
+ * / /\
+ * / / \
+ * / / \
+ * //___________\
+ * 1 3
+ */
+ toothFacetVertexCount = 4;
+ toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
+ for(int i = 0; i < toothCount; i++)
+ toothFaceStripCount[i] = toothFacetVertexCount;
+
+ TriangleStripArray frontGearTeeth
+ = new TriangleStripArray(toothFaceTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ toothFaceStripCount);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = count * toothFacetVertexCount;
+
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+
+ tempCoordinate1.set(xRoot0, yRoot0, frontZ);
+ tempCoordinate2.set(xRoot3, yRoot3, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector2.sub(tempCoordinate2, tempCoordinate1);
+
+ frontToothNormal.cross(tempVector1, tempVector2);
+ frontToothNormal.normalize();
+
+ coordinate.set(xOuter1, yOuter1, toothTipFrontZ);
+ frontGearTeeth.setCoordinate(index, coordinate);
+ frontGearTeeth.setNormal(index, frontToothNormal);
+
+ coordinate.set(xRoot0, yRoot0, frontZ);
+ frontGearTeeth.setCoordinate(index + 1, coordinate);
+ frontGearTeeth.setNormal(index + 1, frontToothNormal);
+
+ coordinate.set(xOuter2, yOuter2, toothTipFrontZ);
+ frontGearTeeth.setCoordinate(index + 2, coordinate);
+ frontGearTeeth.setNormal(index + 2, frontToothNormal);
+
+ coordinate.set(xRoot3, yRoot3, frontZ);
+ frontGearTeeth.setCoordinate(index + 3, coordinate);
+ frontGearTeeth.setNormal(index + 3, frontToothNormal);
+ }
+ newShape = new Shape3D(frontGearTeeth, look);
+ this.addChild(newShape);
+
+ /* Construct the gear's rear facing teeth facets (Using Quads)
+ * 1______2
+ * / \
+ * / \
+ * / \
+ * /____________\
+ * 0 3
+ */
+ toothFacetVertexCount = 4;
+ toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
+
+ QuadArray rearGearTeeth
+ = new QuadArray(toothCount * toothFacetVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS);
+
+ for(int count = 0; count < toothCount; count++) {
+
+ index = count * toothFacetVertexCount;
+ toothStartAngle =
+ gearStartAngle + circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle = toothStartAngle + toothValleyAngleIncrement;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+
+ tempCoordinate1.set(xRoot0, yRoot0, rearZ);
+ tempCoordinate2.set(xRoot3, yRoot3, rearZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipRearZ);
+ tempVector2.sub(tempCoordinate2, tempCoordinate1);
+ rearToothNormal.cross(tempVector2, tempVector1);
+ rearToothNormal.normalize();
+
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ rearGearTeeth.setCoordinate(index, coordinate);
+ rearGearTeeth.setNormal(index, rearToothNormal);
+
+ coordinate.set(xOuter1, yOuter1, toothTipRearZ);
+ rearGearTeeth.setCoordinate(index + 1, coordinate);
+ rearGearTeeth.setNormal(index + 1, rearToothNormal);
+
+ coordinate.set(xOuter2, yOuter2, toothTipRearZ);
+ rearGearTeeth.setCoordinate(index + 2, coordinate);
+ rearGearTeeth.setNormal(index + 2, rearToothNormal);
+
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ rearGearTeeth.setCoordinate(index + 3, coordinate);
+ rearGearTeeth.setNormal(index + 3, rearToothNormal);
+
+ }
+ newShape = new Shape3D(rearGearTeeth, look);
+ this.addChild(newShape);
+
+ /*
+ * Construct the gear's top teeth faces (As seen from above)
+ * Root0 Outer1 Outer2 Root3 Root4 (RearZ)
+ * 0_______3 2_______5 4_______7 6_______9
+ * |0 3| |4 7| |8 11| |12 15|
+ * | | | | | | | |
+ * | | | | | | | |
+ * |1_____2| |5_____6| |9____10| |13___14|
+ * 1 2 3 4 5 6 7 8
+ * Root0 Outer1 Outer2 Root3 Root4 (FrontZ)
+ *
+ * Quad 0123 uses a left normal
+ * Quad 2345 uses an out normal
+ * Quad 4567 uses a right normal
+ * Quad 6789 uses an out normal
+ */
+ topVertexCount = 8 * toothCount + 2;
+ topStripCount[0] = topVertexCount;
+
+ toothFacetVertexCount = 4;
+ toothFacetCount = 4;
+
+ QuadArray topGearTeeth
+ = new QuadArray(toothCount * toothFacetVertexCount
+ * toothFacetCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = count * toothFacetCount * toothFacetVertexCount;
+ toothStartAngle = gearStartAngle +
+ circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+ xRoot4 = rootRadius * (float)Math.cos(nextToothStartAngle);
+ yRoot4 = rootRadius * (float)Math.sin(nextToothStartAngle);
+
+ // Compute normal for quad 1
+ tempCoordinate1.set(xRoot0, yRoot0, frontZ);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ leftNormal.cross(frontNormal, tempVector1);
+ leftNormal.normalize();
+
+ // Coordinate labeled 0 in the quad
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ topGearTeeth.setCoordinate(index, coordinate);
+ topGearTeeth.setNormal(index, leftNormal);
+
+ // Coordinate labeled 1 in the quad
+ coordinate.set(tempCoordinate1);
+ topGearTeeth.setCoordinate(index + 1, coordinate);
+ topGearTeeth.setNormal(index + 1, leftNormal);
+
+ // Coordinate labeled 2 in the quad
+ topGearTeeth.setCoordinate(index + 2, tempCoordinate2);
+ topGearTeeth.setNormal(index + 2, leftNormal);
+ topGearTeeth.setCoordinate(index + 5, tempCoordinate2);
+
+ // Coordinate labeled 3 in the quad
+ coordinate.set(xOuter1, yOuter1, toothTipRearZ);
+ topGearTeeth.setCoordinate(index + 3, coordinate);
+ topGearTeeth.setNormal(index + 3, leftNormal);
+ topGearTeeth.setCoordinate(index + 4, coordinate);
+
+ // Compute normal for quad 2
+ tempCoordinate1.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempCoordinate2.set(xOuter2, yOuter2, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ outNormal.cross(frontNormal, tempVector1);
+ outNormal.normalize();
+
+ topGearTeeth.setNormal(index + 4, outNormal);
+ topGearTeeth.setNormal(index + 5, outNormal);
+
+ // Coordinate labeled 4 in the quad
+ topGearTeeth.setCoordinate(index + 6, tempCoordinate2);
+ topGearTeeth.setNormal(index + 6, outNormal);
+ topGearTeeth.setCoordinate(index + 9, tempCoordinate2);
+
+ // Coordinate labeled 5 in the quad
+ coordinate.set(xOuter2, yOuter2, toothTipRearZ);
+ topGearTeeth.setCoordinate(index + 7, coordinate);
+ topGearTeeth.setNormal(index + 7, outNormal);
+ topGearTeeth.setCoordinate(index + 8, coordinate);
+
+ // Compute normal for quad 3
+ tempCoordinate1.set(xOuter2, yOuter2, toothTipFrontZ);
+ tempCoordinate2.set(xRoot3, yRoot3, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ rightNormal.cross(frontNormal, tempVector1);
+ rightNormal.normalize();
+
+ topGearTeeth.setNormal(index + 8, rightNormal);
+ topGearTeeth.setNormal(index + 9, rightNormal);
+
+ // Coordinate labeled 7 in the quad
+ topGearTeeth.setCoordinate(index + 10, tempCoordinate2);
+ topGearTeeth.setNormal(index + 10, rightNormal);
+ topGearTeeth.setCoordinate(index + 13, tempCoordinate2);
+
+ // Coordinate labeled 6 in the quad
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ topGearTeeth.setCoordinate(index + 11, coordinate);
+ topGearTeeth.setNormal(index + 11, rightNormal);
+ topGearTeeth.setCoordinate(index + 12, coordinate);
+
+ // Compute normal for quad 4
+ tempCoordinate1.set(xRoot3, yRoot3, frontZ);
+ tempCoordinate2.set(xRoot4, yRoot4, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ outNormal.cross(frontNormal, tempVector1);
+ outNormal.normalize();
+
+ topGearTeeth.setNormal(index + 12, outNormal);
+ topGearTeeth.setNormal(index + 13, outNormal);
+
+ // Coordinate labeled 9 in the quad
+ topGearTeeth.setCoordinate(index + 14, tempCoordinate2);
+ topGearTeeth.setNormal(index + 14, outNormal);
+
+ // Coordinate labeled 8 in the quad
+ coordinate.set(xRoot4, yRoot4, rearZ);
+ topGearTeeth.setCoordinate(index + 15, coordinate);
+ topGearTeeth.setNormal(index + 15, outNormal);
+
+ // Prepare for the loop by computing the new normal
+ toothTopStartAngle
+ = nextToothStartAngle + toothTopAngleIncrement;
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+
+ tempCoordinate1.set(xRoot4, yRoot4, toothTipFrontZ);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ leftNormal.cross(frontNormal, tempVector1);
+ leftNormal.normalize();
+ }
+ newShape = new Shape3D(topGearTeeth, look);
+ this.addChild(newShape);
+ }
+
+}
diff --git a/src/GearTest/SpurGearThinBody.java b/src/GearTest/SpurGearThinBody.java
new file mode 100644
index 0000000..76f2415
--- /dev/null
+++ b/src/GearTest/SpurGearThinBody.java
@@ -0,0 +1,185 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class SpurGearThinBody extends SpurGear {
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness) {
+ this(toothCount, pitchCircleRadius, shaftRadius,
+ addendum, dedendum, gearThickness, gearThickness, 0.25f, null);
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param look the gear's appearance
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness,
+ Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius,
+ addendum, dedendum, gearThickness, gearThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param look the gear's appearance
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness, float toothTipThickness,
+ Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum,
+ dedendum, gearThickness, toothTipThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyRatio ratio of tooth valley to circular pitch
+ * (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness, float toothTipThickness,
+ float toothToValleyAngleRatio, Appearance look) {
+
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum,
+ dedendum, gearThickness, toothTipThickness, 0.25f, look,
+ 0.6f * gearThickness, 0.75f * (pitchCircleRadius - shaftRadius));
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyRatio ratio of tooth valley to circular pitch
+ * (must be <= .25)
+ * @param look the gear's appearance object
+ * @param bodyThickness the thickness of the gear body
+ * @param crossSectionWidth the width of the depressed portion of the
+ * gear's body
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness, float toothTipThickness,
+ float toothToValleyAngleRatio, Appearance look,
+ float bodyThickness, float crossSectionWidth) {
+
+ super(toothCount, pitchCircleRadius, addendum, dedendum,
+ toothToValleyAngleRatio);
+
+ float diskCrossSectionWidth =
+ (rootRadius - shaftRadius - crossSectionWidth)/ 2.0f;
+ float outerShaftRadius = shaftRadius + diskCrossSectionWidth;
+ float innerToothRadius = rootRadius - diskCrossSectionWidth;
+
+ // Generate the gear's body disks, first by the shaft, then in
+ // the body and, lastly, by the teeth
+ addBodyDisks(shaftRadius, outerShaftRadius,
+ gearThickness, look);
+ addBodyDisks(innerToothRadius, rootRadius,
+ gearThickness, look);
+ addBodyDisks(outerShaftRadius, innerToothRadius,
+ bodyThickness, look);
+
+ // Generate the gear's "shaft" equivalents the two at the teeth
+ // and the two at the shaft
+ addCylinderSkins(innerToothRadius, gearThickness, InwardNormals, look);
+ addCylinderSkins(outerShaftRadius, gearThickness, OutwardNormals, look);
+
+ // Generate the gear's interior shaft
+ addCylinderSkins(shaftRadius, gearThickness, InwardNormals, look);
+
+ // Generate the gear's teeth
+ addTeeth(pitchCircleRadius, rootRadius,
+ outsideRadius, gearThickness, toothTipThickness,
+ toothToValleyAngleRatio, look);
+ }
+
+}
diff --git a/src/GearTest/build.xml b/src/GearTest/build.xml
new file mode 100644
index 0000000..cbf53a8
--- /dev/null
+++ b/src/GearTest/build.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<project basedir="." default="compile">
+ <target name="compile">
+ <javac debug="true" deprecation="true" destdir="." srcdir=".">
+ </javac>
+ </target>
+
+ <target name="all" depends="compile">
+ </target>
+
+ <target description="Clean all build products." name="clean">
+ <delete>
+ <fileset dir=".">
+ <include name="**/*.class"/>
+ </fileset>
+ </delete>
+ </target>
+
+</project>