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".