TriMesh.findTrianglePick()

There is a problem with TriMesh.findTrianglePick() which I tried to get the height over ground. The object is found by Node.findPick() and that works fine as far as I could see.



downRay is a ray pointing from the cam location downwords, rayIntersectsTriangle() is used to get the t, u, v of the intersection point of a ray on a triangle



The following code failed from time to time:



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

ArrayList<Integer> tris = new ArrayList<Integer>();

mesh.findTrianglePick(downRay, tris);

if (tris.size() > 0)

{

This: http://www.jmonkeyengine.com/jmeforum/index.php?topic=1859.msg15701#msg15701 might be related. Unfortnately, right now nobody seems to have time/answers for this…

It looks like we have the same problem, yes. As I'm deep into trying to get the basics of a FPS-type game going, I use the second version that just scans all triangles for the time being. It works pretty fast for me which is very important as I have to check the height over ground with each step the character does.



This is the rayIntersectsTriangle function I use:



// some variables for intersection testing

    final float EPSILON = 0.000001f;

    Vector3f edge1 = new Vector3f();

    Vector3f edge2 = new Vector3f();

    Vector3f tvec = new Vector3f();

    Vector3f pvec = new Vector3f();

    Vector3f qvec = new Vector3f();

    /*

    * return value is not really a Vector3f with x,y,z !

    * x is the distance, y,z are really u,v in the plane of the triangle

    */

public Vector3f rayIntersectsTriangle(Vector3f origin, Vector3f direction, Vector3f triangle0, Vector3f triangle1, Vector3f triangle2)

    {

            Vector3f intersection = new Vector3f();

            float det, inv_det;

            float t, u, v;



            // find two edges sharing vertex 0

            edge1.set(triangle1.subtract(triangle0));

            edge2.set(triangle2.subtract(triangle0));



            // begin calculating determinant - also used to calculate u

            direction.cross(edge2, pvec);



            // if determinant is near zero, ray lies in plane of triangle

            det = edge1.dot(pvec);



            if (det > -EPSILON && det < EPSILON)

                    return null;

            inv_det = 1.0f / det;

            // calculate distance from vertex 0 to ray origin

            tvec.set(origin.subtract(triangle0));



            // calculate u and test bounds

            u = tvec.dot(pvec) * inv_det;

            if (u < 0.0f || u > 1.0f)

                    return null;



            // prepare to test v

            qvec=tvec.cross(edge1);



            // calculate v and test bounds

            v = direction.dot(qvec) * inv_det;

            if (v < 0.0f || (u + v) > 1.0f)

                    return null;



            // calculate t, scale parameters, ray intersects triangle

            t = edge2.dot(qvec) * inv_det;



            intersection.set(t, u, v);

            return intersection;

    }





The returned t (x in the "vector") is the distance between the origin and the intersection point.

I need this value to keep the character on the ground.