A Simple Wedge Program



/**
 *  This program demonstrate a very simple way to use the Wedge API : Tiwi
 */

import javax.media.j3d.*;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Cylinder;
import javax.vecmath.*;
import java.awt.*;


import escience.tiwi.*;
import escience.util.virtracker.*;
import escience.util.controls.KeyControls;


public class SimpleWedge  {


        /**     In order to move a virtual head in front of the screen if you are not 
using the wedge
        real Head Tracker       */
        private Virtracker      vt;
        private Wedge           wedge;
;

        /**   the configuration class  */
        public SimpleWedge() {

                // setup configuration 1 : ask for what you would like
                WedgeConfigTemplate template = new WedgeConfigTemplate();

                template.setStereo(WedgeConfigTemplate.PREFERRED);
                template.setNumWalls(2);
                template.setHeadTracking(WedgeConfigTemplate.PREFERRED);
                template.setVirTracking(WedgeConfigTemplate.REQUIRED);
                template.setDisplayFrameRate(WedgeConfigTemplate.PREFERRED);

                // set up configuration 2 : Here is what you could get
                WedgeConfiguration config = new WedgeConfiguration(template);

                // Create our own wedge for the view with a class method
                // there should be only one !
                wedge = Wedge.getWedge(config);

                // Head Virtual Tracker
                vt = wedge.getVT();
                if (vt == null) {
                        System.out.println("Error: no Virtracker device");
                }

                Canvas3D leftCanvas = wedge.getCanvas(wedge.LEFT_WALL);
                if (leftCanvas != null)
                        leftCanvas.addKeyListener( new KeyHandler(vt) );
                else
                        System.out.println("Error: should have at least one canvas");
                Canvas3D rightCanvas = wedge.getCanvas(wedge.RIGHT_WALL);
                if (rightCanvas != null)
                        rightCanvas.addKeyListener( new KeyHandler(vt) );


                // Content creation
                IterText points = new IterText();

                // create an arbitrary application scene graph and view branch
                // to place the viewPlatform

                BranchGroup scene = points.createSceneGraph();

                // add a content Branch to your wedge object
                wedge.addBranchGraph(scene);

        }

        public static void main(String[] args) {

                SimpleWedge simple = new SimpleWedge();
        }
}


/**
 * This class contains a method to create a scenegraph of points in
 * virtual space.  Points one meter apart are red spheres, and intermediate
 * points are yellow. SharedGroups and links are used to minimise the number
 * of objects in the scene graph.
 */
 class IterText {

    private static final int numX = 5;
    private static final int numY = 3;
    private static final int numZ = 5;
    private static final int offsetX = -2;
    private static final int offsetY = 0;
    private static final int offsetZ = -2;

    private String fontName = "TestFont";
    private double tessellation = 0.0;

    private Color3f red       = new Color3f(1.0f, 0.0f, 0.0f);
    private Color3f green     = new Color3f(0.0f, 1.0f, 0.0f);
    private Color3f blue      = new Color3f(0.0f, 0.0f, 1.0f);
    private Color3f yellow    = new Color3f(1.0f, 1.0f, 0.0f);
    private Color3f black     = new Color3f(0.0f, 0.0f, 0.0f);
    private Color3f white     = new Color3f(1.0f, 1.0f, 1.0f);
    private Color3f lColor2   = new Color3f(0.0f, 1.0f, 0.0f);
    private Color3f alColor   = new Color3f(0.2f, 0.2f, 0.2f);
    private Color3f bgColor  = new Color3f(0.05f, 0.05f, 0.2f);

    private Shape3D display = null;
    private Font3D f3d = new Font3D(new Font(fontName, Font.PLAIN, 2),
                            new FontExtrusion());

    public IterText() {};

    /**
     * This method creates the scene graph as described above.
     */
    public BranchGroup createSceneGraph() {

        int posX, posY, posZ;

        Appearance whiteA = new Appearance();
        Material whiteM = new Material();
        whiteM.setLightingEnable(true);
        whiteM.setEmissiveColor(white);
        whiteA.setMaterial(whiteM);

        Appearance redA = new Appearance();
        Material redM = new Material();
        redM.setLightingEnable(true);
        redM.setEmissiveColor(red);
        redA.setMaterial(redM);

        Appearance yellowA = new Appearance();
        Material yellowM = new Material();
        yellowM.setLightingEnable(true);
        yellowM.setEmissiveColor(yellow);
        yellowA.setMaterial(yellowM);


        // objects for one meter coordinates
        TransformGroup[][][] tg = new TransformGroup[numX][numY][numZ];
        Transform3D[][][] t3d = new Transform3D[numX][numY][numZ];
        Link[][][] link = new Link[numX][numY][numZ];
        Sphere redSp = new Sphere(0.5f, Sphere.GENERATE_NORMALS, 10, redA);
        Shape3D[][][] sh = new Shape3D[numX][numY][numZ];

        // objects for intermediate coodinates
        TransformGroup[][][] itgy = new TransformGroup[numX][numY][numZ];
        Transform3D[][][] it3dy = new Transform3D[numX][numY][numZ];
        Link[][][] iLinky = new Link[numX][numY][numZ];
        TransformGroup[][][] itgz = new TransformGroup[numX][numY][numZ];
        Transform3D[][][] it3dz = new Transform3D[numX][numY][numZ];
        Link[][][] iLinkz = new Link[numX][numY][numZ];
        Sphere yellowSp = new Sphere(0.5f, Sphere.GENERATE_NORMALS, 10, yellowA);

        // Shared Group Nodes
        SharedGroup redSG = new SharedGroup();
        redSG.addChild(redSp);
        redSG.compile();
        SharedGroup yellowSG = new SharedGroup();
        yellowSG.addChild(yellowSp);
        yellowSG.compile();

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

        objRoot.setCapability(objRoot.ALLOW_CHILDREN_WRITE);
        // 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.

        // draw cylinders for xyz axis
        // first y axis
        TransformGroup yAxisTG = new TransformGroup();
        Transform3D atY = new Transform3D();
        atY.setTranslation(new Vector3d(0.0, 0.0, 0.0));
        yAxisTG.setTransform(atY);
        yAxisTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRoot.addChild(yAxisTG);

        Material axisMatY = new Material(black, green, black, black, 100.0f);
        Appearance axisAppY = new Appearance();
        axisMatY.setLightingEnable(true);
        axisAppY.setMaterial(axisMatY);
        Cylinder yAxis = new Cylinder(0.01f, 5.0f, Cylinder.GENERATE_NORMALS, 
axisAppY);
        yAxisTG.addChild(yAxis);
        // then x Axis
        TransformGroup xAxisTG = new TransformGroup();
        Transform3D atX = new Transform3D();
        atX.setTranslation(new Vector3d(0.0, 0.0, 0.0));
        atX.rotZ(Math.toRadians(90));
        xAxisTG.setTransform(atX);
        xAxisTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRoot.addChild(xAxisTG);

        Material axisMatX = new Material(black, red, black, black, 100.0f);
        Appearance axisAppX = new Appearance();
        axisMatX.setLightingEnable(true);
        axisAppX.setMaterial(axisMatX);
        Cylinder xAxis = new Cylinder(0.01f, 5.0f, Cylinder.GENERATE_NORMALS, 
axisAppX);
        xAxisTG.addChild(xAxis);
        // then z axis
        TransformGroup zAxisTG = new TransformGroup();
        Transform3D atZ = new Transform3D();
        atZ.setTranslation(new Vector3d(0.0, 0.0, 0.0));
        atZ.rotX(Math.toRadians(90));
        zAxisTG.setTransform(atZ);
        zAxisTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRoot.addChild(zAxisTG);

        Material axisMatZ = new Material(black, blue, black, black, 100.0f);
        Appearance axisAppZ = new Appearance();
        axisMatZ.setLightingEnable(true);
        axisAppZ.setMaterial(axisMatZ);
        Cylinder zAxis = new Cylinder(0.01f, 5.0f, Cylinder.GENERATE_NORMALS, 
axisAppZ);
        zAxisTG.addChild(zAxis);

        for (int x = 0; x < numX; x++) {
            for (int y = 0; y < numY; y++) {
                for (int z = 0; z < numZ; z++) {
                    posX = x + offsetX;
                    posY = y + offsetY;
                    posZ = z + offsetZ;

                    // place one meter coordinates, with text
                    tg[x][y][z] = new TransformGroup();
                    t3d[x][y][z] = new Transform3D();
                    t3d[x][y][z].setTranslation(new Vector3d(posX, posY, posZ));
                    t3d[x][y][z].setScale(0.04);
                    tg[x][y][z].setTransform(t3d[x][y][z]);
                    tg[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
                    link[x][y][z] = new Link(redSG);
                    objRoot.addChild(tg[x][y][z]);

                    String str = new String("(" + posX + ", " + posY + ", " + posZ + ")");
                    Text3D txt = new Text3D(f3d, str,
                                            new Point3f(0.001f, 0.0f, 0.0f));
                    sh[x][y][z] = new Shape3D();
                    sh[x][y][z].setAppearance(whiteA);
                    sh[x][y][z].setGeometry(txt);

                    tg[x][y][z].addChild(sh[x][y][z]);
                    tg[x][y][z].addChild(link[x][y][z]);

                    // now do intermediates
                    // first posY + a half meter
                    itgy[x][y][z] = new TransformGroup();
                    it3dy[x][y][z] = new Transform3D();
                    it3dy[x][y][z].setTranslation(new Vector3d(posX, posY + 0.5, posZ));
                    it3dy[x][y][z].setScale(0.02);
                    itgy[x][y][z].setTransform(it3dy[x][y][z]);
                    itgy[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
                    iLinky[x][y][z] = new Link(yellowSG);
                    objRoot.addChild(itgy[x][y][z]);

                    itgy[x][y][z].addChild(iLinky[x][y][z]);

                    // then posZ + a half meter
                    itgz[x][y][z] = new TransformGroup();
                    it3dz[x][y][z] = new Transform3D();
                    it3dz[x][y][z].setTranslation(new Vector3d(posX, posY, posZ + 0.5));
                    it3dz[x][y][z].setScale(0.02);
                    itgz[x][y][z].setTransform(it3dz[x][y][z]);
                    itgz[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
                    iLinkz[x][y][z] = new Link(yellowSG);
                    objRoot.addChild(itgz[x][y][z]);

                    //ispz[x][y][z] = new Sphere(0.5f, Sphere.GENERATE_NORMALS, 10, 
ia[x][y][z]);
                    itgz[x][y][z].addChild(iLinkz[x][y][z]);

                }
            }
        }


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

        return objRoot;
    }
}