Janet Song wrote:

> i am hunting high and low for at least a good reference on veiwing...

and Mike Goldwater wrote:

> I am minded to write my own book.


        OK, OK!  I'm working hard to finish my book, and I know of
        at least two other books that are on the way too.  For now,
        here are some viewing classes and test programs that will
        be included as examples in my book.  None of these use any
        of the com.sun.j3d.utils (except for MainFrame). The source
        for each is attached:

          Box.java              simple box primitive
          PrimStarisBG          creates a spiral of boxes
          SimpleViewBG.java     basic view, base class too
          SpinViewBG.java       spins the scene as it's viewed
          TestViews.java        demonstrates use of viewing classes
          FourView.java         demonstrates multiple views of scene

        Just javac *.java and run either TestViews or FourView.
        You can change the kind of view created and their projections
        by uncommenting lines of code in either of these examples.

        If you have any questions, let me know.  Also, apologies in
        advance if the message strikes anyone as too large to post.
        I'm working on a web site that I'll eventually announce.
        Stay tuned for fillrate.com.

        By the way, if you do decide to write a book, get ready
        for some real fun.  It's more work than grad school!

--
Allen L. McPherson               Member Holstein Aerobatic Club
Los Alamos National Laboratory   Scientific Viz / Advanced Computing Lab
Box 1663 Group:CIC-ACL MS:B287   [EMAIL PROTECTED]
Los Alamos, NM   87545           Voice: (505) 665-6548  Fax: (505) 665-4939
[Personal mail to:               [EMAIL PROTECTED]]
//  Copyright (c) 2000 by Allen Lynn McPherson.  All rights reserved.
//  This example is provided WITHOUT ANY WARRANTY either expressed or implied.

import javax.media.j3d.*;
import javax.vecmath.*;


//  Creates a box of user specified size centered at the local
//  coordinate origin.  The box is made form independent quads
//  without vertex indexing.
public class  Box  extends Shape3D {
  float  x, y, z;

  //  Make a 2x unit cube if no size specified.
  public  Box() {
    this(1.0f, 1.0f, 1.0f);
  }

  public  Box(float x, float y, float z) {
    this.x = x;
    this.y = y;
    this.z = z;

    Point3f   coords[] = {
      //  Front and back faces.
      new Point3f(-x/2, -y/2,  z/2),
      new Point3f( x/2, -y/2,  z/2),
      new Point3f( x/2,  y/2,  z/2),
      new Point3f(-x/2,  y/2,  z/2),
      new Point3f(-x/2, -y/2, -z/2),
      new Point3f(-x/2,  y/2, -z/2),
      new Point3f( x/2,  y/2, -z/2),
      new Point3f( x/2, -y/2, -z/2),
      //  Bottom and top faces.
      new Point3f(-x/2, -y/2,  z/2),
      new Point3f(-x/2, -y/2, -z/2),
      new Point3f( x/2, -y/2, -z/2),
      new Point3f( x/2, -y/2,  z/2),
      new Point3f(-x/2,  y/2,  z/2),
      new Point3f( x/2,  y/2,  z/2),
      new Point3f( x/2,  y/2, -z/2),
      new Point3f(-x/2,  y/2, -z/2),
      //  Left and right faces.
      new Point3f(-x/2,  y/2,  z/2),
      new Point3f(-x/2,  y/2, -z/2),
      new Point3f(-x/2, -y/2, -z/2),
      new Point3f(-x/2, -y/2,  z/2),
      new Point3f( x/2, -y/2,  z/2),
      new Point3f( x/2, -y/2, -z/2),
      new Point3f( x/2,  y/2, -z/2),
      new Point3f( x/2,  y/2,  z/2)
    };
    Vector3f  norms[] = {
      new Vector3f( 0.0f,  0.0f,  1.0f),        //  Front
      new Vector3f( 0.0f,  0.0f,  1.0f),
      new Vector3f( 0.0f,  0.0f,  1.0f),
      new Vector3f( 0.0f,  0.0f,  1.0f),
      new Vector3f( 0.0f,  0.0f, -1.0f),        //  Back
      new Vector3f( 0.0f,  0.0f, -1.0f),
      new Vector3f( 0.0f,  0.0f, -1.0f),
      new Vector3f( 0.0f,  0.0f, -1.0f),
      new Vector3f( 0.0f, -1.0f,  0.0f),        //  Bottom
      new Vector3f( 0.0f, -1.0f,  0.0f),
      new Vector3f( 0.0f, -1.0f,  0.0f),
      new Vector3f( 0.0f, -1.0f,  0.0f),
      new Vector3f( 0.0f,  1.0f,  0.0f),        //  Top
      new Vector3f( 0.0f,  1.0f,  0.0f),
      new Vector3f( 0.0f,  1.0f,  0.0f),
      new Vector3f( 0.0f,  1.0f,  0.0f),
      new Vector3f(-1.0f,  0.0f,  0.0f),        //  Left
      new Vector3f(-1.0f,  0.0f,  0.0f),
      new Vector3f(-1.0f,  0.0f,  0.0f),
      new Vector3f(-1.0f,  0.0f,  0.0f),
      new Vector3f( 1.0f,  0.0f,  0.0f),        //  Right
      new Vector3f( 1.0f,  0.0f,  0.0f),
      new Vector3f( 1.0f,  0.0f,  0.0f),
      new Vector3f( 1.0f,  0.0f,  0.0f)
    };
    Color3f  colors[] = {
      new Color3f( 0.0f,  0.0f,  1.0f), //  Front
      new Color3f( 0.0f,  0.0f,  1.0f),
      new Color3f( 0.0f,  0.0f,  1.0f),
      new Color3f( 0.0f,  0.0f,  1.0f),
      new Color3f( 0.0f,  0.0f,  0.5f), //  Back
      new Color3f( 0.0f,  0.0f,  0.5f),
      new Color3f( 0.0f,  0.0f,  0.5f),
      new Color3f( 0.0f,  0.0f,  0.5f),
      new Color3f( 0.0f,  1.0f,  0.0f), //  Bottom
      new Color3f( 0.0f,  1.0f,  0.0f),
      new Color3f( 0.0f,  1.0f,  0.0f),
      new Color3f( 0.0f,  1.0f,  0.0f),
      new Color3f( 0.0f,  0.5f,  0.0f), //  Top
      new Color3f( 0.0f,  0.5f,  0.0f),
      new Color3f( 0.0f,  0.5f,  0.0f),
      new Color3f( 0.0f,  0.5f,  0.0f),
      new Color3f( 1.0f,  0.0f,  0.0f), //  Left
      new Color3f( 1.0f,  0.0f,  0.0f),
      new Color3f( 1.0f,  0.0f,  0.0f),
      new Color3f( 1.0f,  0.0f,  0.0f),
      new Color3f( 0.5f,  0.0f,  0.0f), //  Right
      new Color3f( 0.5f,  0.0f,  0.0f),
      new Color3f( 0.5f,  0.0f,  0.0f),
      new Color3f( 0.5f,  0.0f,  0.0f)
    };

    QuadArray  aBox =
      new QuadArray(coords.length,
                    GeometryArray.COORDINATES | GeometryArray.NORMALS |
                    GeometryArray.COLOR_3);

    aBox.setCoordinates(0, coords);
    aBox.setNormals(0, norms);
    aBox.setColors(0, colors);
    Appearance  app = new Appearance();
    PolygonAttributes  pa = new PolygonAttributes();
    pa.setPolygonMode(pa.POLYGON_FILL);
    app.setPolygonAttributes(pa);
    Color3f black = new Color3f(0.1f, 0.1f, 0.1f);
    Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
    Color3f ringColor = new Color3f(0.8f, 0.0f, 0.6f);
    this.setGeometry(aBox);
    this.setAppearance(app);
  }

  public Node cloneNode(boolean forceDuplicate) {
    Box  box = new Box(x, y, z);
    box.duplicateNode(this, forceDuplicate);
    return box;
  }

  public void duplicateNode(Node originalNode, boolean forceDuplicate) {
    super.duplicateNode(originalNode, forceDuplicate);
  }
}
//  Copyright (c) 2000 by Allen Lynn McPherson.  All rights reserved.
//  This example is provided WITHOUT ANY WARRANTY either expressed or implied.

import javax.media.j3d.*;
import javax.vecmath.*;

//  Builds a test scene of a "circular staircase" any number of
//  a Shape3D objects.
public class  PrimStairsBG  extends BranchGroup {
  TransformGroup  topGroup = new TransformGroup();

  public  PrimStairsBG(Shape3D prim, int numPrims) {
    Transform3D  rotAroundY = new Transform3D();
    Transform3D  transOutX  = new Transform3D();
    Transform3D  transOutY  = new Transform3D();
    Transform3D  scaleAll   = new Transform3D();

    for (int i=0; i<numPrims; i++) {
      rotAroundY.rotY(i*(2*Math.PI/numPrims));
      transOutX.set(new Vector3d(3.0, 0.0, 0.0));
      transOutY.set(new Vector3d(0.0, (i*(1.0/numPrims)), 0.0));
      scaleAll.set((i+1)*(1.0/numPrims));       //  Watch for 0.0!

      //  Concenate above sequence of transformations into just one.
      Transform3D  primTrans = new Transform3D();       //  Identity
      primTrans.mul(rotAroundY);
      primTrans.mul(scaleAll);
      primTrans.mul(transOutX);
      primTrans.mul(transOutY);

      TransformGroup  primGroup = new TransformGroup(primTrans);
      primGroup.addChild(prim.cloneNode(false));
      topGroup.addChild(primGroup);
    }

    this.addChild(topGroup);
  }
}
//  Copyright (c) 2000 by Allen Lynn McPherson.  All rights reserved.
//  This example is provided WITHOUT ANY WARRANTY either expressed or implied.

import javax.media.j3d.*;
import javax.vecmath.*;

//  Very simple view that positions view platform to look at locale's
//  coordinate origin.  Extends BranchGroup for easy insertion and removal.
public class  SimpleViewBG  extends BranchGroup {
  protected View            view;       //  Viewing parameters.
  protected TransformGroup  topTG;      //  Y-axis rotation.
  protected TransformGroup  middleTG;   //  X-axis rotation.
  protected TransformGroup  bottomTG;   //  Z-axis translation.
  protected TransformGroup  scaleTG;    //  View volume scale.

  public  SimpleViewBG(Canvas3D aCanvas, float aYAngle,
                       float aXAngle, float aDist) {
    view = new View();
    //  Associate passed Canvas3D with this View object.
    view.addCanvas3D(aCanvas);
    view.setPhysicalBody(new PhysicalBody());
    view.setPhysicalEnvironment(new PhysicalEnvironment());

    //  Build the transformations that position and orient
    //  the view platform.
    Transform3D  rotAroundY = new Transform3D();
    Transform3D  rotAroundX = new Transform3D();
    Transform3D  transOutZ  = new Transform3D();
    Transform3D  scaleVV    = new Transform3D();
    rotAroundY.rotY(Math.toRadians(aYAngle));
    rotAroundX.rotX(Math.toRadians(aXAngle));
    transOutZ.set(new Vector3d(0.0, 0.0, aDist));

    //  Build a transform group for each of the above.
    topTG    = new TransformGroup(rotAroundY);
    middleTG = new TransformGroup(rotAroundX);
    bottomTG = new TransformGroup(transOutZ);
    scaleTG  = new TransformGroup(scaleVV);

    //  Build the sub-graph that will transform the view platform.
    ViewPlatform  vp = new ViewPlatform();
    this.addChild(topTG);
    topTG.addChild(middleTG);
    middleTG.addChild(bottomTG);
    bottomTG.addChild(scaleTG);
    scaleTG.addChild(vp);

    //  This should NOT be the default. Make the user set it!
    //  Add a white background to make screen dumps easier to print.
    //addBackground(new Color3f(1.0f, 1.0f, 1.0f));

    //  Set a reasonable activation radius.
    vp.setActivationRadius(100.0f);
    vp.setCapability(ViewPlatform.ALLOW_POLICY_READ);
    //  Tie this view platform to the View object.
    view.attachViewPlatform(vp);
  }

  public void  addViewPlatformGeometry(Group vpGeomG) {
    //  Don't add to scale node, but up one.
    bottomTG.addChild(vpGeomG);
  }

  //  Used to scale viewing volume for parallel projection.
  public void  setScale(float scale) {
    Transform3D  scaleTrans = new Transform3D();
    scaleTrans.set(scale);
    scaleTG.setTransform(scaleTrans);
  }

  public void  addBackground(Color3f bgColor) {
    //  Doesn't need to be very big since it's coincident
    //  with the view platform.
    BoundingSphere  b =
      new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1.0);
    Background  bg = new Background(bgColor);
    bg.setApplicationBounds(b);
    //  Don't add to scale node, but up one.
    bottomTG.addChild(bg);
  }

  public void  addBackground(ImageComponent2D image) {
    //  Doesn't need to be very big since it's coincident
    //  with the view platform.
    BoundingSphere  b =
      new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1.0);
    Background  bg = new Background(image);
    bg.setApplicationBounds(b);
    //  Don't add to scale node, but up one.
    bottomTG.addChild(bg);
  }

  public View  getView() {
    return view;
  }
}





//  Copyright (c) 2000 by Allen Lynn McPherson.  All rights reserved.
//  This example is provided WITHOUT ANY WARRANTY either expressed or implied.

import javax.media.j3d.*;
import javax.vecmath.*;

//  Extends SimpleViewTG to spin view platform around Y-axis.
public class  SpinViewBG  extends SimpleViewBG {

  public  SpinViewBG(Canvas3D aCanvas, float aYAngle,
                     float aXAngle, float aDist) {
    super(aCanvas, aYAngle, aXAngle, aDist);
    addSpinBehavior();
  }

  protected void  addSpinBehavior() {
    //  Make sure that the spin behavior will be able to update the
    //  transformation (from the superclass).
    topTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

    Transform3D  topSpin = new Transform3D();
    topTG.getTransform(topSpin);
    Alpha  spinAlpha =
      new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 8000, 0, 0, 0, 0, 0);
    RotationInterpolator  spinInterp =
      new RotationInterpolator(spinAlpha, topTG, topSpin, 0.0f,
                               (float)Math.PI*2.0f);
    BoundingSphere  spinBounds =
      new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1.0);
    spinInterp.setSchedulingBounds(spinBounds);
    this.addChild(spinInterp);
  }
}
//  Copyright (c) 2000 by Allen Lynn McPherson.  All rights reserved.
//  This example is provided WITHOUT ANY WARRANTY either expressed or implied.

import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import javax.media.j3d.*;
import javax.vecmath.*;


public class  TestViews extends  Applet {
  VirtualUniverse  univ     = new VirtualUniverse();
  Locale           locale   = new Locale(univ);
  BranchGroup      top      = new BranchGroup();
  Canvas3D         canvas   = new Canvas3D(null);

  public TestViews() {
    setLayout(new BorderLayout());
    add(canvas, BorderLayout.CENTER);

    addLights();

    //  Add the view to its own BranchGroup so that it can be
    //  easily detached from the scene graph.
    //SimpleViewBG  view = new SimpleViewBG(canvas, 0.0f, -35.0f, 10.0f);
    SpinViewBG  view = new SpinViewBG(canvas, -45.0f, -35.0f, 10.0f);
    view.addBackground(new Color3f(1,1,1));    //  make the background white


    //  Set for orthographic projection.  Comment out for perspective.
    view.getView().setProjectionPolicy(View.PARALLEL_PROJECTION);

    locale.addBranchGraph(view);

    //  Add a test scene to a separate BranchGroup.  We then have two
    //  scene graph branches: one for the scene and one for the view.
    top.addChild(new PrimStairsBG(new Box(), 20));
    locale.addBranchGraph(top);
  }

  //  Add ambient and directional lights.
  private void  addLights() {
    BoundingSphere  b =
      new BoundingSphere(new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE);
    AmbientLight  al =
      new AmbientLight(true, new Color3f(0.7f, 0.7f, 0.7f));
    al.setInfluencingBounds(b);
    top.addChild(al);

    DirectionalLight dl =
      new DirectionalLight(new Color3f(0.9f, 0.9f, 0.9f),
                           new Vector3f(2.0f,-1.0f, -1.0f));
    dl.setInfluencingBounds(b);
    top.addChild(dl);
  }

  //  Run as application or applet
  public static void  main(String[] args) {
    new MainFrame(new TestViews(), 512, 256);
  }
}
//  Copyright (c) 2000 by Allen Lynn McPherson.  All rights reserved.
//  This example is provided WITHOUT ANY WARRANTY either expressed or implied.

import java.applet.Applet;
import java.awt.*;
import com.sun.j3d.utils.applet.MainFrame;
import javax.media.j3d.*;
import javax.vecmath.*;

//  Display for different views of the same scene.
public class  FourView extends  Applet {
  VirtualUniverse  univ     = new VirtualUniverse();
  Locale           locale   = new Locale(univ);
  BranchGroup      top      = new BranchGroup();
  Canvas3D         c1, c2, c3, c4;

  public FourView() {
    setLayout(new GridLayout(2, 2, 10, 10));
    setBackground(Color.gray);
    c1 = new Canvas3D(null);
    c2 = new Canvas3D(null);
    c3 = new Canvas3D(null);
    c4 = new Canvas3D(null);
    add(c1);
    add(c2);
    add(c3);
    add(c4);

    addLights();

    //  Add a test scene.
    top.addChild(new PrimStairsBG(new Box(), 20));

    //  Create four different view objects (top, front, side, and angular).
    SpinViewBG  view1 = new SpinViewBG(c1,   0.0f, -90.0f, 10.0f);
    SimpleViewBG  view2 = new SimpleViewBG(c2,   0.0f,   0.0f, 10.0f);
    SpinViewBG  view3 = new SpinViewBG(c3, -90.0f,   0.0f, 10.0f);
    SimpleViewBG  view4 = new SimpleViewBG(c4, -45.0f, -35.0f, 10.0f);

    //  Make the view's background white.
    view1.addBackground(new Color3f(1,1,1));
    view2.addBackground(new Color3f(1,1,1));
    view3.addBackground(new Color3f(1,1,1));
    view4.addBackground(new Color3f(1,1,1));

    //  Make top, front, and side views orthographic.
    view1.getView().setProjectionPolicy(View.PARALLEL_PROJECTION);
    view2.getView().setProjectionPolicy(View.PARALLEL_PROJECTION);
    view3.getView().setProjectionPolicy(View.PARALLEL_PROJECTION);
    view1.setScale(4.0f);
    view2.setScale(4.0f);
    view3.setScale(4.0f);

    locale.addBranchGraph(view1);
    locale.addBranchGraph(view2);
    locale.addBranchGraph(view3);
    locale.addBranchGraph(view4);
    locale.addBranchGraph(top);
  }

  //  Add ambient and directional lights.
  private void  addLights() {
    BoundingSphere  b =
      new BoundingSphere(new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE);
    AmbientLight  al =
      new AmbientLight(true, new Color3f(0.7f, 0.7f, 0.7f));
    al.setInfluencingBounds(b);
    top.addChild(al);

    DirectionalLight dl =
      new DirectionalLight(new Color3f(0.9f, 0.9f, 0.9f),
                           new Vector3f(2.0f,-1.0f, -1.0f));
    dl.setInfluencingBounds(b);
    top.addChild(dl);
  }

  //  Run as application or applet
  public static void  main(String[] args) {
    new MainFrame(new FourView(), 512, 512);
  }
}

Reply via email to