# PickResult causes infinity (again)

Hi,

I found several threads about this problem, but none could solve it clearly. I tried many things like updating the CollisionTree, updating world and modelBounds and so on but nothing works. So I build the problem in the shortest code I was able to make.

The problem is in the PickResult. getDistance causes infinity very often. I think it's because the boundingBox doesn't move or rotate so that the ray intersects the boundingBox but cannot find any triangle.

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.curve.PolylineCurve;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;

public class Init extends SimpleGame
{
Vector3f vecs[] = {new Vector3f(0,0,20), new Vector3f(0,0,-20)};
TrianglePickResults result = new TrianglePickResults();
Ray ray = new Ray(vecs[0], vecs[1]);

Box b;
float rot = 0;

@Override
protected void simpleUpdate()
{
super.simpleUpdate();

result.clear();
rootNode.calculatePick(ray,result);
rot += tpf;

b.getLocalRotation().fromAngles(0,rot,rot);

if(result.getNumber() > 0)
System.out.println(result.getPickData(0).getDistance());
}

@Override
protected void simpleInitGame()
{
b = new Box("box", Vector3f.ZERO,5,5,5);
b.setLocalTranslation(5,5,5);
b.setModelBound(new BoundingBox());
b.updateModelBound();

rootNode.attachChild(b);

PolylineCurve line = new PolylineCurve("Kurve", vecs);
rootNode.attachChild(line);

result.setCheckDistance(true);
}

public static void main(String args[])
{
Init i = new Init();
i.setConfigShowMode(ConfigShowMode.AlwaysShow);
i.start();
}
}

Hola ceiphren,

the thing is that TrianglePickResults have number>0 even when just the boundingvolume is hit

by the ray (and not actually the mesh) und also have to test if there are also really triangles hit.

I remember that I had trouble with that as well. Using this query should solve your problem:

if(result.getNumber() > 0 && result.getPickData(0).getTargetTris().size()>0 )

Hope that helps.

Hi ttrocha,

thanks for the reply. Unfortunately this doesn't solve the problem at all.

The following example shows the problem better:

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.CollisionTreeManager;
import com.jme.curve.PolylineCurve;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;

public class Init extends SimpleGame
{
Vector3f vecs[] = {new Vector3f(5,5,20), new Vector3f(5,5,-20)};
TrianglePickResults result = new TrianglePickResults();
Ray ray = new Ray(vecs[0], vecs[1]);

Box b;
Node n;
float rot = 0;

@Override
protected void simpleUpdate()
{
super.simpleUpdate();

b.getLocalRotation().fromAngles(0,rot,rot);

//going crazy with updating stuff
CollisionTreeManager.getInstance().updateCollisionTree(b);
b.updateModelBound();
b.updateWorldBound();

result.clear();

n.calculatePick(ray,result);
rot += tpf;

if(result.getNumber() > 0 && result.getPickData(0).getTargetTris().size() > 0)
System.out.println(result.getPickData(0).getDistance());

if(result.getNumber() > 0 )
System.out.println(result.getPickData(0).getDistance());
}

@Override
protected void simpleInitGame()
{
b = new Box("box", Vector3f.ZERO,3,3,3);
BoundingBox box = new BoundingBox();
b.setModelBound(box);

b.setLocalTranslation(5,5,5);

b.updateModelBound();
b.updateWorldBound();

n = new Node();
n.attachChild(b);
rootNode.attachChild(n);

PolylineCurve line = new PolylineCurve("Kurve", vecs);
rootNode.attachChild(line);

result.setCheckDistance(true);
}

public static void main(String args[])
{
Init i = new Init();
i.setConfigShowMode(ConfigShowMode.AlwaysShow);
i.start();
}
}

Now there should be an intersection, but the result is just useless.

Well,…actually it do solve THE problem you described. But the thing is you have more than

one problem (in jME?).

Just a hint. Your problem is the rotation.

Have fun

Yes, I guess the problem is not the infinity-value, it is the pickresult itself. I found nearly the same problem here:

http://www.jmonkeyengine.com/forum/index.php?topic=10140.msg77501#msg77501

And as you can see I did what they told but it didn’t work.

I don’t know how your hint can help me. Why is there more than one problem?

Well, you don't have the same problem. They change the mesh-data itselfs which means the coordinates of the vertices are changed. You just rotate the Box itself so you don't need to update the CollisionTree. All you need to do is to update the GeometricState. (which automatically updates wolrstranslation, rotations and also worldbound, and much more)

I think one mistake is the difference between your "ingame" ray-representation and the real ray. Consider that the line you draw is a line from point v1 to point v2 but the ray is starting at point v1 and uses the direction v2 which is most of the time a difference. Here a version that works.

One last thing: The topic collision detection really need some time to get comfortable with. It took me quite a time and much of debugging as well until I really knew what was going on… So keep on fighting!

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.CollisionTreeManager;
import com.jme.curve.PolylineCurve;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;

public class Init extends SimpleGame
{
Vector3f vecs[] = {new Vector3f(5,5,20), new Vector3f(5,5,-20)};
TrianglePickResults result = new TrianglePickResults();
Ray ray = new Ray(vecs[0], new Vector3f(0,0,-1));

Box b;
Node n;
float rot;

@Override
protected void simpleUpdate()
{
super.simpleUpdate();
b.updateGeometricState(0,true);

result.clear();

n.calculatePick(ray,result);
b.getLocalRotation().fromAngles(rot,rot,0);

// just in case you will have more then one objects hit by
for (int i=0;i<result.getNumber();i++)
{
if(result.getPickData(i).getTargetTris().size() > 0)
System.out.println("Hit "+result.getPickData(i).getTargetMesh()+" with distance: "+result.getPickData(i).getDistance());
}
rot += tpf;

}

@Override
protected void simpleInitGame()
{
b = new Box("box", Vector3f.ZERO,3,3,3);
BoundingBox box = new BoundingBox();
b.setModelBound(box);

b.setLocalTranslation(5,5,5);
b.updateModelBound();
b.updateGeometricState(0,true);

n = new Node();
n.attachChild(b);
rootNode.attachChild(n);

PolylineCurve line = new PolylineCurve("Kurve", vecs);
rootNode.attachChild(line);

result.setCheckDistance(true);
}

public static void main(String args[])
{
Init i = new Init();
i.setConfigShowMode(ConfigShowMode.AlwaysShow);
i.start();
}
}

Thank you very much. That solved the problem(s). Now the pickResult works pretty nice.