package torus;
/**
CSE391 demo. Uses Java3D to view a list of triangles, to show
how dynamically generated object can be controlled and displayed.
Adapted from Sun's GearTest example, by GWH, Sept 2003, but object
is a simple torus with structure determined by GUI controls.
*/
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class J3Dviewer extends Applet {
private SimpleUniverse u = null;
private controls cp = null; // control panel
private BranchGroup objSplice; // where our thing gets spliced into scene
private BranchGroup objBranch; // group containing our thing
private Appearance app; // its appearance
// The following allows this to be run as an application
// as well as an applet
public static void main(String[] args) {
if (args.length > 0) {
System.out.println("Usage: java J3Dviewer");
System.exit(0);
}
new MainFrame(new J3Dviewer(), 700, 700);
}
// Set up the two frames and their contents
public void init() {
// create control panel in separate JFrame
cp = new controls(this);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = cp.getSize();
cp.setLocation(500, 500);
cp.setSize(450,350);
cp.setVisible(true);
// put 3D canvas in this frame
setLayout(new BorderLayout());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
// Create a simple scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
// Create our scene graph, with lights, rotation, and object
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.6);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
// Create a bounds for the background and lights
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
// Set up the background
Color3f bgColor = new Color3f(0.95f, 0.9f, 0.4f);
Background bgNode = new Background(bgColor);
bgNode.setApplicationBounds(bounds);
objScale.addChild(bgNode);
// Set up the global lights
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
Color3f light2Color = new Color3f(0.3f, 0.3f, 0.4f);
Vector3f light2Direction = new Vector3f(-6.0f, -2.0f, -1.0f);
Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
AmbientLight ambientLightNode = new AmbientLight(ambientColor);
ambientLightNode.setInfluencingBounds(bounds);
objScale.addChild(ambientLightNode);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objScale.addChild(light1);
DirectionalLight light2 = new DirectionalLight(light2Color, light2Direction);
light2.setInfluencingBounds(bounds);
objScale.addChild(light2);
// 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);
objScale.addChild(objTrans);
// Create an Appearance.
app = new Appearance();
Color3f objColor = new Color3f(0.5f, 0.5f, 0.9f);
Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
app.setMaterial(new Material(objColor, black, objColor, white, 100.0f));
// create thing to display
//xyz[][] triangles = makeTetrahedron(); // simple test case
xyz[][] triangles = makeTorus.triangles(cp); // first as list of triangles
Shape3D thing = new makeJ3DObj(triangles, app); // then convert to J3D object
objSplice = new BranchGroup();
//Note Java3D bug: You can't OR these capabilities. Set individually:
objSplice.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
objSplice.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
objBranch = new BranchGroup();
objBranch.setCapability(BranchGroup.ALLOW_DETACH);
objTrans.addChild(objSplice);
objSplice.addChild(objBranch);
objBranch.addChild(thing);
// Create a new Behavior object that will rotate the object and
// add it into the scene graph.
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
8000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
// Have Java 3D perform optimizations on this scene graph.
//objRoot.compile(); //crashes. (J3D bug?)
return objRoot;
}
// When controls change, regenerate the structure
public void updateThing(){
Shape3D newThing = new makeJ3DObj(makeTorus.triangles(cp), app); // remake it
BranchGroup newBG = new BranchGroup(); // make a branchGroup for it
newBG.addChild(newThing);
//newBG.compile(); //(crashes. J3D bug?)
objBranch.detach(); // remove old one
objBranch=newBG;
objBranch.setCapability(BranchGroup.ALLOW_DETACH);
objSplice.addChild(objBranch); // splice in new one
}
// when all done...
public void destroy() {
u.cleanup();
}
// The following was used for testing the viewer before writing the torus code:
// create tetrahedron, as test object
// as array of k triangles in form xyz[k][3]
// where each xyz is a vertex
//
private xyz [][] makeTetrahedron(){
xyz v0=new xyz( 1, 1, 1); // alternate vertices of cube
xyz v1=new xyz( 1,-1,-1);
xyz v2=new xyz(-1,-1, 1);
xyz v3=new xyz(-1, 1,-1);
xyz[][] triList={{v0,v2,v1},{v0,v1,v3},{v2,v0,v3},{v2,v3,v1}}; // 4 triangles
return triList;
}
}