Example usage for javax.media.j3d Shape3D Shape3D

List of usage examples for javax.media.j3d Shape3D Shape3D

Introduction

In this page you can find the example usage for javax.media.j3d Shape3D Shape3D.

Prototype

public Shape3D(Geometry geometry, Appearance appearance) 

Source Link

Document

Constructs and initializes a Shape3D node with the specified geometry and appearance components.

Usage

From source file:AppearanceExplorer.java

Shape3D createTexTris() {

    Point3f pnt[] = new Point3f[9];
    pnt[0] = new Point3f(-0.8f, -0.8f, 0.0f);
    pnt[1] = new Point3f(-0.5f, -0.7f, 0.0f);
    pnt[2] = new Point3f(-0.7f, 0.7f, 0.0f);

    pnt[3] = new Point3f(-0.4f, 0.7f, 0.0f);
    pnt[4] = new Point3f(0.0f, -0.7f, 0.0f);
    pnt[5] = new Point3f(0.4f, 0.7f, 0.0f);

    pnt[6] = new Point3f(0.5f, 0.7f, 0.0f);
    pnt[7] = new Point3f(0.5f, -0.7f, 0.0f);
    pnt[8] = new Point3f(0.9f, 0.0f, 0.0f);

    TexCoord2f texCoord[] = new TexCoord2f[9];
    texCoord[0] = new TexCoord2f(0.05f, 0.90f);
    texCoord[1] = new TexCoord2f(0.25f, 0.10f);
    texCoord[2] = new TexCoord2f(1.00f, 0.60f);

    texCoord[3] = texCoord[0];/*from  w  w w .  jav a 2  s .  co  m*/
    texCoord[4] = texCoord[1];
    texCoord[5] = texCoord[2];

    texCoord[6] = texCoord[0];
    texCoord[7] = texCoord[1];
    texCoord[8] = texCoord[2];

    TriangleArray ta = new TriangleArray(9, GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2);
    ta.setCoordinates(0, pnt);
    ta.setTextureCoordinates(0, 0, texCoord);

    return new Shape3D(ta, appearance);
}

From source file:AppearanceExplorer.java

Shape3D createTexSquare() {

    // color cube
    Point3f pnt[] = new Point3f[4];
    pnt[0] = new Point3f(-1.0f, -1.0f, 0.0f);
    pnt[1] = new Point3f(1.0f, -1.0f, 0.0f);
    pnt[2] = new Point3f(1.0f, 1.0f, 0.0f);
    pnt[3] = new Point3f(-1.0f, 1.0f, 0.0f);
    TexCoord2f texCoord[] = new TexCoord2f[4];
    texCoord[0] = new TexCoord2f(0.0f, 0.0f);
    texCoord[1] = new TexCoord2f(1.0f, 0.0f);
    texCoord[2] = new TexCoord2f(1.0f, 1.0f);
    texCoord[3] = new TexCoord2f(0.0f, 1.0f);

    QuadArray qa = new QuadArray(4, GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2);
    qa.setCoordinates(0, pnt);/*from  w w  w. j  a  v a 2s.  c  om*/
    qa.setTextureCoordinates(0, 0, texCoord);

    return new Shape3D(qa, appearance);
}

From source file:AppearanceExplorer.java

Shape3D createLargeTexSquare() {

    // color cube
    Point3f pnt[] = new Point3f[4];
    pnt[0] = new Point3f(-1.0f, -1.0f, 0.0f);
    pnt[1] = new Point3f(1.0f, -1.0f, 0.0f);
    pnt[2] = new Point3f(1.0f, 1.0f, 0.0f);
    pnt[3] = new Point3f(-1.0f, 1.0f, 0.0f);
    TexCoord2f texCoord[] = new TexCoord2f[4];
    texCoord[0] = new TexCoord2f(-1.0f, -1.0f);
    texCoord[1] = new TexCoord2f(2.0f, -1.0f);
    texCoord[2] = new TexCoord2f(2.0f, 2.0f);
    texCoord[3] = new TexCoord2f(-1.0f, 2.0f);

    QuadArray qa = new QuadArray(4, GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2);
    qa.setCoordinates(0, pnt);/*from  ww w  . j av  a 2  s  .  c  o  m*/
    qa.setTextureCoordinates(0, 0, texCoord);

    return new Shape3D(qa, appearance);
}

From source file:AppearanceExplorer.java

Shape3D createColorCube() {

    // color cube
    int[] indices = { 0, 3, 4, 2, // left face x = -1
            0, 1, 5, 3, // bottom face y = -1
            0, 2, 6, 1, // back face z = -1
            7, 5, 1, 6, // right face x = 1
            7, 6, 2, 4, // top face y = 1
            7, 4, 3, 5 // front face z = 1
    };//from ww w  .  ja v  a2  s . co m

    Point3f pts[] = new Point3f[8];
    pts[0] = new Point3f(-1.0f, -1.0f, -1.0f);
    pts[1] = new Point3f(1.0f, -1.0f, -1.0f);
    pts[2] = new Point3f(-1.0f, 1.0f, -1.0f);
    pts[3] = new Point3f(-1.0f, -1.0f, 1.0f);
    pts[4] = new Point3f(-1.0f, 1.0f, 1.0f);
    pts[5] = new Point3f(1.0f, -1.0f, 1.0f);
    pts[6] = new Point3f(1.0f, 1.0f, -1.0f);
    pts[7] = new Point3f(1.0f, 1.0f, 1.0f);
    Color3f colr[] = new Color3f[8];
    colr[0] = black;
    colr[1] = red;
    colr[2] = green;
    colr[3] = blue;
    colr[4] = cyan;
    colr[5] = magenta;
    colr[6] = yellow;
    colr[7] = white;
    // The normals point out from 0,0,0, through the verticies of the
    // cube. These can be calculated by copying the coordinates to
    // a Vector3f and normalizing.
    Vector3f norm[] = new Vector3f[8];
    for (int i = 0; i < 8; i++) {
        norm[i] = new Vector3f(pts[i]);
        norm[i].normalize();
    }

    IndexedQuadArray iqa = new IndexedQuadArray(8,
            GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.NORMALS, 24);
    iqa.setCoordinates(0, pts);
    iqa.setColors(0, colr);
    iqa.setNormals(0, norm);
    iqa.setCoordinateIndices(0, indices);
    iqa.setColorIndices(0, indices);
    iqa.setNormalIndices(0, indices);
    return new Shape3D(iqa, appearance);
}

From source file:AppearanceExplorer.java

Shape3D createNGCube(float creaseAngle) {

    // color cube
    int[] indices = { 0, 3, 4, 2, // left face x = -1
            0, 1, 5, 3, // bottom face y = -1
            0, 2, 6, 1, // back face z = -1
            7, 5, 1, 6, // right face x = 1
            7, 6, 2, 4, // top face y = 1
            7, 4, 3, 5 // front face z = 1
    };//from  w  w w. j  a  va  2  s. co m

    Point3f pts[] = new Point3f[8];
    pts[0] = new Point3f(-1.0f, -1.0f, -1.0f);
    pts[1] = new Point3f(1.0f, -1.0f, -1.0f);
    pts[2] = new Point3f(-1.0f, 1.0f, -1.0f);
    pts[3] = new Point3f(-1.0f, -1.0f, 1.0f);
    pts[4] = new Point3f(-1.0f, 1.0f, 1.0f);
    pts[5] = new Point3f(1.0f, -1.0f, 1.0f);
    pts[6] = new Point3f(1.0f, 1.0f, -1.0f);
    pts[7] = new Point3f(1.0f, 1.0f, 1.0f);

    GeometryInfo gi = new GeometryInfo(GeometryInfo.QUAD_ARRAY);
    gi.setCoordinates(pts);
    gi.setCoordinateIndices(indices);
    NormalGenerator ng = new NormalGenerator();
    ng.setCreaseAngle((float) Math.toRadians(creaseAngle));
    ng.generateNormals(gi);
    GeometryArray cube = gi.getGeometryArray();
    return new Shape3D(cube, appearance);
}

From source file:AppearanceExplorer.java

Shape3D createTriWithHole() {

    int[] stripCounts = new int[2];
    stripCounts[0] = 3;/*from   w  w w. j av  a2 s. c om*/
    stripCounts[1] = 3;
    int[] contourCounts = new int[1];
    contourCounts[0] = 2;
    Point3f pnt[] = new Point3f[6];
    pnt[0] = new Point3f(-1.0f, -1.0f, 0.0f);
    pnt[1] = new Point3f(1.0f, -1.0f, 0.0f);
    pnt[2] = new Point3f(1.0f, 1.0f, 0.0f);
    pnt[3] = new Point3f(-0.6f, -0.8f, 0.0f);
    pnt[4] = new Point3f(0.8f, 0.6f, 0.0f);
    pnt[5] = new Point3f(0.8f, -0.8f, 0.0f);

    GeometryInfo gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
    gi.setCoordinates(pnt);
    gi.setStripCounts(stripCounts);
    gi.setContourCounts(contourCounts);

    Triangulator tr = new Triangulator();
    tr.triangulate(gi);
    GeometryArray triWithHole = gi.getGeometryArray();

    return new Shape3D(triWithHole, appearance);
}

From source file:AppearanceExplorer.java

Shape3D createText3D() {
    Font3D f3d = new Font3D(new Font(null, Font.PLAIN, 2), new FontExtrusion());
    Text3D t3d = new Text3D(f3d, "Text3D", new Point3f(-3.0f, -1.0f, 0.0f));
    Shape3D textShape = new Shape3D(t3d, appearance);
    return textShape;
}

From source file:ExLinearFog.java

private void addBox(float width, float height, float depth, float y, float width2, float depth2, int flags) {
    float[] coordinates = {
            // around the bottom
            -width / 2.0f, -height / 2.0f, depth / 2.0f, width / 2.0f, -height / 2.0f, depth / 2.0f,
            width / 2.0f, -height / 2.0f, -depth / 2.0f, -width / 2.0f, -height / 2.0f, -depth / 2.0f,

            // around the top
            -width2 / 2.0f, height / 2.0f, depth2 / 2.0f, width2 / 2.0f, height / 2.0f, depth2 / 2.0f,
            width2 / 2.0f, height / 2.0f, -depth2 / 2.0f, -width2 / 2.0f, height / 2.0f, -depth2 / 2.0f, };
    int[] fullCoordinateIndexes = { 0, 1, 5, 4, // front
            1, 2, 6, 5, // right
            2, 3, 7, 6, // back
            3, 0, 4, 7, // left
            4, 5, 6, 7, // top
            3, 2, 1, 0, // bottom
    };//from  www . ja v a2s.co m
    float v = -(width2 - width) / height;
    float[] normals = { 0.0f, v, 1.0f, // front
            1.0f, v, 0.0f, // right
            0.0f, v, -1.0f, // back
            -1.0f, v, 0.0f, // left
            0.0f, 1.0f, 0.0f, // top
            0.0f, -1.0f, 0.0f, // bottom
    };
    int[] fullNormalIndexes = { 0, 0, 0, 0, // front
            1, 1, 1, 1, // right
            2, 2, 2, 2, // back
            3, 3, 3, 3, // left
            4, 4, 4, 4, // top
            5, 5, 5, 5, // bottom
    };
    float[] textureCoordinates = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, };
    int[] fullTextureCoordinateIndexes = { 0, 1, 2, 3, // front
            0, 1, 2, 3, // right
            0, 1, 2, 3, // back
            0, 1, 2, 3, // left
            0, 1, 2, 3, // top
            0, 1, 2, 3, // bottom
    };

    // Select indexes needed
    int[] coordinateIndexes;
    int[] normalIndexes;
    int[] textureCoordinateIndexes;
    if (flags == 0) {
        // build neither top or bottom
        coordinateIndexes = new int[4 * 4];
        textureCoordinateIndexes = new int[4 * 4];
        normalIndexes = new int[4 * 4];
        for (int i = 0; i < 4 * 4; i++) {
            coordinateIndexes[i] = fullCoordinateIndexes[i];
            textureCoordinateIndexes[i] = fullTextureCoordinateIndexes[i];
            normalIndexes[i] = fullNormalIndexes[i];
        }
    } else if ((flags & (BUILD_TOP | BUILD_BOTTOM)) == (BUILD_TOP | BUILD_BOTTOM)) {
        // build top and bottom
        coordinateIndexes = fullCoordinateIndexes;
        textureCoordinateIndexes = fullTextureCoordinateIndexes;
        normalIndexes = fullNormalIndexes;
    } else if ((flags & BUILD_TOP) != 0) {
        // build top but not bottom
        coordinateIndexes = new int[5 * 4];
        textureCoordinateIndexes = new int[5 * 4];
        normalIndexes = new int[5 * 4];
        for (int i = 0; i < 5 * 4; i++) {
            coordinateIndexes[i] = fullCoordinateIndexes[i];
            textureCoordinateIndexes[i] = fullTextureCoordinateIndexes[i];
            normalIndexes[i] = fullNormalIndexes[i];
        }
    } else {
        // build bottom but not top
        coordinateIndexes = new int[5 * 4];
        textureCoordinateIndexes = new int[5 * 4];
        normalIndexes = new int[5 * 4];
        for (int i = 0; i < 4 * 4; i++) {
            coordinateIndexes[i] = fullCoordinateIndexes[i];
            textureCoordinateIndexes[i] = fullTextureCoordinateIndexes[i];
            normalIndexes[i] = fullNormalIndexes[i];
        }
        for (int i = 5 * 4; i < 6 * 4; i++) {
            coordinateIndexes[i - 4] = fullCoordinateIndexes[i];
            textureCoordinateIndexes[i - 4] = fullTextureCoordinateIndexes[i];
            normalIndexes[i - 4] = fullNormalIndexes[i];
        }
    }

    IndexedQuadArray quads = new IndexedQuadArray(coordinates.length, // number
            // of
            // vertexes
            GeometryArray.COORDINATES | // vertex coordinates given
                    GeometryArray.NORMALS | // normals given
                    GeometryArray.TEXTURE_COORDINATE_2, // texture
            // coordinates given
            coordinateIndexes.length); // number of coordinate indexes
    quads.setCoordinates(0, coordinates);
    quads.setCoordinateIndices(0, coordinateIndexes);
    quads.setNormals(0, normals);
    quads.setNormalIndices(0, normalIndexes);
    quads.setTextureCoordinates(0, textureCoordinates);
    quads.setTextureCoordinateIndices(0, textureCoordinateIndexes);
    Shape3D box = new Shape3D(quads, mainAppearance);

    Vector3f trans = new Vector3f(0.0f, y, 0.0f);
    Transform3D tr = new Transform3D();
    tr.set(trans); // translate
    TransformGroup tg = new TransformGroup(tr);
    tg.addChild(box);
    addChild(tg);
}

From source file:ExLinearFog.java

private void addCylinder(float radius, float height, float y) {
    ////from w w  w. j av a2  s .c om
    //  Compute coordinates, normals, and texture coordinates
    //  around the top and bottom of a cylinder
    //
    float[] coordinates = new float[NSTEPS * 2 * 3]; // xyz
    float[] normals = new float[NSTEPS * 2 * 3]; // xyz vector
    float[] textureCoordinates = new float[NSTEPS * 2 * 2]; // st
    float angle = 0.0f;
    float deltaAngle = 2.0f * (float) Math.PI / ((float) NSTEPS - 1);
    float s = 0.0f;
    float deltaS = 1.0f / ((float) NSTEPS - 1);
    int n = 0;
    int tn = 0;
    float h2 = height / 2.0f;
    for (int i = 0; i < NSTEPS; i++) {
        // bottom
        normals[n + 0] = (float) Math.cos(angle);
        normals[n + 1] = 0.0f;
        normals[n + 2] = -(float) Math.sin(angle);
        coordinates[n + 0] = radius * normals[n + 0];
        coordinates[n + 1] = -h2;
        coordinates[n + 2] = radius * normals[n + 2];
        textureCoordinates[tn + 0] = s;
        textureCoordinates[tn + 1] = 0.0f;
        n += 3;
        tn += 2;

        // top
        normals[n + 0] = normals[n - 3];
        normals[n + 1] = 0.0f;
        normals[n + 2] = normals[n - 1];
        coordinates[n + 0] = coordinates[n - 3];
        coordinates[n + 1] = h2;
        coordinates[n + 2] = coordinates[n - 1];
        textureCoordinates[tn + 0] = s;
        textureCoordinates[tn + 1] = 1.0f;
        n += 3;
        tn += 2;

        angle += deltaAngle;
        s += deltaS;
    }

    //
    //  Compute coordinate indexes, normal indexes, and texture
    //  coordinate indexes awround the sides of a cylinder.
    //  For this application, we don't need top or bottom, so
    //  skip them.
    //
    int[] indexes = new int[NSTEPS * 4];
    n = 0;
    int p = 0; // panel count
    for (int i = 0; i < NSTEPS - 1; i++) {
        indexes[n + 0] = p; // bottom left
        indexes[n + 1] = p + 2; // bottom right (next panel)
        indexes[n + 2] = p + 3; // top right (next panel)
        indexes[n + 3] = p + 1; // top left
        n += 4;
        p += 2;
    }
    indexes[n + 0] = p; // bottom left
    indexes[n + 1] = 0; // bottom right (next panel)
    indexes[n + 2] = 1; // top right (next panel)
    indexes[n + 3] = p + 1; // top left

    IndexedQuadArray quads = new IndexedQuadArray(coordinates.length / 3, // number
            // of
            // vertexes
            GeometryArray.COORDINATES | // format
                    GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2,
            indexes.length); // number
    // of
    // indexes
    quads.setCoordinates(0, coordinates);
    quads.setTextureCoordinates(0, textureCoordinates);
    quads.setNormals(0, normals);
    quads.setCoordinateIndices(0, indexes);
    quads.setTextureCoordinateIndices(0, indexes);
    quads.setNormalIndices(0, indexes);

    Shape3D shape = new Shape3D(quads, mainAppearance);

    Vector3f trans = new Vector3f(0.0f, y, 0.0f);
    Transform3D tr = new Transform3D();
    tr.set(trans); // translate
    TransformGroup tg = new TransformGroup(tr);

    tg.addChild(shape);
    addChild(tg);
}

From source file:GearTest.java

/**
 * Construct a SpurGear's teeth by adding the teeth shape nodes
 * /*  w w  w .  jav  a 2 s  . c  o m*/
 * @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);
}