# Picking

Bounding based picking has a handy distance sort routine that will take all ray-picked items and sort them by distance.  This is great, except that the distance is calculated by the closest bounding edge to the ray origin which is quite often not correct, especially if you have a large object and a small object.  So I've added an intersectsWhere method to Boundings that will give you the point (or points) where a ray intersects a Bounding as well as the distances to them from the ray's current origin  (so you don't have to recalc those distances, wee!!)  This data is stored in a new class called IntersectionRecord.

In any case, picking now uses this method to do distance sorting and the result is much more accurate bounds picking behavior most noticable in crowded scenes.  Should be in cvs shortly.

In cvs.

i gotta rethink what people need, i implemented this 8 months ago…

That's alright, the boolean check test was fixed to be faster in the process and it didn't take all that long to do.

llovely, at least something good came out of my error

any suggestion with triangle based picking in current cvs? my current code based on version 0.10 does not work anymore.

```private PickResults results = new TrianglePickResults() {              MathUtil it = new MathUtil();              public void processPick() {                    for (int i = 0; i < getNumber(); i++) {                            Vector3f[] vertices = new Vector3f[3];             Ray lineOfSight = getPickData(i).getRay();                          ArrayList al = getPickData(i).getTargetTris();             TriMesh mesh = (TriMesh)getPickData(i).getTargetMesh();                          for (int j = 0; j < al.size(); j++) {                int triIndex = ((Integer) al.get(j)).intValue();                mesh.getTriangle(triIndex, vertices);                                it.rayIntersectsTriangle(                      lineOfSight.origin.subtract(mesh.getWorldTranslation()),                      lineOfSight.direction,                      vertices[0],                      vertices[1],                      vertices[2]);                                                try {                   Vector3f sceneTarget = it.getLastIntersectionVector().add(mesh.getWorldTranslation());                                      fireObjectPickEvent(mesh, sceneTarget);                } catch (RuntimeException ex) {                   Logger.getLogger("engine").warning("no object data found");                }                             }          }       }    };```

This code is used to position the ball over the terrain in my demo at http://jxg-tech.mi-studios.de/

Though that subclassing is pretty unconventional imo, that code in the processPick method should still work from a short glance at it. What does not work any more?

Btw. your demo just gives me a black screen for a while and then crashes:

```org.lwjgl.opengl.OpenGLException: Invalid value (1281)         at org.lwjgl.opengl.Util.checkGLError(Util.java:56)         at org.lwjgl.opengl.Display.update(Display.java:569)         at com.jme.renderer.lwjgl.LWJGLRenderer.displayBackBuffer(Unknown Source)         at com.jme.app.BaseGame.start(Unknown Source)         at de.mistudios.jxg.RunCore.<init>(Unknown Source)         at de.mistudios.jxg.RunCore.main(Unknown Source) ```

(Linux on P4, JDK1.5)

Oh, sorry, Linux is at this moment not tested…

`TriMesh mesh = (TriMesh)getPickData(i).getTargetMesh();`

give me an error on compile.

getPickData(i).getTargetMesh() returns GeomBatch in the new version.

Previews that returns TriMesh...  :?

I don't understand the GeomBatch class

oh, yeah, simply add .getParentGeom()

mesh.getParentGeom().getTriangle(triIndex, vertices);

undefined for type Geometry  :’(

Geometry does not have that method, right. It did not have it before. That's why you were casting to TriMesh, isn't it? If you are sure that you hit TriMeshes keep it that way. All you have to change in the above posted code is replacing

``` TriMesh mesh = (TriMesh)getPickData(i).getTargetMesh();```

with

``` TriMesh mesh = (TriMesh)getPickData(i).getTargetMesh().getParentGeom();```

OK, it's so easy.  :roll:

OK Its fixed… my demo runs at 11 FPS. Oh No…

With version 0.10 release it runs at 180FPS.

grrrrrr…

all object are rendered… no culling or clipping…

:-o

i go back to the release version 0.10. dont understand all the changes in current cvs.  ://

ok. i try a little bit  8)

and the reason is…

i change

trees.setCullMode(Spatial.CULL_NEVER);

to

trees.setCullMode(Spatial.CULL_DYNAMIC);

and this on all other objects in the scene.

And now… we get 200FPS,

but no physics. it reports me an error on compile my source after change to CVS-Version.

java.lang.NoSuchMethodError: com.jme.scene.TriMesh.getIndexBuffer()Ljava/nio/IntBuffer;

at org.odejava.GeomTriMesh.<init>(Unknown Source)

at com.jmex.physics.PhysicsEntityFactory.createTriMesh(Unknown Source)

at com.jmex.physics.PhysicsEntityFactory.createGeom(Unknown Source)

at com.jmex.physics.PhysicsEntityFactory.createEntites(Unknown Source)

at com.jmex.physics.StaticPhysicsObject.<init>(Unknown Source)

at com.jmex.physics.StaticPhysicsObject.<init>(Unknown Source)

its only on StaticPhysicsObject's

i patch the current cvs-version of physics 1 an it works…

thanks @ all

Another big fix in CVS is locking for shared objects works much better.

So, you should lock your terrain and your trees and get another performance boost.

ok,

tree.lock();

and

terrain.lock();

and 10fps more.

I would suggest only lcokBounds and lockTransforms on the Terrain…  VBO and Display Lists do not mix well on some cards.

Ok i change it to this only on my terriainnode

Ray-Picking changed recently. I didn't have a close look on the cause yet, but I get all my 10000 SharedMeshes picked and sorted for each Ray :-o (which is quite slow :|) since I updated cvs…

I'll try to figure out why (wasn't able to reproduce it in HelloMousePick, yet) - maybe someone already has an idea?

Tracked it: it's the BoundingSphere: Ray-BoundingSphere seems to collide always :-o (change HelloMousePicking to bound by sphere to see the effect)