< Zurück | Inhalt | Weiter >

16.7 VRML picking example

The VrmlPickingTest example illustrates how the PickCanvas and PickResult classes can be used. The example loads a VRML format data file and allows the user to rotate, translate, and scale the loaded model. When the mouse is clicked, a list is generated of the intersections of the model with a PickCylinderRay that passes perpendicularly through the clicked screen location into the 3D scene. All the intersections with the model are reported, as well as the closest intersection.


When a mouse click occurs, VrmlPickingTest produces the following output (which corresponds to clicking the mouse in the position shown in figure 16.1. The output is a list of the PickResult objects (sorted from nearest to farthest):


*** MouseClick ***


First, the path through the scenegraph to the intersected node is displayed. In this case, the path is the VirtualUniverse’s Locale, a BranchGroup, the Sphere primitive (user data is “Sphere”), then finally a Shape3D containing a TriangleStripArray.


image


Figure 16.1 A VRML scene loaded into the VrmlPickingTest example. Note the position of the cursor (the hand icon), which corresponds to the scene intersections in the code which follows

Sorted PickResult 0: PickResult: sgp:javax.media.j3d.Locale@124fb8e : javax.media.j3d.BranchGroup : com.sun.j3d.utils.geometry.Sphere, Sphere : javax.media.j3d.Shape3D, Spherejavax.media.j3d.TriangleStripArray@12b486c


The transformation matrix required to convert the terminal node of the scenegraph path (Shape3D) to Virtual World coordinates is displayed. This is the transformation matrix that was in effect when the pick took place.


LocalToVworld Transform:

−0.5243562077058301, −0.8502316137753383, 0.04644104194946784, 0.35220520974733893

0.3928339572694004, −0.19315917400790997, 0.8990945531548112, 5.215472765774056

−0.7554680995624017, 0.4896894285499475, 0.4352840614012915, 0.5764203070064573

0.0, 0.0, 0.0, 1.0


Next, the intersection information for the ray is displayed. In this case, the ray intersected six Nodes in the model. For each intersection, the distance of the intersection from the ViewPlatform is calculated along with the point’s coordinates in Virtual World coordinates. As you can see from the Z−coordinates and distances, five of the intersections were with Nodes at the front of the Sphere while one was with a node at the rear of the Sphere.


node:javax.media.j3d.Shape3D@12b485a PickIntersection: geomIndex = 0

dist:13.190385327169809

ptVW:(0.3082159939737674, 5.101595194311164, −0.40544525181089597)


PickIntersection: geomIndex = 0 dist:11.285273011880047

ptVW:(0.2697997524391042, 4.782074528439611, 1.4723671948932975)


PickIntersection: geomIndex = 0 dist:11.28272787795884

ptVW:(0.2766647006417829, 4.784127302928557, 1.4754390646997604)


PickIntersection: geomIndex = 0 dist:11.282690605316592

ptVW:(0.26386760841671225, 4.797646503054273, 1.4773578620510737)


PickIntersection: geomIndex = 0 dist:11.279971427880689

ptVW:(0.27735265885195876, 4.796380438058344, 1.4802262351804227)


PickIntersection: geomIndex = 0 dist:11.28272787795884

ptVW:(0.2766647006417829, 4.784127302928557, 1.4754390646997604)


Sorted Object 0: Sphere Closest Object: Sphere

The second illustrated pick intersection is more complex (figure 16.2). As you can see, the sphere is still the closest intersection; however, the pick ray passes through the entire model. In this example (output following), the VRML part intersections are (sorted from nearest to farthest):


1. Sphere: 2 intersections

2. Cone: 2 intersections

3. Cone: 2 intersections

4. Box: 2 intersections

5. Cone: 7 intersections


*** MouseClick ***


Sorted PickResult 0: PickResult: sgp:javax.media.j3d.Locale@124fb8e : javax.media.j3d.BranchGroup :


image


Figure 16.2 A VRML scene loaded into the VrmlPickingTest example. Note the position of the cursor (the hand icon) which corresponds to the scene intersections in the code that follows


com.sun.j3d.utils.geometry.Sphere, Sphere : javax.media.j3d.Shape3D, Sphere javax.media.j3d.TriangleStripArray@12b486c LocalToVworld Transform:

0.974680683424301, −0.19810018807842686, −0.10370092016385302,

−0.5185046008192652

0.2217376557236817, 0.9160774460188752, 0.3341175316108114,

2.8105876580540574

0.028809328241108344, −0.34865230298798766, 0.9368092624581957, 3.084046312290978

0.0, 0.0, 0.0, 1.0


node:javax.media.j3d.Shape3D@12b485a PickIntersection: geomIndex = 0

dist:10.31109258625374

ptVW:(−0.503754844446497, 2.138046095717119, 2.3502490354035483)


PickIntersection: geomIndex = 0 dist:10.315735064224192

ptVW:(−0.48806121433886257, 2.1446076441445165, 2.3442903032651294)


PickIntersection: geomIndex = 0 dist:10.311507103034156

ptVW:(−0.46680214250863505, 2.1403178766932185, 2.3478813387527073)


PickIntersection: geomIndex = 0 dist:8.737141773923474

ptVW:(−0.41919205110931124, 2.265854783380931, 3.916754614302066)


PickIntersection: geomIndex = 0 dist:8.771580342395431

ptVW:(−0.41919205110931124, 2.265854783380931, 3.916754614302066)


PickIntersection: geomIndex = 0 dist:8.732273133281984

ptVW:(−0.41290180559136586, 2.275910225691348, 3.9205080490411017)


PickIntersection: geomIndex = 0 dist:8.73669779993455

ptVW:(−0.4106277895151771, 2.2691852339960756, 3.916514821486335)


Sorted Object 0: Sphere


Sorted PickResult 1: PickResult: sgp:javax.media.j3d.Locale@124fb8e : javax.media.j3d.BranchGroup : javax.media.j3d.Shape3D, Cone javax.media.j3d.TriangleFanArray@1262519 LocalToVworld Transform:

0.974680683424301, −0.19810018807842686, −0.10370092016385302,

−0.3111027604915591

0.2217376557236817, 0.9160774460188752, 0.3341175316108114,

2.1423525948324347

0.028809328241108344, −0.34865230298798766, 0.9368092624581957, 1.2104277873745866

0.0, 0.0, 0.0, 1.0


node:javax.media.j3d.Shape3D@1261cac PickIntersection: geomIndex = 0

dist:10.943688351941072

ptVW:(−0.510896717862459, 2.1149716954978928, 1.7318035261186269)


PickIntersection: geomIndex = 0 dist:10.92767850911496

ptVW:(−0.5066210416916537, 2.112735307161519, 1.7330744444918968)


Sorted Object 1: Cone


Sorted PickResult 2: PickResult: sgp:javax.media.j3d.Locale@124fb8e : javax.media.j3d.BranchGroup : javax.media.j3d.Shape3D, Cone javax.media.j3d.TriangleFanArray@1262519 LocalToVworld Transform:

0.974680683424301, −0.19810018807842686, −0.10370092016385302,

−0.3111027604915591

0.2217376557236817, 0.9160774460188752, 0.3341175316108114,

2.1423525948324347

0.028809328241108344, −0.34865230298798766, 0.9368092624581957, 1.2104277873745866

0.0, 0.0, 0.0, 1.0


node:javax.media.j3d.Shape3D@1261cac PickIntersection: geomIndex = 0

dist:10.943688351941072

ptVW:(−0.510896717862459, 2.1149716954978928, 1.7318035261186269)


PickIntersection: geomIndex = 0

dist:10.92767850911496

ptVW:(−0.5066210416916537, 2.112735307161519, 1.7330744444918968)


Sorted Object 2: Cone


Sorted PickResult 3: PickResult: sgp:javax.media.j3d.Locale@124fb8e : javax.media.j3d.BranchGroup : javax.media.j3d.Shape3D, Box javax.media.j3d.QuadArray@1264877


LocalToVworld Transform:

0.974680683424301, −0.10370092016385303, 0.19810018807842686,

−0.10370092016385303

0.2217376557236817, 0.3341175316108115, −0.9160774460188752, 1.4741175316108115

0.028809328241108344, 0.9368092624581957, 0.3486523029879877,

−0.6631907375418048

0.0, 0.0, 0.0, 1.0


node:javax.media.j3d.Shape3D@1264cfe PickIntersection: geomIndex = 0

dist:12.494425040536017

ptVW:(−0.5914732681836042, 1.9639480320061125, 0.17556762285086336)


PickIntersection: geomIndex = 0 dist:14.587993543333791

ptVW:(−0.6908450104199546, 1.7903467955691152, −1.9084230065569017)


Sorted Object 3: Box


Sorted PickResult 4: PickResult: sgp:javax.media.j3d.Locale@124fb8e : javax.media.j3d.BranchGroup : javax.media.j3d.Shape3D, Cone javax.media.j3d.TriangleFanArray@124fa1a LocalToVworld Transform:

0.974680683424301, −0.19810018807842686, −0.10370092016385302,

−0.2074018403277061

0.2217376557236817, 0.9160774460188752, 0.3341175316108114,

1.8082350632216233

0.028809328241108344, −0.34865230298798766, 0.9368092624581957, 0.2736185249163908

0.0, 0.0, 0.0, 1.0


node:javax.media.j3d.Shape3D@124fa08 PickIntersection: geomIndex = 0

dist:12.494425040536019

ptVW:(−0.5914732681836044, 1.9639480320061125, 0.17556762285086158)


PickIntersection: geomIndex = 0 dist:12.500884811804253

ptVW:(−0.5720301373107639, 1.9989535603646984, 0.16523500707364264)


Sorted Object 4: Cone


Closest PickResult: PickResult: sgp:javax.media.j3d.Locale@124fb8e : javax.media.j3d.BranchGroup : com.sun.j3d.utils.geometry.Sphere, Sphere : javax.media.j3d.Shape3D, Sphere javax.media.j3d.TriangleStripArray@12b486c


LocalToVworld Transform:

0.974680683424301, −0.19810018807842686, −0.10370092016385302,

−0.5185046008192652

0.2217376557236817, 0.9160774460188752, 0.3341175316108114,

2.8105876580540574

0.028809328241108344, −0.34865230298798766, 0.9368092624581957, 3.084046312290978

0.0, 0.0, 0.0, 1.0


node:javax.media.j3d.Shape3D@12b485a PickIntersection: geomIndex = 0

dist:10.31109258625374

ptVW:(−0.503754844446497, 2.138046095717119, 2.3502490354035483)


PickIntersection: geomIndex = 0 dist:10.315735064224192

ptVW:(−0.48806121433886257, 2.1446076441445165, 2.3442903032651294)


PickIntersection: geomIndex = 0 dist:10.311507103034156

ptVW:(−0.46680214250863505, 2.1403178766932185, 2.3478813387527073)


PickIntersection: geomIndex = 0 dist:8.737141773923474

ptVW:(−0.41919205110931124, 2.265854783380931, 3.916754614302066)


PickIntersection: geomIndex = 0 dist:8.771580342395431

ptVW:(−0.41919205110931124, 2.265854783380931, 3.916754614302066)


PickIntersection: geomIndex = 0 dist:8.732273133281984

ptVW:(−0.41290180559136586, 2.275910225691348, 3.9205080490411017)


PickIntersection: geomIndex = 0 dist:8.73669779993455

ptVW:(−0.4106277895151771, 2.2691852339960756, 3.916514821486335)


Closest Object: Sphere


Note that multiple intersections can be reported because the pick ray used for intersection testing actually has a width (tolerance). The tolerance makes it easier for users to pick small objects or lines at the expense of absolute accuracy. You should also note that generating all the picking information in the preceding code is computationally quite expensive, so you should use simple BOUNDS picking whenever possible, unless you need to know the exact location within a shape that was picked.


A method to generate the picking output is shown in the following example:


 

From VrmlPickingTest.java