Hi,
Thanks for your reply. In the meantime I solved it. Good old PickCanvas. I used the USE_BOUNDS type as I understand this is the cheapest computationally.
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.universe.SimpleUniverse;
import javax.media.j3d.*;
import javax.vecmath.*;
import javax.swing.JOptionPane;
import java.awt.event.*;
import java.util.Enumeration;
/**
* PickCanvasTest.java
* @author Tim Bennett
*/
public class PickCanvasTest extends Applet {
BranchGroup objRoot;
Canvas3D canvas3D;
public PickCanvasTest() {
setLayout(new BorderLayout());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
canvas3D = new Canvas3D(config);
add("Center", canvas3D);
BranchGroup scene = createSceneGraph();
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph(scene);
}
public BranchGroup createSceneGraph() {
objRoot = new BranchGroup();
objRoot.setCapability(BranchGroup.ALLOW_PICKABLE_READ);
objRoot.setCapability(BranchGroup.ENABLE_PICK_REPORTING);
ColorCube ca=new ColorCube(0.4);
ca.setCapability(ColorCube.ALLOW_PICKABLE_READ);
ca.setCapability(ColorCube.ALLOW_BOUNDS_READ);
ca.setCapability(ColorCube.ENABLE_PICK_REPORTING);
// ca.setCapability(ColorCube.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
ca.getGeometry().setCapability( GeometryArray.ALLOW_COORDINATE_READ );
ca.getGeometry().setCapability( GeometryArray.ALLOW_COUNT_READ );
ca.getGeometry().setCapability( GeometryArray.ALLOW_FORMAT_READ );
ca.setPickable(true);
objRoot.addChild(ca);
SimpleBehavior myBehavior = new SimpleBehavior(objRoot,canvas3D);
myBehavior.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myBehavior);
objRoot.compile();
return objRoot;
}
public class SimpleBehavior extends Behavior {
private TransformGroup targetTG;
private Transform3D rotation = new Transform3D();
private WakeupCondition wCond;
private PickCanvas pickCanvas;
// create SimpleBehavior
public SimpleBehavior(BranchGroup targetBG,Canvas3D canvas3D) {
wCond=new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
pickCanvas=new PickCanvas(canvas3D,targetBG);
pickCanvas.setTolerance(5.0f);
// pickCanvas.setMode(PickCanvas.GEOMETRY_INTERSECT_INFO);
pickCanvas.setMode(PickCanvas.BOUNDS);
}
public void initialize() {
// set initial wakeup condition
this.setSchedulingBounds(new BoundingSphere(new Point3d(),300));
this.wakeupOn(wCond);
}
public void processStimulus(Enumeration criteria) {
PickResult pickResult;
MouseEvent event=(MouseEvent)((WakeupOnAWTEvent) criteria.nextElement()).getAWTEvent()[0];
// pickCanvas.setShapeLocation(event);
int x = event.getX();
int y = event.getY();
pickCanvas.setShapeLocation( x, y );
if(pickCanvas.pickClosest()!=null) {
pickResult=pickCanvas.pickClosest();
Node node=pickResult.getObject();
System.err.println( "Picked!" );
Shape3D shape = (Shape3D) pickResult.getNode(PickResult.SHAPE3D);
System.err.println( "Name: " + shape.toString() );
//PickTool.setCapabilities(node,PickTool.INTERSECT_FULL);
}
else
JOptionPane.showMessageDialog(null,"pickCanvas.pickClosest() is null");
this.wakeupOn(wCond);
}
}
public static void main(String[] args) {
Frame frame = new MainFrame(new PickCanvasTest(), 256, 256);
}
}
How could one adapt this to implement Collision Avoidance. Do you have to pick every frame forwards (to stop you going through walls) and downwards (to stop yourself from going through the floor)?