Example usage for javax.media.j3d Switch ALLOW_SWITCH_WRITE

List of usage examples for javax.media.j3d Switch ALLOW_SWITCH_WRITE

Introduction

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

Prototype

int ALLOW_SWITCH_WRITE

To view the source code for javax.media.j3d Switch ALLOW_SWITCH_WRITE.

Click Source Link

Document

Specifies that this node allows writing its child selection and mask values.

Usage

From source file:SwitchTest.java

protected BranchGroup createSceneBranchGroup() {
    BranchGroup objRoot = super.createSceneBranchGroup();

    double labelScale = 20;

    // flip this boolean to either display all
    // the child nodes or to just display the 3, 6 and 7th.
    final boolean bDisplayAll = false;

    // create the Switch Node
    int nMode = Switch.CHILD_ALL;

    if (bDisplayAll == false)
        nMode = Switch.CHILD_MASK;/*from   www.  ja va  2s  .c om*/

    Switch switchGroup = new Switch(nMode);
    switchGroup.setCapability(Switch.ALLOW_SWITCH_WRITE);

    switchGroup.addChild(createLabel("Child Node 1", labelScale));
    switchGroup.addChild(createLabel("Child Node 2", labelScale));
    switchGroup.addChild(createLabel("Child Node 3", labelScale));
    switchGroup.addChild(createLabel("Child Node 4", labelScale));
    switchGroup.addChild(createLabel("Child Node 5", labelScale));
    switchGroup.addChild(createLabel("Child Node 6", labelScale));
    switchGroup.addChild(createLabel("Child Node 7", labelScale));

    if (bDisplayAll == false) {
        java.util.BitSet visibleNodes = new java.util.BitSet(switchGroup.numChildren());

        // make the third, sixth and seventh nodes visible
        visibleNodes.set(2);
        visibleNodes.set(5);
        visibleNodes.set(6);

        switchGroup.setChildMask(visibleNodes);
    }

    // finally add the Switch Node
    objRoot.addChild(switchGroup);

    return objRoot;
}

From source file:LOD.java

public BranchGroup createSceneGraph() {
    // Create the root of the branch graph
    BranchGroup objRoot = new BranchGroup();

    createLights(objRoot);/*from w w  w . j a  v  a 2  s . c  o  m*/

    // 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);
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    objRoot.addChild(objTrans);

    // Create a switch to hold the different levels of detail
    Switch sw = new Switch(0);
    sw.setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_READ);
    sw.setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_WRITE);

    // Create several levels for the switch, with less detailed
    // spheres for the ones which will be used when the sphere is
    // further away
    sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 40));
    sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 20));
    sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 10));
    sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 3));

    // Add the switch to the main group
    objTrans.addChild(sw);

    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);

    // set up the DistanceLOD behavior
    float[] distances = new float[3];
    distances[0] = 5.0f;
    distances[1] = 10.0f;
    distances[2] = 25.0f;
    DistanceLOD lod = new DistanceLOD(distances);
    lod.addSwitch(sw);
    lod.setSchedulingBounds(bounds);
    objTrans.addChild(lod);

    // Have Java 3D perform optimizations on this scene graph.
    objRoot.compile();

    return objRoot;
}

From source file:PointTest.java

protected BranchGroup createSceneBranchGroup() {
    BranchGroup objRoot = super.createSceneBranchGroup();

    TransformGroup objTrans = new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    Transform3D yAxis = new Transform3D();
    Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 14000, 0, 0, 0, 0, 0);

    RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, objTrans, yAxis, 0.0f,
            (float) Math.PI * 2.0f);
    rotator.setSchedulingBounds(getApplicationBounds());
    objTrans.addChild(rotator);//from  ww w. j av a2s .  c  om

    Switch switchGroup = new Switch();
    switchGroup.setCapability(Switch.ALLOW_SWITCH_WRITE);

    switchGroup.addChild(createPoints(1, 5, false));
    switchGroup.addChild(createPoints(1, 5, true));
    switchGroup.addChild(createPoints(8, 10, false));
    switchGroup.addChild(createPoints(8, 10, true));

    switchGroup.addChild(createPoints(2, 5, false));
    switchGroup.addChild(createPoints(2, 5, true));
    switchGroup.addChild(createPoints(2, 20, false));
    switchGroup.addChild(createPoints(2, 20, true));

    // create a SwitchValueInterpolator to
    // cycle through the child nodes in the Switch Node
    Alpha switchAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 15000, 0, 0, 0, 0, 0);

    SwitchValueInterpolator switchInterpolator = new SwitchValueInterpolator(switchAlpha, switchGroup);
    switchInterpolator.setSchedulingBounds(getApplicationBounds());
    switchInterpolator.setEnable(true);

    // WARNING: do not add the SwitchValueInterpolator to the Switch Node!
    objRoot.addChild(switchInterpolator);

    objTrans.addChild(switchGroup);
    objRoot.addChild(objTrans);

    return objRoot;
}

From source file:ExTransform.java

public Group buildScene() {
    // Turn on the headlight
    setHeadlightEnable(true);//ww w .  j  a v  a2s  .  c  o m

    // Build the scene root
    switchGroup = new Switch();
    switchGroup.setCapability(Switch.ALLOW_SWITCH_WRITE);

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

    Transform3D t3d;

    Appearance app = new Appearance();
    Material mat = new Material();
    mat.setAmbientColor(0.2f, 0.8f, 0.4f);
    mat.setDiffuseColor(0.2f, 0.8f, 0.4f);
    mat.setSpecularColor(0.0f, 0.0f, 0.f);
    app.setMaterial(mat);

    // Build the 3D object:
    Box box = new Box(3.0f, 2.0f, 1.0f, app);

    // Build the shared object:
    sharedObject = new SharedGroup();
    sharedObject.addChild(box);

    // Build 4 separate transforms:

    Transform3D id = new Transform3D();
    TransformGroup idGroup = new TransformGroup(id);
    idGroup.addChild(new Link(sharedObject));
    switchGroup.addChild(idGroup);

    Transform3D rot = new Transform3D();
    rot.set(new AxisAngle4d(0., 1., 0., Math.PI / 4.));
    TransformGroup rotGroup = new TransformGroup(rot);
    rotGroup.addChild(new Link(sharedObject));
    switchGroup.addChild(rotGroup);

    Transform3D trans = new Transform3D();
    trans.set(new Vector3d(2., 0., 0.));
    TransformGroup transGroup = new TransformGroup(trans);
    transGroup.addChild(new Link(sharedObject));
    switchGroup.addChild(transGroup);

    Transform3D scale = new Transform3D();
    scale.set(2.0);
    TransformGroup scaleGroup = new TransformGroup(scale);
    scaleGroup.addChild(new Link(sharedObject));
    switchGroup.addChild(scaleGroup);

    switchGroup.setWhichChild(options[currentSwitch].child);

    return switchGroup;
}

From source file:NodesTest.java

protected BranchGroup createSceneBranchGroup() {
    BranchGroup objRoot = super.createSceneBranchGroup();

    double labelScale = 20;

    // create the top level Switch Node
    // we will use the Switch Node to switch the
    // other Nodes on and off.
    // 1: Switch// w w w.ja va 2  s .c o m
    Switch switchGroup = new Switch();
    switchGroup.setCapability(Switch.ALLOW_SWITCH_WRITE);
    switchGroup.addChild(createLabel("1. Switch Label", labelScale));

    // 2: BranchGroup
    BranchGroup branchGroup = new BranchGroup();
    branchGroup.addChild(createLabel("2. BranchGroup", labelScale));
    switchGroup.addChild(branchGroup);

    // 3: OrderedGroup,
    OrderedGroup orderedGroup = new OrderedGroup();
    orderedGroup.addChild(createLabel("3. OrderedGroup", labelScale));
    orderedGroup.addChild(createLabel("Child 1", labelScale));
    orderedGroup.addChild(createLabel("Child 2", labelScale));
    switchGroup.addChild(orderedGroup);

    // 4: SharedGroup,
    SharedGroup sharedGroup1 = new SharedGroup();
    sharedGroup1.addChild(createLabel("4. Shared Group 1", labelScale));
    switchGroup.addChild(new Link(sharedGroup1));

    // 5: Primitive,
    BranchGroup primitiveGroup = new BranchGroup();
    primitiveGroup.addChild(createLabel("5. Primitive", labelScale));
    primitiveGroup.addChild(new Sphere(2));
    switchGroup.addChild(primitiveGroup);

    // 6: TransformGroup
    TransformGroup transformGroup = new TransformGroup();
    transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    Transform3D yAxis = new Transform3D();
    Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 4000, 0, 0, 0, 0, 0);

    RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, transformGroup, yAxis, 0.0f,
            (float) Math.PI * 2.0f);
    rotator.setSchedulingBounds(createApplicationBounds());
    transformGroup.addChild(rotator);

    transformGroup.addChild(new ColorCube(2));
    transformGroup.addChild(createLabel("6. TransformGroup", labelScale));
    switchGroup.addChild(transformGroup);

    // 7: add another copy of the shared group
    switchGroup.addChild(new Link(sharedGroup1));

    // create a SwitchValueInterpolator to
    // cycle through the child nodes in the Switch Node
    Alpha switchAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 10000, 0, 0, 0, 0, 0);

    SwitchValueInterpolator switchInterpolator = new SwitchValueInterpolator(switchAlpha, switchGroup);
    switchInterpolator.setSchedulingBounds(createApplicationBounds());
    switchInterpolator.setEnable(true);

    // WARNING: do not add the SwitchValueInterpolator to the Switch Node!
    objRoot.addChild(switchInterpolator);

    // finally add the Switch Node
    objRoot.addChild(switchGroup);

    return objRoot;
}

From source file:SimpleLOD.java

/**
 * Build the content branch for the scene graph This creates three
 * cylinders, each with a different resolution. These are then used with a
 * LOD node to implement a crude level of detail.
 * /*from  w w w . j  a va  2s.com*/
 * @return BranchGroup that is the root of the content
 */
protected BranchGroup buildContentBranch() {
    //Create the appearance
    Appearance app = new Appearance();
    Color3f ambientColour = new Color3f(1.0f, 1.0f, 0.0f);
    Color3f emissiveColour = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f specularColour = new Color3f(1.0f, 1.0f, 1.0f);
    Color3f diffuseColour = new Color3f(1.0f, 1.0f, 0.0f);
    float shininess = 20.0f;
    app.setMaterial(new Material(ambientColour, emissiveColour, diffuseColour, specularColour, shininess));
    //Make the switch node that is to used with the LOD
    //and make it writable
    Switch LODswitch = new Switch();
    LODswitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
    //Add the three cylinders
    LODswitch.addChild(new Cylinder(1.0f, 1.0f, Cylinder.GENERATE_NORMALS, 10, 10, app));
    LODswitch.addChild(new Cylinder(1.0f, 1.0f, Cylinder.GENERATE_NORMALS, 5, 5, app));
    LODswitch.addChild(new Cylinder(1.0f, 1.0f, Cylinder.GENERATE_NORMALS, 3, 3, app));
    //Define the distances for the LOD
    float[] LODdistances = { 5.0f, 10.0f, 15.0f };
    DistanceLOD myLOD = new DistanceLOD(LODdistances, new Point3f(0.0f, 0.0f, 0.0f));
    myLOD.setSchedulingBounds(bounds);
    //Add the switch to the LOD
    myLOD.addSwitch(LODswitch);
    BranchGroup contentBranch = new BranchGroup();
    contentBranch.addChild(myLOD);
    addLights(contentBranch);

    contentBranch.addChild(LODswitch);
    return contentBranch;

}

From source file:LightBug.java

void setupSpheres() {

    // create a Switch for the spheres, allow switch changes
    spheresSwitch = new Switch(Switch.CHILD_ALL);
    spheresSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);

    // Set up an appearance to make the Sphere with red ambient,
    // black emmissive, red diffuse and white specular coloring
    Material material = new Material(red, black, red, white, 64);
    Appearance appearance = new Appearance();
    appearance.setMaterial(material);/*from   w w  w .j a  v a2s  .  co m*/

    // create a sphere and put it into a shared group
    Sphere sphere = new Sphere(0.5f, appearance);
    SharedGroup sphereSG = new SharedGroup();
    sphereSG.addChild(sphere);

    // create a grid of spheres in the z=0 plane
    // each has a TransformGroup to position the sphere which contains
    // a link to the shared group for the sphere
    for (int y = -2; y <= 2; y++) {
        for (int x = -2; x <= 2; x++) {
            TransformGroup tg = new TransformGroup();
            tmpVector.set(x * 1.2f, y * 1.2f, 0.0f);
            tmpTrans.set(tmpVector);
            tg.setTransform(tmpTrans);
            tg.addChild(new Link(sphereSG));
            spheresSwitch.addChild(tg);
        }
    }
}

From source file:SoundBug.java

void setupSounds() {
    soundSwitch = new Switch(Switch.CHILD_NONE);
    soundSwitch.setWhichChild(Switch.CHILD_NONE);
    soundSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);

    // set up the BoundingSphere for all the sounds
    BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);

    // Set up the sound media container
    java.net.URL soundURL = null;
    String soundFile = "techno_machine.au";
    try {/*from w  w w.  j  a  v  a  2s  .c o  m*/
        java.net.URL codeBase = null;
        try {
            codeBase = getCodeBase();
        } catch (Exception ex) {
            // got an exception, probably running as an application,
            // keep code base null...
        }
        if (codeBase != null) {
            soundURL = new java.net.URL(codeBase.toString() + soundFile);
        }
    } catch (java.net.MalformedURLException ex) {
        System.out.println(ex.getMessage());
        System.exit(1);
    }
    if (soundURL == null) { // application, try file URL
        try {
            soundURL = new java.net.URL("file:./" + soundFile);
        } catch (java.net.MalformedURLException ex) {
            System.out.println(ex.getMessage());
            System.exit(1);
        }
    }
    System.out.println("soundURL = " + soundURL);
    MediaContainer soundMC = new MediaContainer(soundURL);

    // set up the Background Sound
    soundBackground = new BackgroundSound();
    soundBackground.setCapability(Sound.ALLOW_ENABLE_WRITE);
    soundBackground.setSoundData(soundMC);
    soundBackground.setSchedulingBounds(bounds);
    soundBackground.setEnable(true);
    soundBackground.setLoop(Sound.INFINITE_LOOPS);
    soundSwitch.addChild(soundBackground);

    // set up the point sound
    soundPoint = new PointSound();
    soundPoint.setCapability(Sound.ALLOW_ENABLE_WRITE);
    soundPoint.setSoundData(soundMC);
    soundPoint.setSchedulingBounds(bounds);
    soundPoint.setEnable(true);
    soundPoint.setLoop(Sound.INFINITE_LOOPS);
    soundPoint.setPosition(-5.0f, -5.0f, 0.0f);
    Point2f[] distGain = new Point2f[2];
    // set the attenuation to linearly decrease volume from max at
    // source to 0 at a distance of 5m
    distGain[0] = new Point2f(0.0f, 1.0f);
    distGain[1] = new Point2f(5.0f, 0.0f);
    soundPoint.setDistanceGain(distGain);
    soundSwitch.addChild(soundPoint);

}

From source file:InterpolatorTest.java

protected BranchGroup createSceneBranchGroup() {
    BranchGroup objRoot = super.createSceneBranchGroup();

    // create a root TG in case we need to scale the scene
    TransformGroup objTrans = new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    // create the Appearance for the Shape3D
    Appearance app = new Appearance();

    // create a Material, modified by the ColorInterpolator
    Color3f objColor = new Color3f(1.0f, 0.7f, 0.8f);
    Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
    Material mat = new Material(objColor, black, objColor, black, 80.0f);
    mat.setCapability(Material.ALLOW_COMPONENT_WRITE);
    app.setMaterial(mat);// ww  w .  jav a  2s  .  com

    // create a TransparencyAttributes, modified by the
    // TransparencyInterpolator
    TransparencyAttributes transparency = new TransparencyAttributes();
    transparency.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);
    transparency.setTransparencyMode(TransparencyAttributes.NICEST);
    app.setTransparencyAttributes(transparency);

    // create a Switch Node and set capabilities
    Switch switchNode = new Switch();
    switchNode.setCapability(Switch.ALLOW_SWITCH_WRITE);

    // create a Alpha object for the Interpolators
    Alpha alpha = new Alpha(-1, Alpha.INCREASING_ENABLE | Alpha.DECREASING_ENABLE, 500, 100, 5000, 2000, 1000,
            5000, 2000, 500);

    // add each BG and Interpolator as a child of the Switch Node
    TransformGroup tg = createSharedGroup(app);
    switchNode.addChild(createBranchGroup(tg, new ColorInterpolator(alpha, app.getMaterial())));

    tg = createSharedGroup(app);
    switchNode.addChild(createBranchGroup(tg, new PositionInterpolator(alpha, tg)));

    tg = createSharedGroup(app);
    switchNode.addChild(createBranchGroup(tg, new RotationInterpolator(alpha, tg)));

    tg = createSharedGroup(app);
    switchNode.addChild(createBranchGroup(tg, new ScaleInterpolator(alpha, tg)));

    tg = createSharedGroup(app);
    switchNode.addChild(createBranchGroup(tg,
            new TransparencyInterpolator(alpha, app.getTransparencyAttributes(), 0, 0.8f)));

    // define the data for the RotPosScalePathInterpolator
    float[] knots = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f, 0.8f, 0.9f, 1.0f };
    float[] scales = { 0.2f, 0.5f, 0.8f, 2.3f, 5.4f, 0.6f, 0.4f, 0.2f, 0.1f };
    Quat4f[] quats = new Quat4f[9];
    Point3f[] positions = new Point3f[9];

    quats[0] = new Quat4f(0.3f, 1.0f, 1.0f, 0.0f);
    quats[1] = new Quat4f(1.0f, 0.0f, 0.0f, 0.3f);
    quats[2] = new Quat4f(0.2f, 1.0f, 0.0f, 0.0f);
    quats[3] = new Quat4f(0.0f, 0.2f, 1.0f, 0.0f);
    quats[4] = new Quat4f(1.0f, 0.0f, 0.4f, 0.0f);
    quats[5] = new Quat4f(0.0f, 1.0f, 1.0f, 0.2f);
    quats[6] = new Quat4f(0.3f, 0.3f, 0.0f, 0.0f);
    quats[7] = new Quat4f(1.0f, 0.0f, 1.0f, 1.0f);
    quats[8] = quats[0];

    positions[0] = new Point3f(0.0f, 0.0f, -1.0f);
    positions[1] = new Point3f(1.0f, -2.0f, -2.0f);
    positions[2] = new Point3f(-2.0f, 2.0f, -3.0f);
    positions[3] = new Point3f(1.0f, 1.0f, -4.0f);
    positions[4] = new Point3f(-4.0f, -2.0f, -5.0f);
    positions[5] = new Point3f(2.0f, 0.3f, -6.0f);
    positions[6] = new Point3f(-4.0f, 0.5f, -7.0f);
    positions[7] = new Point3f(0.0f, -1.5f, -4.0f);
    positions[8] = positions[0];

    tg = createSharedGroup(app);

    // create the Interpolator
    RotPosScalePathInterpolator rotPosScalePathInterplator = new RotPosScalePathInterpolator(alpha, tg,
            new Transform3D(), knots, quats, positions, scales);

    // add a BG for the Interpolator
    switchNode.addChild(createBranchGroup(tg, rotPosScalePathInterplator));

    // create a RandomAlpha object to control a SwitchInterpolator
    // to set the Switches active child node randomly
    RandomAlpha randomAlpha = new RandomAlpha();

    // create the interpolator
    SwitchValueInterpolator switchInterpolator = new SwitchValueInterpolator(randomAlpha, switchNode);
    switchInterpolator.setSchedulingBounds(getApplicationBounds());

    // connect the scenegraph
    objTrans.addChild(switchNode);
    objTrans.addChild(switchInterpolator);

    // Set up the global lights
    Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
    Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
    Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);

    AmbientLight aLgt = new AmbientLight(alColor);
    aLgt.setInfluencingBounds(getApplicationBounds());
    DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
    lgt1.setInfluencingBounds(getApplicationBounds());

    // add the lights
    objRoot.addChild(aLgt);
    objRoot.addChild(lgt1);

    // connect
    objRoot.addChild(objTrans);

    return objRoot;
}

From source file:ExDepthCue.java

public Group buildScene() {
    // Get the current color
    Color3f color = (Color3f) colors[currentColor].value;

    // Turn off the example headlight
    setHeadlightEnable(false);/* w  ww. j  av a  2s. com*/

    // Create the scene group
    Group scene = new Group();

    // Create a switch group to hold the fog node. This enables
    // us to turn the fog node on and off via the GUI.
    fogSwitch = new Switch();
    fogSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);

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

    // Set the fog color, density, and its influencing bounds
    fog = new LinearFog();
    fog.setColor(color);
    // front and back distances set below
    fog.setCapability(Fog.ALLOW_COLOR_WRITE);
    fog.setCapability(Fog.ALLOW_INFLUENCING_BOUNDS_WRITE);
    fog.setInfluencingBounds(worldBounds);
    fogSwitch.addChild(fog);
    scene.addChild(fogSwitch);
    if (depthCueOnOff)
        fogSwitch.setWhichChild(0); // on
    else
        fogSwitch.setWhichChild(Switch.CHILD_NONE); // off

    // Set the background color and its application bounds
    //   Usually, the background color should match the fog color
    //   or the results look odd.
    background = new Background();
    background.setColor(color);
    background.setApplicationBounds(worldBounds);
    background.setCapability(Background.ALLOW_COLOR_WRITE);
    scene.addChild(background);

    // Build foreground geometry
    Group content = buildIsoline();
    scene.addChild(content);

    // Automatically compute good front and back distances for
    // fog to get good depth-cueing. To do this, first get the
    // dimensions of the bounds around the content. Then,
    // set the front distance to be at the center of the content
    // (or closer by a tad) and the back distance at the front
    // distance PLUS half the depth of the content's bounding box
    BoundingSphere sampleSphere = new BoundingSphere();
    BoundingBox sampleBox = new BoundingBox();
    Bounds bounds = content.getBounds();
    double deltaDistance = 0.0;
    double centerZ = 0.0;

    if (bounds == null) {
        // No bounds available. Estimate the values knowing
        // that the above content is what it is.
        centerZ = 0.5; // 0.5 closer than true center
        deltaDistance = 2.0;
    } else if (bounds.getClass() == sampleSphere.getClass()) {
        BoundingSphere sphereBounds = (BoundingSphere) bounds;
        deltaDistance = Math.abs(sphereBounds.getRadius());
        Point3d center = new Point3d();
        sphereBounds.getCenter(center);
        centerZ = center.z + 0.5; // 0.5 closer than true center
    } else if (bounds.getClass() == sampleBox.getClass()) {
        BoundingBox boxBounds = (BoundingBox) bounds;
        Point3d p1 = new Point3d();
        Point3d p2 = new Point3d();
        boxBounds.getLower(p1);
        boxBounds.getUpper(p2);
        deltaDistance = p2.z - p1.z;
        if (deltaDistance < 0.0)
            deltaDistance *= -1.0;
        if (p1.z > p2.z)
            centerZ = p1.z - deltaDistance / 2.0;
        else
            centerZ = p2.z - deltaDistance / 2.0;
        centerZ += 0.5; // 0.5 closer than true center
    } else {
        System.err.println("Unknown bounds type");
    }

    // Set front distance to the distance from the default
    // viewing position (0,0,10) to the center of the bounds.
    fog.setFrontDistance(10.0f - (float) centerZ);

    // Set back distance to the distance from the default
    // viewing position (0,0,10) to the back of the bounds.
    fog.setBackDistance(10.0f - (float) centerZ + (float) deltaDistance);

    return scene;
}