Getting exact point of intersection of mouse click and terrain page

I'm trying to get the point of intersection of the mouse click and terrain page… So far I've tried using MousePicking, but I don't know where to find the point of the intersection… anyone help?

just use ray detection should be fine.



use hardware mouse, and asign a listener to it. the listener will give the screen coordinates whenever u click.



translate the screen coordinates into world coordinates by using display.getworldcoord.



then cast a ray from the click position into the screen and then u should have an arraylist of collision results.



em…im bad at explaining things, this is a method i wrote. u just need to pass in the ray and the name of the object(or model or whatever) u r looking for, it will return the intersection point.



   /**
    * Find the intersection of the calling object and the object with given name in the direction
    * defined by the given Ray. If the returned value is (0, 0, 0), that means it did not
    * find any results.
    * @param ray The ray defines the direction of searching.
    * @param targetName The name of the model which is being looked for.
    * @return A Vector3f which defines the intersection point.
    */
   protected static Vector3f findBounding(Ray ray, String targetName) {
      Vector3f intersection = new Vector3f();
      PickResults results = new BoundingPickResults();

      // Use the ray to find all the models on the player's island which are hit by the ray.
      results.clear();
      player.getIsland().findPick(ray, results);
      
      // Find the target model in the results.
      boolean found = false;
      boolean hit = false;
      for(int i = 0; i < results.getNumber() && found == false; i++)
      {
         TriMesh model = (TriMesh)results.getPickData(i).getTargetMesh().getParentGeom();
         if(model.getName().equalsIgnoreCase(targetName))
         {
            found = true;
            // Find the intersection where the ray hits the target's boundingBox.
            Vector3f[] vertices = new Vector3f[3];
            for(int j = 0; j < model.getTriangleCount() && hit == false; j++)
            {
               model.getTriangle(j, vertices);
               hit = ray.intersectWhere(
                     vertices[0].addLocal(model.getLocalTranslation()),
                        vertices[1].addLocal(model.getLocalTranslation()),
                           vertices[2].addLocal(model.getLocalTranslation()), intersection);
            }
         }
      }
      // Return the intersection.
      return intersection;
   }

player.getIsland().findPick(ray, results);

change this line to

terrainNode.findPick(ray, results);



then u should be fine~ :smiley:

Yay!!!  :smiley:



Edit: Would I use this line to get the Ray from the Mouse to the terrain I'm looking at?



      Ray ray = new Ray(am.getLocalTranslation(), cam.getDirection());

skyuzo said:

Yay!!!

am is AbsoluteMouse

to create a ray, all u need is a starting position and a direction.



so what u should do its simply find the mouse world coordinates and use this as the starting position.



then u create a new vector which has the same x and y coordinates but +1 z coordinates. this means that the second vector is 1 unit inside the screen and the original mouse world coordinate is right on the screen.



then u use the section vector subtract the original one to get the vector which starts at the original vector point, but pointing to the second vector.

and then u normalize this resulted vector to make it a unit vector which can be used to indicate a direction.



so here u go, u have the starting point and the direction, then u can create ur ray which starts at where the mouse is clicked and going inside the screen.

skyuzo said:

am is AbsoluteMouse


u dont need to use absolute mouse. coz hardware mouse is faster and it does the same thing~ :D

one disadvantage is that u can only set the cursor of the mouse, but u cant do any editional editing to it inside jme. such as resize, and all those states.

coz basically an absolutemouse is just a spatial with its screen coordinates stored in it. so u can do whatever u can do to a spatial to it.

but harwaremouse is the mouse u use in ur operating system which i assume is windows XD so its faster, but u cant do any editing to it.
howerev, u can always edit the texuture(the cursor) in photoshop or whatever. i personally think its better that way :D

Is this correct?




      Vector2f mo = new Vector2f(MouseInput.get().getXAbsolute(),
                           MouseInput.get().getYAbsolute());
      Vector3f mouse = new Vector3f(mo.x, mo.y, 0.0f);
      Ray ray = new Ray(mouse, mouse.add(new Vector3f(0,0,1f)));



Edit: oh wait...

Edit: argh.. the ray never intersects with the terrain.. maybe it is because I set the camera to face a different direction... I dont know  :?


float mx = MouseInput.get().getXAbsolute();
      float my = MouseInput.get().getYAbsolute();
      Vector3f mouse3d = cam.getWorldCoordinates(
                        new Vector2f(mx, my), 0.0f);
      Vector3f to = mouse3d.add(new Vector3f(0,0,1f));
      Vector3f direction = to.subtract(mouse3d).normalize();
      Ray ray = new Ray(mouse3d, direction);

ok, u need a mouse listener first.



check out the MouseInputListener class.

create ur own mouselistener class which implements the MouseInputListener class.



then u add ur listener to the hardware mouse.


      // Assign mouse to a listener.
      listener = new MyMouseListener();
      MouseInput.get().addListener(listener);



the methods in mouse listener class gets called whenever a mouse action happens, like click, move, scroll.
so in ur mouse listener class, when the onButton method gets called, u check if the correct button was pressed and if true, u store the x, y value.
and in addition, u add a method which returns the x y values. lets call it getScreenCoords().

so to create the ray u do this


ROFL! the thing I was doing wrong was that when I use TerrainPage, the name of the node returns something like terrainPage2Page3Page3Block3, so the name wasn't equal and there was no collision… I'll just modify your method to fit my needs…  :smiley:



Edit: Still not working… hmm…



Edit: apparently, it is found but it never hits anywhere…  :expressionless:



Edit: Woohoo!! it worked when i changed



                model.getTriangle(j, vertices);
                hit = ray.intersectWhere(
                      vertices[0].addLocal(model.getWorldTranslation()),
                      vertices[1].addLocal(model.getWorldTranslation()),
                      vertices[2].addLocal(model.getWorldTranslation()), intersection);



Thanks for the help!

sry for not noticing that.



coz when i look for the intersection, im always looking for the intersection in a part of scene graph. each part has its own localtranslation, so i barely use worldtranslation.

but ur terrain is directly under the rootnode. so if u look for the localtranslation the method was just looking under the terrain node's local which doesnt have anything.



glad i can help~ :wink: