Here is the code example to be put in 3 files. Sorry its so big. I don't
yet understand Java 3D enough to know exactly how to cut it done further.
After compiling and running Octave.java, you can use buttons 1 and 2 to
rotate about the x axis and 5, 6 to rotate about the y axis.
There are 2 tetrahedra defined to *intersect* each other. But as you rotate
the scene you see one tetrahedron in front of the other. This is not
correct (or not the way I need the tetrahedra to be displayed.) I need the
2 tetrahedra to be rendered as if they were one polyhedron, not 2 seperate
polyhedra.
Note that I do have
Appearance A = new Appearance();
RenderingAttributes RA = new RenderingAttributes();
RA.setDepthBufferEnable(true);
A.setRenderingAttributes(RA);
Here are the (not short) 3 files....
******** file: Octave.java **************************
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.util.Enumeration;
public class Octave extends JApplet
implements WindowListener
{
static Octave theApp;
DefaultMutableTreeNode root;
// All the polyhedra
Shape3D[] theSolidShapes = new Shape3D[2];
public static void main(String[] args)
{
theApp = new Octave();
} // end of main
public Octave()
{
JFrame frame = new JFrame();
frame.getContentPane().setBackground(Color.black);
frame.getContentPane().setLayout(new BorderLayout());
Toolkit theKit = frame.getToolkit();
Dimension windowSize = theKit.getScreenSize();
frame.setBounds(0, 0, windowSize.width, windowSize.height);
// Make this class listens for window events so we can close
// the window.
frame.addWindowListener(this);
// SimpleUniverse is a Convenience Utility class
Canvas3D canvas3D = new Canvas3D(null);
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
// create all the geometry
BranchGroup scene = createSceneGraph(simpleU);
simpleU.addBranchGraph(scene);
frame.getContentPane().add("Center", canvas3D);
frame.setVisible(true);
} // end of Octave (constructor)
public BranchGroup createSceneGraph(SimpleUniverse SU)
{
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// Create a light source
AmbientLight lightA = new AmbientLight();
lightA.setInfluencingBounds(new BoundingSphere());
objRoot.addChild(lightA);
DirectionalLight lightD1 = new DirectionalLight();
lightD1.setInfluencingBounds(new BoundingSphere());
objRoot.addChild(lightD1);
// add a transform object to allow the polyhedra to be rotated
TransformGroup objRotX = new TransformGroup();
objRotX.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
TransformGroup objRotY = new TransformGroup();
objRotY.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRotX.addChild(objRotY);
objRoot.addChild(objRotX);
// create all the polyhdera.
theSolidShapes[0] = new Shape3D();
theSolidShapes[0].setGeometry(Solid1());
theSolidShapes[0].setAppearance(createAppearanceSolid());
objRotY.addChild(theSolidShapes[0]);
theSolidShapes[1] = new Shape3D();
theSolidShapes[1].setGeometry(Solid2());
theSolidShapes[1].setAppearance(createAppearanceSolid());
objRotY.addChild(theSolidShapes[1]);
// Add behaviors
SimpleBehaviorX myRotXBehavior = new SimpleBehaviorX(objRotX);
myRotXBehavior.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myRotXBehavior);
SimpleBehaviorY myRotYBehavior = new SimpleBehaviorY(objRotY);
myRotYBehavior.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myRotYBehavior);
// Set the initial viewing platform location
TransformGroup vpTrans = null;
Transform3D T3D = new Transform3D();
Vector3f translate = new Vector3f();
vpTrans = SU.getViewingPlatform().getViewPlatformTransform();
translate.set(0.0f, 0.0f, 5.0f);
T3D.setTranslation(translate);
vpTrans.setTransform(T3D);
objRoot.compile();
return objRoot;
} // end of createSceneGraph method
public Geometry Solid1()
{
int NV = 3 * 4;
Point3f[] coord = new Point3f[NV];
Vector3f[] norms = new Vector3f[NV];
TriangleArray ta = new TriangleArray(NV, TriangleArray.COORDINATES |
TriangleArray.NORMALS);
Point3f v1 = new Point3f(-1.0f, -1.0f, -1.0f);
Point3f v2 = new Point3f( 1.0f, 1.0f, -1.0f);
Point3f v3 = new Point3f( 1.0f, -1.0f, 1.0f);
Point3f v4 = new Point3f(-1.0f, 1.0f, 1.0f);
coord[0] = v1;
coord[1] = v2;
coord[2] = v3;
coord[3] = v2;
coord[4] = v4;
coord[5] = v3;
coord[6] = v1;
coord[7] = v3;
coord[8] = v4;
coord[9] = v1;
coord[10] = v4;
coord[11] = v2;
ta.setCoordinates(0, coord);
// need to calculate all normals
for (int i = 0; i < 4; i++)
{
// For each triangular face, calculate 3 normals
int j = 3 * i;
Vector3f hold1 = new Vector3f(coord[j].x - coord[j+1].x,
coord[j].y - coord[j+1].y,
coord[j].z - coord[j+1].z);
Vector3f hold2 = new Vector3f(coord[j+1].x - coord[j+2].x,
coord[j+1].y - coord[j+2].y,
coord[j+1].z - coord[j+2].z);
Vector3f hold3 = new Vector3f(coord[j+2].x - coord[j].x,
coord[j+2].y - coord[j].y,
coord[j+2].z - coord[j].z);
Vector3f hold4 = new Vector3f(0.0f, 0.0f, 0.0f);
hold4.cross(hold1, hold2);
norms[j] = new Vector3f(hold4);
hold4.cross(hold2, hold3);
norms[j+1] = new Vector3f(hold4);
hold4.cross(hold3, hold1);
norms[j+2] = new Vector3f(hold4);
norms[j].normalize();
norms[j+1].normalize();
norms[j+2].normalize();
} // end for statement
ta.setNormals(0, norms);
return(ta);
} // end Solid1()
public Geometry Solid2()
{
int NV = 3 * 4;
Point3f[] coord = new Point3f[NV];
Vector3f[] norms = new Vector3f[NV];
TriangleArray ta = new TriangleArray(NV, TriangleArray.COORDINATES |
TriangleArray.NORMALS);
Point3f v1 = new Point3f( 1.0f, -1.0f, -1.0f);
Point3f v2 = new Point3f(-1.0f, 1.0f, -1.0f);
Point3f v3 = new Point3f(-1.0f, -1.0f, 1.0f);
Point3f v4 = new Point3f( 1.0f, 1.0f, 1.0f);
coord[0] = v1;
coord[1] = v2;
coord[2] = v4;
coord[3] = v1;
coord[4] = v4;
coord[5] = v3;
coord[6] = v1;
coord[7] = v3;
coord[8] = v2;
coord[9] = v2;
coord[10] = v3;
coord[11] = v4;
ta.setCoordinates(0, coord);
// need to calculate all normals
for (int i = 0; i < 4; i++)
{
// For each triangular face, calculate 3 normals
int j = 3 * i;
Vector3f hold1 = new Vector3f(coord[j].x - coord[j+1].x,
coord[j].y - coord[j+1].y,
coord[j].z - coord[j+1].z);
Vector3f hold2 = new Vector3f(coord[j+1].x - coord[j+2].x,
coord[j+1].y - coord[j+2].y,
coord[j+1].z - coord[j+2].z);
Vector3f hold3 = new Vector3f(coord[j+2].x - coord[j].x,
coord[j+2].y - coord[j].y,
coord[j+2].z - coord[j].z);
Vector3f hold4 = new Vector3f(0.0f, 0.0f, 0.0f);
hold4.cross(hold1, hold2);
norms[j] = new Vector3f(hold4);
hold4.cross(hold2, hold3);
norms[j+1] = new Vector3f(hold4);
hold4.cross(hold3, hold1);
norms[j+2] = new Vector3f(hold4);
norms[j].normalize();
norms[j+1].normalize();
norms[j+2].normalize();
} // end for statement
ta.setNormals(0, norms);
return(ta);
} // end Solid2()
public Appearance createAppearanceSolid()
{
Appearance A = new Appearance();
RenderingAttributes RA = new RenderingAttributes();
RA.setDepthBufferEnable(true);
A.setRenderingAttributes(RA);
Material theMaterial = new Material();
theMaterial.setCapability(Material.ALLOW_COMPONENT_WRITE);
theMaterial.setDiffuseColor(1.0f, 0.0f, 0.0f);
theMaterial.setLightingEnable(true);
A.setMaterial(theMaterial);
A.setPolygonAttributes(new
PolygonAttributes(PolygonAttributes.POLYGON_FILL,
PolygonAttributes.CULL_BACK, 0.01f, false));
TransparencyAttributes TA = new
TransparencyAttributes(TransparencyAttributes.NICEST, 0.0f);
A.setTransparencyAttributes(TA);
return(A);
} // end createAppearanceSolid
public void windowClosing(WindowEvent e)
{
// This is how to close and end the applet
Window w = e.getWindow();
w.setVisible(false);
if (w != null) w.dispose();
System.exit(0);
} // end windowClosing
public void windowClosed(WindowEvent e)
{
}
public void windowOpened(WindowEvent e)
{
}
public void windowActivated(WindowEvent e)
{
}
public void windowDeactivated(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowIconified(WindowEvent e)
{
}
} // end of class Octave
********** file: SimpleBehaviorX.java **************
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.event.*;
import java.awt.AWTEvent;
import java.util.Enumeration;
public class SimpleBehaviorX extends Behavior
{
private TransformGroup targetTG;
private Transform3D rotation = new Transform3D();
private double angle = 0.0;
private char theKey;
private boolean doRot;
// create SimpleBehavior
SimpleBehaviorX(TransformGroup targetTG)
{
this.targetTG = targetTG;
}
// initialize the Behavior
// set initial wakeup condition
// called when behavior beacomes live
public void initialize()
{
// set initial wakeup condition
this.wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));
}
// behave
// called by Java 3D when appropriate stimulus occures
public void processStimulus(Enumeration criteria)
{
WakeupCriterion wakeup;
AWTEvent[] evt = null;
theKey = ' ';
doRot = false;
// decode event
while (criteria.hasMoreElements())
{
// check to see if one is to rotate about Y-axis
wakeup = (WakeupCriterion)criteria.nextElement();
if (!(wakeup instanceof WakeupOnAWTEvent))
{
// not the right kind of event
continue;
} // end if statement
evt = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
if (evt == null) continue;
for (int i = 0; i < evt.length; i++)
{
if (evt[0] instanceof KeyEvent)
{
theKey = ((KeyEvent)evt[0]).getKeyChar();
if ((theKey == '1') || (theKey == '2'))
{
doRot = true;
break;
} // end if '1' or '2'
} // end if KeyEvent
} // end for statement
} // end while statement
// do what is necessary
if (doRot)
{
if (theKey == '2')
{
angle += 0.05;
if (angle > (2.0 * Math.PI)) angle = angle - 2.0 * Math.PI;
}
else
{
angle -= 0.05;
if (angle < (-2.0 * Math.PI)) angle = angle + 2.0 * Math.PI;
}
rotation.rotX(angle);
targetTG.setTransform(rotation);
} // end if statement
// always reset the trigger
this.wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));
}
} // end of class SimpleBehaviorX
********* file: SimpleBehaviorY.java *******************
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.event.*;
import java.awt.AWTEvent;
import java.util.Enumeration;
public class SimpleBehaviorY extends Behavior
{
private TransformGroup targetTG;
private Transform3D rotation = new Transform3D();
private double angle = 0.0;
private char theKey;
private boolean doRot;
// create SimpleBehavior
SimpleBehaviorY(TransformGroup targetTG)
{
this.targetTG = targetTG;
}
// initialize the Behavior
// set initial wakeup condition
// called when behavior beacomes live
public void initialize()
{
// set initial wakeup condition
this.wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));
}
// behave
// called by Java 3D when appropriate stimulus occures
public void processStimulus(Enumeration criteria)
{
WakeupCriterion wakeup;
AWTEvent[] evt = null;
theKey = ' ';
doRot = false;
// decode event
while (criteria.hasMoreElements())
{
// check to see if one is to rotate about Y-axis
wakeup = (WakeupCriterion)criteria.nextElement();
if (!(wakeup instanceof WakeupOnAWTEvent))
{
// not the right kind of event
continue;
} // end if statement
evt = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
if (evt == null) continue;
for (int i = 0; i < evt.length; i++)
{
if (evt[0] instanceof KeyEvent)
{
theKey = ((KeyEvent)evt[0]).getKeyChar();
if ((theKey == '5') || (theKey == '6'))
{
doRot = true;
break;
} // end if '5' or '6'
} // end if KeyEvent
} // end for statement
} // end while statement
// do what is necessary
if (doRot)
{
if (theKey == '6')
{
angle += 0.05;
if (angle > (2.0 * Math.PI)) angle = angle - 2.0 * Math.PI;
}
else
{
angle -= 0.05;
if (angle < (-2.0 * Math.PI)) angle = angle + 2.0 * Math.PI;
}
rotation.rotY(angle);
targetTG.setTransform(rotation);
} // end if statement
// always reset the trigger
this.wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));
} // end processStimulus
} // end of class SimpleBehaviorY
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".