MousePicking (TriMesh)

Hi forum,



sad to say, but i've got again a mouse picking problem.

At this moment I'm able to select a TriMesh (which has the shape oh a triangle (thats all I need)) and change the color of the chosen triangle (TriMesh). BUT it evens changes colors, when i click in it's bounds, whithout hitting the "real" triangle. How can I solve this? I want to avoid this triangleMousePicking, because I've got an example (which works) but I dont understand it. It would be great to be able to select a TriMesh but only if there's more than the bounding box.



thanks



Frantic



here's the code i'm using at this moment:



            if (MouseInput.get().isButtonDown(0)) {
                // Get the position that the mouse is pointing to
                Vector2f screenPos = new Vector2f();
                screenPos.set(am.getHotSpotPosition().x, am.getHotSpotPosition().y);
                // Get the world location of that X,Y value
                Vector3f worldCoords = aDisplaySystem.getWorldCoordinates(screenPos, 0);
                Vector3f worldCoords2 = aDisplaySystem.getWorldCoordinates(screenPos, 1);
                // Create a ray starting from the camera, and going in the direction
                // of the mouse's location
                Ray mouseRay = new Ray(worldCoords, worldCoords2.subtractLocal(
                                worldCoords).normalizeLocal());
                // Does the mouse's ray intersect the box's world bounds?

                results = new TrianglePickResults();
      results.setCheckDistance(true);
      results.clear();

                rootNode.calculatePick(mouseRay, results);

                for (int i = 0; i < results.getNumber(); i++)
                   ((TriMesh)results.getPickData(i).getTargetMesh()).setRandomColors();
                }
            }
        }

Hehe,…I had the same problem once. The thing is that hasNumber() returns even numbers if you just hit the boundingbox. So you have to do an additional call:


if (results.getPickData(i).getTargetTris().size()>0) {....}



This should solve your problem....

Thanks a lot, i love those easy solutions :smiley:

It works!!!



But… What I did is, i created a Sphere, and replaced every Triangle of the Sphere with a TriMesh-triangle, and deleted the Sphere afterwards. So i just needed the Sphere to calculate the Positions of my TriMesh-triangles.



If I use this MousePicking Code above with you extension, I'm able to select most of this TriMeshes, but not all, there always a few which I can't select, does someone have an idea to solve this? I'm bit confused :smiley:



Thanks again, Frantic



Here's my Code for Mousepicking:


           if (MouseInput.get().isButtonDown(0)) {
                // Get the position that the mouse is pointing to
                Vector2f screenPos = new Vector2f();
                screenPos.set(am.getHotSpotPosition().x, am.getHotSpotPosition().y);
                // Get the world location of that X,Y value
                Vector3f worldCoords = aDisplaySystem.getWorldCoordinates(screenPos, 0);
                Vector3f worldCoords2 = aDisplaySystem.getWorldCoordinates(screenPos, 1);
                // Create a ray starting from the camera, and going in the direction
                // of the mouse's location
                Ray mouseRay = new Ray(worldCoords, worldCoords2.subtractLocal(
                                worldCoords).normalizeLocal());
                // Does the mouse's ray intersect the box's world bounds?

                results = new TrianglePickResults();
      results.setCheckDistance(true);
      results.clear();

               rootNode.calculatePick(mouseRay, results);

                for (int i = 0; i < results.getNumber(); i++) {
                    if (results.getPickData(i).getTargetTris().size()>0) {
                        ((TriMesh)results.getPickData(i).getTargetMesh()).setRandomColors();
                    }
                }
            }



and here's my Code for Creating the TriMesh-Triangles:


        Sphere s = new Sphere("mySphere", new Vector3f(-5,5,0), 8,8,4);
        s.setModelBound(new BoundingBox());
        s.updateModelBound();

        // Normal directions for each vertex position
        Vector3f[] normals = {
                new Vector3f(0, 0, 1),
                new Vector3f(0, 0, 1),
                new Vector3f(0, 0, 1),
        };
        // Color for each vertex position
        ColorRGBA[] colors = {
                new ColorRGBA(1, 0, 0, 1),
                new ColorRGBA(1, 0, 0, 1),
                new ColorRGBA(0, 1, 0, 1),
        };
        // Texture Coordinates for each position
        Vector2f[] texCoords = {
                new Vector2f(0, 0),
                new Vector2f(1, 0),
                new Vector2f(0, 1),
        };
        int[] indexes = { 0, 1, 2 };

        for(int i = 0; i< s.getTriangleCount(); i++){
            Vector3f[] mystorage = new Vector3f[3];
            s.getTriangle(i, mystorage);

            TriMesh aTriangle = new TriMesh(
                ((Integer)i).toString(),
                BufferUtils.createFloatBuffer(mystorage),
                BufferUtils.createFloatBuffer(normals),
                BufferUtils.createFloatBuffer(colors),
                TexCoords.makeNew(texCoords),
                BufferUtils.createIntBuffer(indexes));
            aTriangle.setModelBound(new BoundingBox());
            aTriangle.updateModelBound();

            rootNode.attachChild(aTriangle);
        }



(Im dont even think i need this normals and colors buffers at all :D)

Well, for selecting single Triangles of a model you don't have to break the model into TriMeshs.

If you use your code the calculatePick will add every Triangle that is picked by the ray into the TrianglePickResult.

That means you can find the numbers of that triangles with the getTargetTris(). Once you have the number you can use getTriangle(nr,float[] pos) on the the TriMesh and will get the coordinates in pos-array. This you can use to create one on the fly with your color.



In jmetest there is a similar example: jmetest.intersection.TestTriangleTest



Have fun