Example usage for javax.media.j3d Transform3D rotY

List of usage examples for javax.media.j3d Transform3D rotY

Introduction

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

Prototype

public void rotY(double angle) 

Source Link

Document

Sets the value of this transform to a counter clockwise rotation about the y axis.

Usage

From source file:SplineAnim.java

public BranchGroup createSceneGraph() {

    // Colors for lights and objects
    Color3f aColor = new Color3f(0.2f, 0.2f, 0.2f);
    Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
    Color3f coneColor = new Color3f(0.9f, 0.1f, 0.1f);
    Color3f sphereColor = new Color3f(0.1f, 0.7f, 0.9f);
    Color3f bgColor = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f lightColor = new Color3f(1.0f, 1.0f, 1.0f);

    // Root of the branch grsph
    BranchGroup root = new BranchGroup();

    // Create transforms such that all objects appears in the scene
    sceneTransform = new Transform3D();
    sceneTransform.setScale(0.14f);/*from www .  j  a  va  2s.com*/
    Transform3D yrot = new Transform3D();
    yrot.rotY(-Math.PI / 5.0d);
    sceneTransform.mul(yrot);
    sceneTransformGroup = new TransformGroup(sceneTransform);
    sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    root.addChild(sceneTransformGroup);

    // Create bounds for the background and lights
    bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0f);

    // Set up the background
    Background bg = new Background(bgColor);
    bg.setApplicationBounds(bounds);
    sceneTransformGroup.addChild(bg);

    // Create the transform group node for the lights
    lightTransform1 = new Transform3D();
    lightTransform2 = new Transform3D();
    Vector3d lightPos1 = new Vector3d(0.0, 0.0, 2.0);
    Vector3d lightPos2 = new Vector3d(1.0, 0.0, -2.0);
    lightTransform1.set(lightPos1);
    lightTransform2.set(lightPos2);
    light1TransformGroup = new TransformGroup(lightTransform1);
    light2TransformGroup = new TransformGroup(lightTransform2);
    sceneTransformGroup.addChild(light1TransformGroup);
    sceneTransformGroup.addChild(light2TransformGroup);

    // Create lights
    AmbientLight ambLight = new AmbientLight(aColor);
    Light dirLight1;
    Light dirLight2;

    Vector3f lightDir1 = new Vector3f(lightPos1);
    Vector3f lightDir2 = new Vector3f(lightPos2);
    lightDir1.negate();
    lightDir2.negate();
    dirLight1 = new DirectionalLight(lightColor, lightDir1);
    dirLight2 = new DirectionalLight(lightColor, lightDir2);

    // Set the influencing bounds
    ambLight.setInfluencingBounds(bounds);
    dirLight1.setInfluencingBounds(bounds);
    dirLight2.setInfluencingBounds(bounds);

    // Add the lights into the scene graph
    sceneTransformGroup.addChild(ambLight);
    sceneTransformGroup.addChild(dirLight1);
    sceneTransformGroup.addChild(dirLight2);

    // Create a cone and add it to the scene graph.
    objTransform = new Transform3D();
    objTransformGroup = new TransformGroup(objTransform);
    objTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    sceneTransformGroup.addChild(objTransformGroup);

    Material m = new Material(coneColor, eColor, coneColor, sColor, 100.0f);
    Appearance a = new Appearance();
    m.setLightingEnable(true);
    a.setMaterial(m);
    Cone cone = new Cone(0.4f, 1.0f);
    cone.setAppearance(a);
    objTransformGroup.addChild(cone);

    // Create transform groups for each knot point
    // knot point 0
    Transform3D t3dKnot = new Transform3D();
    t3dKnot.set(pos0);
    TransformGroup k0TransformGroup = new TransformGroup(t3dKnot);
    sceneTransformGroup.addChild(k0TransformGroup);

    // knot point 1
    t3dKnot = new Transform3D();
    t3dKnot.set(pos1);
    TransformGroup k1TransformGroup = new TransformGroup(t3dKnot);
    sceneTransformGroup.addChild(k1TransformGroup);

    // knot point 2
    t3dKnot = new Transform3D();
    t3dKnot.set(pos2);
    TransformGroup k2TransformGroup = new TransformGroup(t3dKnot);
    sceneTransformGroup.addChild(k2TransformGroup);

    // knot point 3
    t3dKnot = new Transform3D();
    t3dKnot.set(pos3);
    TransformGroup k3TransformGroup = new TransformGroup(t3dKnot);
    sceneTransformGroup.addChild(k3TransformGroup);

    // knot point 4
    t3dKnot = new Transform3D();
    t3dKnot.set(pos4);
    TransformGroup k4TransformGroup = new TransformGroup(t3dKnot);
    sceneTransformGroup.addChild(k4TransformGroup);

    // knot point 5
    t3dKnot = new Transform3D();
    t3dKnot.set(pos5);
    TransformGroup k5TransformGroup = new TransformGroup(t3dKnot);
    sceneTransformGroup.addChild(k5TransformGroup);

    // Create spheres for each knot point's transform group
    ColoringAttributes sphereColorAttr = new ColoringAttributes();
    sphereColorAttr.setColor(sphereColor);
    Appearance sphereAppearance = new Appearance();
    sphereAppearance.setColoringAttributes(sphereColorAttr);
    k0TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
    k1TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
    k2TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
    k3TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
    k4TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
    k5TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));

    return root;
}

From source file:AvatarTest.java

public TransformGroup addBehaviors(Group bgRoot) {
    // 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);

    Transform3D zAxis = new Transform3D();
    zAxis.rotY(Math.toRadians(90.0));

    Alpha zoomAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 20000, 0, 0, 0, 0, 0);

    PositionInterpolator posInt = new PositionInterpolator(zoomAlpha, objTrans, zAxis, 0, -160);

    posInt.setSchedulingBounds(getBoundingSphere());
    objTrans.addChild(posInt);//from   w  w  w .j av  a  2 s  .  c o  m

    bgRoot.addChild(objTrans);

    return objTrans;
}

From source file:Text2DTest.java

/**
 * Process a keyboard event to move or rotate the viewer.
 *///from   w  w w  . j a  va  2  s .  c  o m
void processManualEvent(AWTEvent[] events) {

    for (int i = 0; i < events.length; ++i) {
        if (events[i] instanceof KeyEvent) {
            KeyEvent event = (KeyEvent) events[i];
            if (event.getKeyCode() == KeyEvent.VK_EQUALS) {
                continue;
            }
            Transform3D t = new Transform3D();
            viewTransformGroup.getTransform(t);
            Vector3f viewDir = new Vector3f(0f, 0f, -1f);
            Vector3f translation = new Vector3f();
            t.get(translation);
            t.transform(viewDir);
            if (event.getKeyCode() == KeyEvent.VK_UP) {
                translation.x += viewDir.x;
                translation.y += viewDir.y;
                translation.z += viewDir.z;
            } else if (event.getKeyCode() == KeyEvent.VK_DOWN) {
                translation.x -= viewDir.x;
                translation.y -= viewDir.y;
                translation.z -= viewDir.z;
            } else if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
                rotation += -.1;
            } else if (event.getKeyCode() == KeyEvent.VK_LEFT) {
                rotation += .1;
            }
            t.rotY(rotation);
            t.setTranslation(translation);
            viewTransformGroup.setTransform(t);
        }
    }
}

From source file:BackgroundGeometry.java

public BranchGroup createSceneGraph() {

    // 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);//  w  w w.j av  a2 s . com
    objScale.setTransform(t3d);
    objRoot.addChild(objScale);

    // 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.
    TransformGroup objTrans = new TransformGroup();
    objScale.addChild(objTrans);

    Background bg = new Background();
    bg.setApplicationBounds(bounds);
    BranchGroup backGeoBranch = new BranchGroup();
    Sphere sphereObj = new Sphere(1.0f,
            Sphere.GENERATE_NORMALS | Sphere.GENERATE_NORMALS_INWARD | Sphere.GENERATE_TEXTURE_COORDS, 45);
    Appearance backgroundApp = sphereObj.getAppearance();
    backGeoBranch.addChild(sphereObj);
    bg.setGeometry(backGeoBranch);
    objTrans.addChild(bg);

    TextureLoader tex = new TextureLoader(bgImage, new String("RGB"), this);
    if (tex != null)
        backgroundApp.setTexture(tex.getTexture());

    Vector3f tranlation = new Vector3f(2.0f, 0.0f, 0.0f);
    Transform3D modelTransform = new Transform3D();
    Transform3D tmpTransform = new Transform3D();
    double angleInc = Math.PI / 8.0;
    double angle = 0.0;
    int numBoxes = 16;

    float scaleX[] = { 0.1f, 0.2f, 0.2f, 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.1f, 0.3f, 0.2f, 0.3f, 0.1f, 0.3f, 0.2f,
            0.3f };

    float scaleY[] = { 0.3f, 0.4f, 0.3f, 0.4f, 0.3f, 0.4f, 0.3f, 0.4f, 0.3f, 0.3f, 0.3f, 0.3f, 0.3f, 0.3f, 0.3f,
            0.4f };

    float scaleZ[] = { 0.3f, 0.2f, 0.1f, 0.1f, 0.3f, 0.2f, 0.1f, 0.3f, 0.3f, 0.2f, 0.1f, 0.3f, 0.3f, 0.2f, 0.1f,
            0.2f };

    Appearance a1 = new Appearance();
    Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f sColor = new Color3f(0.5f, 0.5f, 1.0f);
    Color3f oColor = new Color3f(0.5f, 0.5f, 0.3f);

    Material m = new Material(oColor, eColor, oColor, sColor, 100.0f);
    m.setLightingEnable(true);
    a1.setMaterial(m);

    for (int i = 0; i < numBoxes; i++, angle += angleInc) {
        modelTransform.rotY(angle);
        tmpTransform.set(tranlation);
        modelTransform.mul(tmpTransform);

        TransformGroup tgroup = new TransformGroup(modelTransform);
        objTrans.addChild(tgroup);

        tgroup.addChild(new Box(scaleX[i], scaleY[i], scaleZ[i], Box.GENERATE_NORMALS, a1));
    }

    // Shine it with two lights.
    Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
    Color3f lColor2 = new Color3f(0.2f, 0.2f, 0.1f);
    Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
    Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f);
    DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
    DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2);
    lgt1.setInfluencingBounds(bounds);
    lgt2.setInfluencingBounds(bounds);
    objScale.addChild(lgt1);
    objScale.addChild(lgt2);

    return objRoot;
}

From source file:KeyNavigateTest.java

protected void doRotateY(double radians) {
    transformGroup.getTransform(transform3D);
    Transform3D toMove = new Transform3D();
    toMove.rotY(radians);
    transform3D.mul(toMove);//from w w w. ja v  a2  s. com
    updateTransform();
}

From source file:AppearanceTest.java

public void onY_30_degrees() {
    Transform3D t3d = new Transform3D();
    t3d.rotY(Math.toRadians(30));
    getTextureAttributes().setTextureTransform(t3d);
}

From source file:Gouraud.java

/**
 * Erstellt den Szenegraphen//from   www  . ja v  a  2s .  com
 * 
 * @return BranchGroup
 */
public BranchGroup macheSzene() {
    BranchGroup objWurzel = new BranchGroup();
    // Transformation, 2 Rotationen:
    Transform3D drehung = new Transform3D();
    Transform3D drehung2 = new Transform3D();
    drehung.rotX(Math.PI / 4.0d);
    drehung2.rotY(Math.PI / 5.0d);
    drehung.mul(drehung2);
    TransformGroup objDreh = new TransformGroup(drehung);
    //Loader
    ObjectFile file = new ObjectFile(ObjectFile.RESIZE);
    Scene scene = null;
    try {
        // Laden der Obj Datei mittels jar
        scene = file.load(ClassLoader.getSystemResource("teapot.obj"));
    } catch (Exception e) {
        System.err.println(e);
        System.exit(1);
    }
    objDreh.addChild(scene.getSceneGroup());

    DirectionalLight d_Licht = new DirectionalLight(new Color3f(1.0f, 1.0f, 1.0f),
            new Vector3f(-1.0f, -1.0f, -1.0f));
    d_Licht.setInfluencingBounds(new BoundingSphere(new Point3d(0.0d, 0.0d, 0.0d), 100.0d));
    objDreh.addChild(d_Licht);
    objWurzel.addChild(objDreh);
    return objWurzel;
}

From source file:ExHenge.java

public Group buildRing(SharedGroup sg) {
    Group g = new Group();

    g.addChild(new Link(sg)); // 0 degrees

    TransformGroup tg = new TransformGroup();
    Transform3D tr = new Transform3D();
    tr.rotY(0.785); // 45 degrees
    tg.setTransform(tr);/*w w w . ja v  a2 s.  c  o  m*/
    tg.addChild(new Link(sg));
    g.addChild(tg);

    tg = new TransformGroup();
    tr = new Transform3D();
    tr.rotY(-0.785); // -45 degrees
    tg.setTransform(tr);
    tg.addChild(new Link(sg));
    g.addChild(tg);

    tg = new TransformGroup();
    tr = new Transform3D();
    tr.rotY(1.571); // 90 degrees
    tg.setTransform(tr);
    tg.addChild(new Link(sg));
    g.addChild(tg);

    tg = new TransformGroup();
    tr = new Transform3D();
    tr.rotY(-1.571); // -90 degrees
    tg.setTransform(tr);
    tg.addChild(new Link(sg));
    g.addChild(tg);

    tg = new TransformGroup();
    tr = new Transform3D();
    tr.rotY(2.356); // 135 degrees
    tg.setTransform(tr);
    tg.addChild(new Link(sg));
    g.addChild(tg);

    tg = new TransformGroup();
    tr = new Transform3D();
    tr.rotY(-2.356); // -135 degrees
    tg.setTransform(tr);
    tg.addChild(new Link(sg));
    g.addChild(tg);

    tg = new TransformGroup();
    tr = new Transform3D();
    tr.rotY(Math.PI); // 180 degrees
    tg.setTransform(tr);
    tg.addChild(new Link(sg));
    g.addChild(tg);

    return g;
}

From source file:ExBluePrint.java

private Group buildGadget() {
    if (debug)/*from ww  w  . ja v  a 2s .co m*/
        System.err.println("  gadget...");
    //
    //  Create two appearances:
    //    wireframeApp: draw as blue wireframe
    //    shadedApp: draw as metalic shaded polygons
    //

    //  Wireframe:
    //    no Material - defaults to coloring attributes color
    //    polygons as lines, with backfaces
    //    thick lines
    Appearance wireframeApp = new Appearance();

    ColoringAttributes wireframeCatt = new ColoringAttributes();
    wireframeCatt.setColor(0.0f, 0.2559f, 0.4213f);
    wireframeCatt.setShadeModel(ColoringAttributes.SHADE_FLAT);
    wireframeApp.setColoringAttributes(wireframeCatt);

    PolygonAttributes wireframePatt = new PolygonAttributes();
    wireframePatt.setPolygonMode(PolygonAttributes.POLYGON_LINE);
    wireframePatt.setCullFace(PolygonAttributes.CULL_NONE);
    wireframeApp.setPolygonAttributes(wireframePatt);

    LineAttributes wireframeLatt = new LineAttributes();
    wireframeLatt.setLineWidth(2.0f);
    wireframeApp.setLineAttributes(wireframeLatt);

    //  Shaded:
    //    silver material
    Appearance shadedApp = new Appearance();

    Material shadedMat = new Material();
    shadedMat.setAmbientColor(0.30f, 0.30f, 0.30f);
    shadedMat.setDiffuseColor(0.30f, 0.30f, 0.50f);
    shadedMat.setSpecularColor(0.60f, 0.60f, 0.80f);
    shadedMat.setShininess(0.10f);
    shadedApp.setMaterial(shadedMat);

    ColoringAttributes shadedCatt = new ColoringAttributes();
    shadedCatt.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
    shadedApp.setColoringAttributes(shadedCatt);

    //
    //  Create a switch group to hold two versions of the
    //  shape: one wireframe, and one shaded
    //
    Transform3D tr = new Transform3D();
    tr.set(new Vector3f(-1.0f, 0.2f, 0.0f));
    TransformGroup gadget = new TransformGroup(tr);
    shadingSwitch = new Switch();
    shadingSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
    Group wireframe = new Group();
    Group shaded = new Group();
    shadingSwitch.addChild(wireframe);
    shadingSwitch.addChild(shaded);
    shadingSwitch.setWhichChild(1); // shaded
    gadget.addChild(shadingSwitch);

    //
    //  Build a gear (wireframe and shaded)
    //
    tr = new Transform3D();
    tr.rotY(Math.PI / 2.0);
    TransformGroup tg = new TransformGroup(tr);
    SpurGear gear = new SpurGearThinBody(24, // tooth count
            1.6f, // pitch circle radius
            0.3f, // shaft radius
            0.08f, // addendum
            0.05f, // dedendum
            0.3f, // gear thickness
            0.28f, // tooth tip thickness
            wireframeApp);// appearance
    tg.addChild(gear);
    wireframe.addChild(tg);

    tg = new TransformGroup(tr);
    gear = new SpurGearThinBody(24, // tooth count
            1.6f, // pitch circle radius
            0.3f, // shaft radius
            0.08f, // addendum
            0.05f, // dedendum
            0.3f, // gear thickness
            0.28f, // tooth tip thickness
            shadedApp); // appearance
    tg.addChild(gear);
    shaded.addChild(tg);

    //
    //  Build another gear (wireframe and shaded)
    //
    tr.rotY(Math.PI / 2.0);
    Vector3f trans = new Vector3f(-0.5f, 0.0f, 0.0f);
    tr.setTranslation(trans);
    tg = new TransformGroup(tr);
    gear = new SpurGearThinBody(30, // tooth count
            2.0f, // pitch circle radius
            0.3f, // shaft radius
            0.08f, // addendum
            0.05f, // dedendum
            0.3f, // gear thickness
            0.28f, // tooth tip thickness
            wireframeApp);// appearance
    tg.addChild(gear);
    wireframe.addChild(tg);

    tg = new TransformGroup(tr);
    gear = new SpurGearThinBody(30, // tooth count
            2.0f, // pitch circle radius
            0.3f, // shaft radius
            0.08f, // addendum
            0.05f, // dedendum
            0.3f, // gear thickness
            0.28f, // tooth tip thickness
            shadedApp); // appearance
    tg.addChild(gear);
    shaded.addChild(tg);

    //
    //  Build a cylindrical shaft (wireframe and shaded)
    //
    tr.rotZ(-Math.PI / 2.0);
    trans = new Vector3f(1.0f, 0.0f, 0.0f);
    tr.setTranslation(trans);
    tg = new TransformGroup(tr);
    Cylinder cyl = new Cylinder(0.3f, // radius
            4.0f, // length
            Primitive.GENERATE_NORMALS, // format
            16, // radial resolution
            1, // length-wise resolution
            wireframeApp);// appearance
    tg.addChild(cyl);
    wireframe.addChild(tg);

    tg = new TransformGroup(tr);
    cyl = new Cylinder(0.3f, // radius
            4.0f, // length
            Primitive.GENERATE_NORMALS, // format
            16, // radial resolution
            1, // length-wise resolution
            shadedApp); // appearance
    tg.addChild(cyl);
    shaded.addChild(tg);

    //
    //  Build shaft teeth (wireframe and shaded)
    //
    tr.rotY(Math.PI / 2.0);
    trans = new Vector3f(2.05f, 0.0f, 0.0f);
    tr.setTranslation(trans);
    tg = new TransformGroup(tr);
    gear = new SpurGear(12, // tooth count
            0.5f, // pitch circle radius
            0.3f, // shaft radius
            0.05f, // addendum
            0.05f, // dedendum
            1.5f, // gear thickness
            0.8f, // tooth tip thickness
            wireframeApp);// appearance
    tg.addChild(gear);
    wireframe.addChild(tg);

    tg = new TransformGroup(tr);
    gear = new SpurGear(12, // tooth count
            0.5f, // pitch circle radius
            0.3f, // shaft radius
            0.05f, // addendum
            0.05f, // dedendum
            1.5f, // gear thickness
            0.8f, // tooth tip thickness
            shadedApp); // appearance
    tg.addChild(gear);
    shaded.addChild(tg);

    return gadget;
}

From source file:ExHenge.java

public Group buildScene() {
    // Turn off the example headlight
    setHeadlightEnable(false);/*from   w  w  w .jav a2 s. c o m*/

    // Default to walk navigation
    setNavigationType(Walk);

    //
    // Preload the texture images
    //
    if (debug)
        System.err.println("  textures...");
    Texture groundTex = null;
    Texture spurTex = null;
    Texture domeTex = null;
    TextureLoader texLoader = null;
    ImageComponent image = null;

    texLoader = new TextureLoader("mud01.jpg", this);
    image = texLoader.getImage();
    if (image == null)
        System.err.println("Cannot load mud01.jpg texture");
    else {
        groundTex = texLoader.getTexture();
        groundTex.setBoundaryModeS(Texture.WRAP);
        groundTex.setBoundaryModeT(Texture.WRAP);
        groundTex.setMinFilter(Texture.NICEST);
        groundTex.setMagFilter(Texture.NICEST);
        groundTex.setMipMapMode(Texture.BASE_LEVEL);
        groundTex.setEnable(true);
    }

    texLoader = new TextureLoader("stonebrk2.jpg", this);
    image = texLoader.getImage();
    if (image == null)
        System.err.println("Cannot load stonebrk2.jpg texture");
    else {
        spurTex = texLoader.getTexture();
        spurTex.setBoundaryModeS(Texture.WRAP);
        spurTex.setBoundaryModeT(Texture.WRAP);
        spurTex.setMinFilter(Texture.NICEST);
        spurTex.setMagFilter(Texture.NICEST);
        spurTex.setMipMapMode(Texture.BASE_LEVEL);
        spurTex.setEnable(true);
    }

    texLoader = new TextureLoader("fire.jpg", this);
    image = texLoader.getImage();
    if (image == null)
        System.err.println("Cannot load fire.jpg texture");
    else {
        domeTex = texLoader.getTexture();
        domeTex.setBoundaryModeS(Texture.WRAP);
        domeTex.setBoundaryModeT(Texture.WRAP);
        domeTex.setMinFilter(Texture.NICEST);
        domeTex.setMagFilter(Texture.NICEST);
        domeTex.setMipMapMode(Texture.BASE_LEVEL);
        domeTex.setEnable(true);
    }

    //
    // Build some shapes we'll need
    //
    if (debug)
        System.err.println("  flying buttresses...");

    // Build three types of spurs (flying buttresses)
    Appearance spurApp = new Appearance();

    Material spurMat = new Material();
    spurMat.setAmbientColor(0.6f, 0.6f, 0.6f);
    spurMat.setDiffuseColor(1.0f, 1.0f, 1.0f);
    spurMat.setSpecularColor(0.0f, 0.0f, 0.0f);
    spurApp.setMaterial(spurMat);

    Transform3D tr = new Transform3D();
    tr.setIdentity();
    tr.setScale(new Vector3d(1.0, 4.0, 1.0));

    TextureAttributes spurTexAtt = new TextureAttributes();
    spurTexAtt.setTextureMode(TextureAttributes.MODULATE);
    spurTexAtt.setPerspectiveCorrectionMode(TextureAttributes.NICEST);
    spurTexAtt.setTextureTransform(tr);
    spurApp.setTextureAttributes(spurTexAtt);

    if (spurTex != null)
        spurApp.setTexture(spurTex);

    Arch spur1 = new Arch(0.0, // start Phi
            1.571, // end Phi
            9, // nPhi
            -0.0982, // start Theta
            0.0982, // end Theta (11.25 degrees)
            2, // nTheta
            2.5, // start radius
            1.0, // end radius
            0.05, // start phi thickness
            0.025, // end phi thickness
            spurApp); // appearance

    Arch spur2 = new Arch(0.0, // start Phi
            1.571, // end Phi
            9, // nPhi
            -0.0982, // start Theta
            0.0982, // end Theta (11.25 degrees)
            2, // nTheta
            1.5, // start radius
            2.0, // end radius
            0.05, // start phi thickness
            0.025, // end phi thickness
            spurApp); // appearance

    Arch spur3 = new Arch(0.0, // start Phi
            1.571, // end Phi
            9, // nPhi
            -0.0982, // start Theta
            0.0982, // end Theta (11.25 degrees)
            2, // nTheta
            1.5, // start radius
            1.0, // end radius
            0.05, // start phi thickness
            0.025, // end phi thickness
            spurApp); // appearance

    Arch spur4 = new Arch(0.0, // start Phi
            1.178, // end Phi
            9, // nPhi
            -0.0982, // start Theta
            0.0982, // end Theta (11.25 degrees)
            2, // nTheta
            4.0, // start radius
            4.0, // end radius
            0.05, // start phi thickness
            0.025, // end phi thickness
            spurApp); // appearance

    // Put each spur into a shared group so we can instance
    // the spurs multiple times
    SharedGroup spur1Group = new SharedGroup();
    spur1Group.addChild(spur1);
    spur1Group.compile();

    SharedGroup spur2Group = new SharedGroup();
    spur2Group.addChild(spur2);
    spur2Group.compile();

    SharedGroup spur3Group = new SharedGroup();
    spur3Group.addChild(spur3);
    spur3Group.compile();

    SharedGroup spur4Group = new SharedGroup();
    spur4Group.addChild(spur4);
    spur4Group.compile();

    // Build a central dome
    if (debug)
        System.err.println("  central dome...");

    Appearance domeApp = new Appearance();
    // No material needed - we want the dome to glow,
    // so use a REPLACE mode texture only
    TextureAttributes domeTexAtt = new TextureAttributes();
    domeTexAtt.setTextureMode(TextureAttributes.REPLACE);
    domeTexAtt.setPerspectiveCorrectionMode(TextureAttributes.NICEST);
    domeApp.setTextureAttributes(domeTexAtt);

    if (domeTex != null)
        domeApp.setTexture(domeTex);

    Arch dome = new Arch(0.0, // start Phi
            1.571, // end Phi
            5, // nPhi
            0.0, // start Theta
            2.0 * Math.PI, // end Theta (360 degrees)
            17, // nTheta
            1.0, // start radius
            1.0, // end radius
            0.0, // start phi thickness
            0.0, // end phi thickness
            domeApp); // appearance

    // Build the ground. Use a trick to get better lighting
    // effects by using an elevation grid. The idea is this:
    // for interactive graphics systems, such as those
    // controlled by Java3D, lighting effects are computed only
    // at triangle vertexes. Imagine a big rectangular ground
    // underneath a PointLight (added below). If the
    // PointLight is above the center of the square, in the real
    // world we'd expect a bright spot below it, fading to
    // darkness at the edges of the square. Not so in
    // interactive graphics. Since lighting is only computed
    // at vertexes, and the square's vertexes are each
    // equidistant from a centered PointLight, all four square
    // coordinates get the same brightness. That brightness
    // is interpolated across the square, giving a *constant*
    // brightness for the entire square! There is no bright
    // spot under the PointLight. So, here's the trick: use
    // more triangles. Pretty simple. Split the ground under
    // the PointLight into a grid of smaller squares. Each
    // smaller square is shaded using light brightness computed
    // at the square's vertexes. Squares directly under the
    // PointLight get brighter lighting at their vertexes, and
    // thus they are bright. This gives the desired bright
    // spot under the PointLight. The more squares we use
    // (a denser grid), the more accurate the bright spot and
    // the smoother the lighting gradation from bright directly
    // under the PointLight, to dark at the distant edges. Of
    // course, with more squares, we also get more polygons to
    // draw and a performance slow-down. So there is a
    // tradeoff between lighting quality and drawing speed.
    // For this example, we'll use a coarse mesh of triangles
    // created using an ElevationGrid shape.
    if (debug)
        System.err.println("  ground...");

    Appearance groundApp = new Appearance();

    Material groundMat = new Material();
    groundMat.setAmbientColor(0.3f, 0.3f, 0.3f);
    groundMat.setDiffuseColor(0.7f, 0.7f, 0.7f);
    groundMat.setSpecularColor(0.0f, 0.0f, 0.0f);
    groundApp.setMaterial(groundMat);

    tr = new Transform3D();
    tr.setScale(new Vector3d(8.0, 8.0, 1.0));

    TextureAttributes groundTexAtt = new TextureAttributes();
    groundTexAtt.setTextureMode(TextureAttributes.MODULATE);
    groundTexAtt.setPerspectiveCorrectionMode(TextureAttributes.NICEST);
    groundTexAtt.setTextureTransform(tr);
    groundApp.setTextureAttributes(groundTexAtt);

    if (groundTex != null)
        groundApp.setTexture(groundTex);

    ElevationGrid ground = new ElevationGrid(11, // X dimension
            11, // Z dimension
            2.0f, // X spacing
            2.0f, // Z spacing
            // Automatically use zero heights
            groundApp); // Appearance

    //
    // Build the scene using the shapes above. Place everything
    // withing a TransformGroup.
    //
    // Build the scene root
    TransformGroup scene = new TransformGroup();
    tr = new Transform3D();
    tr.setTranslation(new Vector3f(0.0f, -1.6f, 0.0f));
    scene.setTransform(tr);

    // Create influencing bounds
    BoundingSphere worldBounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), // Center
            1000.0); // Extent

    // General Ambient light
    ambient = new AmbientLight();
    ambient.setEnable(ambientOnOff);
    ambient.setColor(new Color3f(0.3f, 0.3f, 0.3f));
    ambient.setCapability(AmbientLight.ALLOW_STATE_WRITE);
    ambient.setInfluencingBounds(worldBounds);
    scene.addChild(ambient);

    // Bright Ambient light
    brightAmbient = new AmbientLight();
    brightAmbient.setEnable(brightAmbientOnOff);
    brightAmbient.setColor(new Color3f(1.0f, 1.0f, 1.0f));
    brightAmbient.setCapability(AmbientLight.ALLOW_STATE_WRITE);
    brightAmbient.setInfluencingBounds(worldBounds);
    scene.addChild(brightAmbient);

    // Red directional light
    redDirectional = new DirectionalLight();
    redDirectional.setEnable(redDirectionalOnOff);
    redDirectional.setColor(new Color3f(1.0f, 0.0f, 0.0f));
    redDirectional.setDirection(new Vector3f(1.0f, -0.5f, -0.5f));
    redDirectional.setCapability(AmbientLight.ALLOW_STATE_WRITE);
    redDirectional.setInfluencingBounds(worldBounds);
    scene.addChild(redDirectional);

    // Yellow directional light
    yellowDirectional = new DirectionalLight();
    yellowDirectional.setEnable(yellowDirectionalOnOff);
    yellowDirectional.setColor(new Color3f(1.0f, 0.8f, 0.0f));
    yellowDirectional.setDirection(new Vector3f(-1.0f, 0.5f, 1.0f));
    yellowDirectional.setCapability(AmbientLight.ALLOW_STATE_WRITE);
    yellowDirectional.setInfluencingBounds(worldBounds);
    scene.addChild(yellowDirectional);

    // Orange point light
    orangePoint = new PointLight();
    orangePoint.setEnable(orangePointOnOff);
    orangePoint.setColor(new Color3f(1.0f, 0.5f, 0.0f));
    orangePoint.setPosition(new Point3f(0.0f, 0.5f, 0.0f));
    orangePoint.setCapability(AmbientLight.ALLOW_STATE_WRITE);
    orangePoint.setInfluencingBounds(worldBounds);
    scene.addChild(orangePoint);

    // Ground
    scene.addChild(ground);

    // Dome
    scene.addChild(dome);

    // Spur 1's
    Group g = buildRing(spur1Group);
    scene.addChild(g);

    // Spur 2's
    TransformGroup tg = new TransformGroup();
    tr = new Transform3D();
    tr.rotY(0.3927);
    tg.setTransform(tr);
    g = buildRing(spur2Group);
    tg.addChild(g);
    scene.addChild(tg);

    // Spur 3's
    g = buildRing(spur3Group);
    scene.addChild(g);

    // Spur 4's
    tg = new TransformGroup();
    tg.setTransform(tr);
    g = buildRing(spur4Group);
    tg.addChild(g);
    scene.addChild(tg);

    return scene;
}