Hello everyone. I was hoping someone might be able to offer some advice on a difficulty I am experiencing. I am currently trying to get geometry-based picking to work in a Java3D 1.3 application, but I keep running into the following exception:
javax.media.j3d.CapabilityNotSetException: Shape3D: no capability to allow intersect
This shouldn't be happening as I am setting the appropriate capabilities in my geometries:
box.setCapability(Geometry.ALLOW_INTERSECT);
box.setCapability(Primitive.ENABLE_GEOMETRY_PICKING);If anyone has managed to use geometry-based picking in a Java3D app before, I'd love to hear from you. I've attached my source code, in case you're interested.
Cheers.
Ian
=========================================================================== 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".
import java.awt.*; import java.awt.event.*; import java.util.Enumeration; import java.applet.Applet; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.geometry.*; import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.picking.behaviors.*;
public class WorldViewer extends Applet
{
private Canvas3D canvas;
private SimpleUniverse u;
private BranchGroup objRoot = new BranchGroup();
private final float earthRadius = 0.6f;
private Appearance basicAppearance = new Appearance();
private Material basicMaterial = new Material();
// private Sphere earth = new Sphere(earthRadius,
Primitive.ENABLE_GEOMETRY_PICKING, 50);
private Sphere earth = new Sphere(earthRadius);
private TransformGroup globalRotateGroup = new TransformGroup();
private Group cityGroup = new Group();
private Transform3D globalRotate = new Transform3D();
private RotationControlBehavior rotateBehaviour = new
RotationControlBehavior();
private MovementBehavior movementBehaviour = new MovementBehavior();
private int rotationVector;
public WorldViewer() {
setLayout(new BorderLayout());
GraphicsEnvironment ge;
GraphicsDevice gd;
GraphicsConfigTemplate3D gct = new GraphicsConfigTemplate3D();
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
canvas = new Canvas3D(gd.getBestConfiguration(gct));
canvas.setStereoEnable(false);
canvas.setMonoscopicViewPolicy(View.CYCLOPEAN_EYE_VIEW);
add(canvas, BorderLayout.CENTER);
// Create the scene; attach it to the virtual universe
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(canvas);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
private BranchGroup createSceneGraph()
{
objRoot.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
objRoot.addChild(globalRotateGroup);
objRoot.addChild(rotateBehaviour);
objRoot.addChild(movementBehaviour);
globalRotateGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
globalRotateGroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
globalRotateGroup.setTransform(globalRotate);
globalRotateGroup.addChild(cityGroup);
// basicMaterial.setAmbientColor(new Color3f(0.0f,0.0f,1.0f));
basicMaterial.setDiffuseColor(new Color3f(0.7f,0.7f,0.7f));
// basicMaterial.setSpecularColor(new Color3f(0.7f,0.7f,0.7f));
basicMaterial.setColorTarget(Material.DIFFUSE);
basicAppearance.setMaterial(basicMaterial);
Color3f col = new Color3f(0.0f, 0.0f, 1.0f);
ColoringAttributes ca = new ColoringAttributes(col,
ColoringAttributes.NICEST);
basicAppearance.setColoringAttributes(ca);
// earth.setAppearance(basicAppearance);
globalRotateGroup.addChild(earth);
// Main light
DirectionalLight mainLight = new DirectionalLight (
new Color3f (1f, 1f, 1f),
new Vector3f (-1.f, -0.5f, -1f));
mainLight.setInfluencingBounds(new BoundingSphere(new Point3d(),
Float.MAX_VALUE));
mainLight.setCapability(Light.ALLOW_STATE_WRITE);
objRoot.addChild(mainLight);
addCity(cityGroup, 35.75f, -139.75f, 5258, 5934, "Tokyo");
addCity(cityGroup, 40.75f, 74f, 11518, 1728, "New York");
addCity(cityGroup, 19f, -72.75f, 958, 18262, "Mumbai");
addCity(cityGroup, 19.5f, 99f, 1476, 11685, "Mexico City");
addCity(cityGroup, -6f, -106.75f, 2590, 6564, "Jakarta");
addCity(cityGroup, 37.5f, -127f, 1049, 16064, "Seoul");
addCity(cityGroup, -23.5f, 46.5f, 1981, 8378, "Sao Paulo");
addCity(cityGroup, 34.75f, -135.5f, 2720, 5681, "Osaka-Kobe-Kyoto");
addCity(cityGroup, 14.5f, -121f, 1943, 7465, "Manila");
addCity(cityGroup, 34f, 118.25f, 5457, 2436, "Los Angeles");
addCity(cityGroup, 30f, -31.25f, 482, 25325, "Cairo");
addCity(cityGroup, 22.5f, -88.5f, 1036, 11680, "Calcutta");
addCity(cityGroup, -34.5f, 58.5f, 2771, 4041, "Buenos Aires");
addCity(cityGroup, 28.75f, -77.25f, 583, 17675, "Delhi");
addCity(cityGroup, 25f, -67f, 932, 10832, "Karachi");
addCity(cityGroup, -23f, 43.25f, 1166, 8280, "Rio de Janeiro");
addCity(cityGroup, 49f, -2.5f, 2721, 3545, "Paris");
addCity(cityGroup, 31.25f, -121.5f, 549, 16391, "Shanghai");
addCity(cityGroup, 41f, -29f, 1269, 7013, "Istanbul");
addCity(cityGroup, 55.75f, -37.5f, 596, 14605, "Moscow");
addCity(cityGroup, 42f, 87.5f, 5499, 1511, "Chicago");
addCity(cityGroup, 35f, -137f, 2823, 2851, "Nagoya");
addCity(cityGroup, 40f, -116.5f, 518, 14479, "Beijing");
addCity(cityGroup, 51.5f, 0f, 1186, 6046, "London");
addCity(cityGroup, 13.75f, -100.5f, 482, 13877, "Bangkok");
addCity(cityGroup, 51.25f, -7.25f, 2720, 2243, "Rhine-Ruhr-Wupper");
addCity(cityGroup, 13f, -80.25f, 456, 13345, "Chennai");
addCity(cityGroup, 39f, 77f, 4763, 1262, "Washington");
addCity(cityGroup, 25f, -121.5f, 259, 23012, "Taipei");
addCity(cityGroup, 4.75f, 74f, 479, 11625, "Bogota");
addCity(cityGroup, 40f, 75.25f, 4659, 1105, "Philidelphia");
addCity(cityGroup, -26.25f, -28f, 1300, 3923, "Johannesburg");
addCity(cityGroup, -33.5f, 70.75f, 974, 5070, "Santiago");
addCity(cityGroup, 25.75f, 80.25f, 2890, 1702, "Miami");
addCity(cityGroup, 10.75f, -106.75f, 135, 35722, "Ho Chi Minh");
addCity(cityGroup, 37.75f, 122.5f, 2038, 2339, "San Francisco");
addCity(cityGroup, 40.5f, 3.75f, 526, 8654, "Madrid");
addCity(cityGroup, 10.5f, 67f, 280, 16266, "Caracas");
addCity(cityGroup, 42.25f, 71f, 5144, 867, "Boston");
addCity(cityGroup, 6.5f, -3.5f, 324, 13591, "Lagos");
addCity(cityGroup, 43.75f, 79.5f, 1652, 2643, "Toronto");
addCity(cityGroup, 45.5f, -9.25f, 829, 5068, "Milan");
addCity(cityGroup, 32.75f, 96.75f, 3644, 1138, "Dallas");
addCity(cityGroup, 23f, -113.25f, 3644, 1138, "Guangzhao");
addCity(cityGroup, 42.25f, 83f, 3266, 1195, "Detroit");
addCity(cityGroup, -20f, 44f, 829, 4706, "Belo Horizonte");
addCity(cityGroup, 22.25f, -114.25f, 82, 46561, "Hong Kong");
addCity(cityGroup, 29.75f, 95.5f, 3354, 1140, "Houston");
addCity(cityGroup, 39.25f, -117.25f, 174, 21535, "Tianjin");
addCity(cityGroup, 41.75f, -123.5f, 335, 11006, "Shenyang");
addCity(cityGroup, 35f, -129f, 366, 9973, "Busan");
addCity(cityGroup, -34f, -151f, 2103, 1683, "Sydney");
addCity(cityGroup, 33.75f, 84.5f, 5084, 688, "Atlanta");
addCity(cityGroup, 38f, -23.75f, 417, 8350, "Athens");
addCity(cityGroup, 52.5f, -13.5f, 619, 5607, "Berlin");
addCity(cityGroup, 30.5f, -114.25f, 194, 17289, "Wuhan");
addCity(cityGroup, 45.5f, 73.5f, 1738, 1851, "Montreal");
addCity(cityGroup, 41.5f, -2.25f, 339, 9431, "Barcelona");
addCity(cityGroup, -30f, 51.25f, 707, 4314, "Porto Alegre");
addCity(cityGroup, 3f, -101.75f, 531, 5697, "Kuala Lampur");
addCity(cityGroup, -37.75f, -145f, 2025, 1493, "Melbourne");
addCity(cityGroup, 1.25f, -104f, 319, 9376, "Singapore");
addCity(cityGroup, 49.25f, 123f, 1119, 1636, "Vancouver");
addCity(cityGroup, 33.5f, 112f, 2069, 1405, "Phoenix");
addCity(cityGroup, 47.5f, 122.25f, 2471, 1098, "Seattle");
addCity(cityGroup, 32.75f, 117f, 2025, 1320, "San Diego");
addCity(cityGroup, 42f, 12.5f, 474, 5600, "Rome");
addCity(cityGroup, -7.25f, -112.75f, 140, 17682, "Surabaya");
addCity(cityGroup, 45.75f, -126.75f, 153, 16137, "Harbin");
addCity(cityGroup, 53.5f, 2.25f, 725, 3309, "Manchester");
addCity(cityGroup, 45f, 93.25f, 2315, 1032, "Minneapolis");
addCity(cityGroup, 41f, 14.25f, 552, 4214, "Naples");
addCity(cityGroup, 22.5f, -106.5f, 102, 22618, "Chongquing");
addCity(cityGroup, -25.5f, 49.25f, 803, 2802, "Curitiba");
addCity(cityGroup, 18.5f, 66f, 2310, 960, "San Juan");
addCity(cityGroup, 52.5f, 2f, 632, 3481, "Birmingham");
addCity(cityGroup, 32f, -119f, 124, 17258, "Nanjing");
addCity(cityGroup, 38.5f, 90.25f, 2147, 968, "St. Louis");
// Have Java 3D perform optimizations on this scene graph.
objRoot.compile();
return objRoot;
}
public void addCity(Group parentGroup, float lattitude, float longitude, int
area, int populationDensity, String cityName)
{
// Set box size based on area and pop density.
float boxWidth = (float)Math.sqrt(area) * 0.001f;
float boxHeight = earthRadius/2 + (populationDensity * 0.00001f);
float boxDepth = boxWidth;
TransformGroup transGrp1 = new TransformGroup();
TransformGroup transGrp2 = new TransformGroup();
TransformGroup transGrp3 = new TransformGroup();
Transform3D translate = new Transform3D();
Transform3D rotX = new Transform3D();
Transform3D rotY = new Transform3D();
transGrp1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
transGrp1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transGrp2.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
transGrp2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transGrp3.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
transGrp3.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transGrp3.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
// North is positive, West is positive
rotY.rotY(Math.toRadians(-longitude));
rotX.rotX(Math.toRadians(90 - lattitude));
translate.setTranslation(new Vector3f(0f, earthRadius/2, 0f));
parentGroup.addChild(transGrp1);
transGrp1.addChild(transGrp2);
transGrp2.addChild(transGrp3);
Box box = new Box(boxWidth, boxHeight, boxDepth,
earth.getAppearance());
box.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
box.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
box.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
box.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
box.setCapability(Geometry.ALLOW_INTERSECT);
box.setCapability(Primitive.ENABLE_GEOMETRY_PICKING);
box.setCapability(Node.ALLOW_PICKABLE_READ);
box.setCapability(Node.ALLOW_PICKABLE_WRITE);
box.setCapability(Node.ENABLE_PICK_REPORTING);
transGrp3.addChild(box);
MouseOverCityBehavior behavior = new MouseOverCityBehavior(canvas,
objRoot, new BoundingSphere(), box, cityName);
parentGroup.addChild(new PickRotateBehavior(objRoot, canvas, new
BoundingSphere(), PickTool.GEOMETRY));
parentGroup.addChild(behavior);
transGrp1.setTransform(rotY);
transGrp2.setTransform(rotX);
transGrp3.setTransform(translate);
}
private void update()
{
Transform3D additionalRotation = new Transform3D();
additionalRotation.rotY(-rotationVector * 0.0001);
globalRotate.mul(additionalRotation);
globalRotateGroup.setTransform(globalRotate);
}
public class RotationControlBehavior extends Behavior
{
WakeupOnAWTEvent criterion = new WakeupOnAWTEvent(Event.MOUSE_MOVE);
public void initialize()
{
setSchedulingBounds(new BoundingSphere(new Point3d(0, 0, 0),
1e10));
wakeupOn(criterion);
}
public void processStimulus(Enumeration criteria)
{
AWTEvent[] events = criterion.getAWTEvent();
MouseEvent me = (MouseEvent)events[0];
// If there is mouse movement in the left-most quarter of the
screen
if (me.getX() < getWidth() / 4)
{
rotationVector = me.getX() - getWidth() / 4;
}
// If there is mouse movement in the right-most quarter of the
screen
else if (me.getX() > getWidth() / 4 * 3)
{
rotationVector = me.getX() - getWidth() / 4 * 3;
}
else
{
rotationVector = 0;
}
wakeupOn(criterion);
}
}
public class MovementBehavior extends Behavior
{
WakeupCriterion criterion;
public void initialize()
{
criterion = new WakeupOnElapsedFrames(0);
setSchedulingBounds(new BoundingSphere(new Point3d(0, 0, 0),
1e10));
wakeupOn(criterion);
}
public void processStimulus(Enumeration criteria)
{
update();
wakeupOn(criterion);
}
}
public class MouseOverCityBehavior extends PickMouseBehavior
{
private WakeupOnAWTEvent criterion;
private Box box;
private String cityName;
public MouseOverCityBehavior (Canvas3D canvas, BranchGroup root,
Bounds bounds, Box box, String cityName)
{
super(canvas, root, bounds);
this.box = box;
this.cityName = cityName;
}
public void initialize() {
criterion = new WakeupOnAWTEvent(Event.MOUSE_MOVE);
wakeupOn(criterion);
}
public void processStimulus(Enumeration criteria) {
AWTEvent[] events = criterion.getAWTEvent();
MouseEvent me = (MouseEvent)events[0];
System.out.println(cityName);
wakeupOn(criterion);
}
public void updateScene(int x, int y)
{
System.out.println("updateScene " + cityName);
}
}
}
===========================================================================
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".
