Ray question

Hello everybody



How can i find the exact coordinates of the collision of a ray and a trimesh ? ( i have a ray and i want to calculate its collision

coordinates with an instance of TerrainBlock )

i cant find a suitable method for this in Ray , Trimesh or Triangle classes .



thanks

If you are just testing against the TriMesh you can do it like this:


Ray r = new Ray(new Vector3f(0,0,0),new Vector3f(1,0,0));
TrianglePickResults tpr = new TrianglePickResults();
terrain.findPick(r, tpr);
if (tpr.getNumber()>0) // was there an intersection?
{
  Vector3f intersectionPoint = ((TrianglePickData)tpr.getPickData(0)).getIntersectionPoint();
}


This method doesnt work me , intersectionPoint is always zero ( 0.0,0.0,0.0)

however i did it another way ( finding the triangle and then computing the middle  point from three vertices )



thanks

but you are using findPick?!? On the trimesh or the terrain?



Cause if you use a node(like TerrainPage or similar) the intersectionPoint is not working reliable. But as you seem to get the triangle it is ok.



BTW: The middlepoint is not necessarily the intersectionPoint. For small triangles this might be no problem, better use:

Vector3f intersectionPoint=new Vector3f();
ray.intersectWhere(v0, v1, v2, intersectionPoint)



Where v0,v1,v2 are the triangle's vertices!

I first used the findPick on terrain , didnt work and now im using getTrianglePick method of the TerrainBlock and is working fine  .

any ideas why findPick always gives 0 ?

Actually no,…as findPick is calling findTrianglePick internally.

if you can rewrite the code as it didn't work out, I can have a look.

yes here it is :

tb is an instance of TerrainBlock


      if (MouseInput.get().isButtonDown(0)) {
            Vector2f screenPos = new Vector2f();

            screenPos.set(am.getHotSpotPosition().getX(), am.getHotSpotPosition().getY());

            Vector3f worldCoords = display.getWorldCoordinates(screenPos, 0);
            Vector3f worldCoords2 = display.getWorldCoordinates(screenPos, 1);


            Ray mouseRay = new Ray(worldCoords, worldCoords2.subtractLocal(worldCoords).normalizeLocal());

            TrianglePickResults pr = new TrianglePickResults();

            tb.findPick(mouseRay, pr);
            Vector3f intersectionPoint;
            if (pr.getNumber() > 0) {
                intersectionPoint = ((TrianglePickData) pr.getPickData(0)).getIntersectionPoint();


                tb.addHeightMapValue((int) intersectionPoint.getX(), (int) intersectionPoint.getY(), -0.3f);
             
                tb.updateFromHeightMap();
                System.out.println(intersectionPoint);
            }
          
        }

Strange, looks good for me! If the ray is heading towards the terrainblock (and it seems to work as you tested it with findTrianglePick)



You could check if there are more than one results…but actually that shouldnt be possible…Hmm. Differs from the angle.



Try:

pr.setCheckDistance(true);




Hmm,...nevertheless without the same model and a real test-case its hard to find the problem. But as long as you found a suitable way :D

Keep on rocking

thank you very much ttrocha



pr.setCheckDistance(true);



this line did the trick its ok now  :roll:



but i dont understand why i should call this on pr as pr has only one result in it . I dont understand its comment .


Well, that was the cause I didnt use it. it is possible the internal intersection is only set during the

sort of the results as intersectionPoint. I have to check this

May i ask you another question ?



Is there anyway to bound half of the vertices of a trimesh to a model bound and the other half to another bound ?

is this possible ?



thanks

Hmm,…well not automatically! The question is what is the half. Can you give an example for

the usecase? Do you have a loaded model or do you still talk about the terrain. Even normally

one TriMesh has only one BoundingVolume noone prevents you from creating another one (and

save this somewhere else) If you e.g. would have a cube you could first calculate the bounding-

volume and then derive two different from this.

But if you e.g. have a model that you created in a modeller it would be the easiest way to split the

mesh into two…which would result in two different boundingvolumes automatically

Actually i want to create a huge terrain and perform editting on it . i have to ways 1- make the huge terrain consisting of

many smaller terrain blocks and then all of those have bounding boxes and i gain the performance gain as described in

the beginner tutorials but this will complicate the task of editting terrain 2-  make a huge block and then perform editting on

it and then splitting it somehow and then give each block a bounding box . if the latter is possible the code will be much

easier to write .

That already exists. TerrainPage is the class you need! It is a structure where at the leafs

again smaller trainpages of the Heightmap are created. Have a look here:



jmetest.terrain.TestTerrainPage



The call is similar to the TerrainBlock with some additional parameters.

oh nice class

thanks