jme3 ray casting

Need some help on ray casting part where a mouse or cam point into the scene.  I just want to get the object name and the location point where mouse hits.



Not sure of the name or the term to say it.

-ray casting

-tracing

-picking



I just need simple example how to get the point or object select in the scene.

Actually i don't use wrappers for jbullet, I directly call the methods.



   private void updateGroundInfo() {
      Vector3f pos = this.ply.getPosition();
      javax.vecmath.Vector3f ppos = new javax.vecmath.Vector3f(pos.x,pos.y,pos.z);
      javax.vecmath.Vector3f epos = new javax.vecmath.Vector3f(pos.x,pos.y,pos.z);
      epos.y -= 2;
      RayResult res = new RayResult(ply.physic);
      SSolarSystem.getPspace().rayTest(ppos, epos, res);
      this.onground = res.hit;
      if(res.hit){
         this.hitnormal.x = res.hitnormal.x;
         this.hitnormal.y = res.hitnormal.y;
         this.hitnormal.z = res.hitnormal.z;
                                          this.hitnormal.normalizeLocal()
         System.out.println(this.hitnormal);
      }else{
         this.hitnormal.x = 0;
         this.hitnormal.y = 1;
         this.hitnormal.z = 0;
      }
   }


class RayResult extends CollisionWorld.RayResultCallback{
   private CollisionObject filter;
   public RayResult(CollisionObject filter){
      this.filter = filter;
   }
   
   public boolean hit = false;
   public javax.vecmath.Vector3f hitnormal;
   
   @Override
   public float addSingleResult(LocalRayResult arg0, boolean arg1) {
      if(arg0.hitFraction > 0.1 && arg0.collisionObject != filter){
         this.hitnormal = arg0.hitNormalLocal;
         hit = true;
      }
      return 1;
   }
   
}

Well all terms are right ^^



You can do ray traces against a single geometry in jme3 when i last checked, and have tow rite your own method to use it for a whole scene. Btw if you use JBullet i suggest to use the jbullet rays, as they have the advantage of the jbullet optimisations, and offer a elegant way between grafical triangle tracing and bounding box tracing (as physic models are usually lower versions of the grafical one)

Empire Phoenix said:

Btw if you use JBullet i suggest to use the jbullet rays, as they have the advantage of the jbullet optimisations, and offer a elegant way between grafical triangle tracing and bounding box tracing (as physic models are usually lower versions of the grafical one)

I didnt implement bullet ray collision shapes in jme3 physics yet, did you make a wrapper class for that? :)

I found a bug in the system actually. Transforms are not being accounted for… So ray collision is dysfunctional :confused: I am working on a fix atm

Empire Phoenix said:

Actually i don't use wrappers for jbullet, I directly call the methods.

Ok. You know that this kind of code will be broken later in the native version of jme3 physics? The jbullet objects should not be used directly.
Cheers,
Normen
Momoko_Fan said:

I found a bug in the system actually. Transforms are not being accounted for.. So ray collision is dysfunctional :/ I am working on a fix atm


The collision results also never contains the geometry object?

- Mikkel

So I have wait for a ray casting to work or something. Not sure how code since I don't understand how it coded. a Simple example would be nice.

Well I posted the way I use it.



Well I can however adapt your way to directly access the bullet library then^^



Faster it is, because of no synchronizing, of course it is only single threaded then, but it is intended to work that way for me, as I want to run multiple Servers with physic on a multi cpu computer.

Empire Phoenix said:

Well I posted the way I use it.

Well I can however adapt your way to directly access the bullet library then^^

Faster it is, because of no synchronizing, of course it is only single threaded then, but it is intended to work that way for me, as I want to run multiple Servers with physic on a multi cpu computer.

To adapt to that way you'd have to recompile the native binary each time, on all platforms you want to release to ;)
No syncing? So you dont move any spatials? Jme3 physics has multithreaded support, even detached. The two ways are outlined in SimpleBulletApplication and more PhysicsSpaces can be created on separate threads.

Empire Phoenix, I not sure how the code work that you pasted.

So you dont move any spatials?



Actually no, my server who calculates the physic has no complete scene graph, it just uses Nodes to convert local to owrld positions and save some states about objects.

Darknet said:

Empire Phoenix, I not sure how the code work that you pasted.

Best wait until the normal ray picking bug is fixed, see momokos post.

I manage to look around the forums. But I came in the dead end. Not sure what wrong with the coding. I got two object and one them not detecting mouse ray check on top cube.






import org.lwjgl.input.Mouse;
import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.binding.BindingListener;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

public class MouseRayHitMeshObject00 extends SimpleApplication implements BindingListener{
   public Geometry boxpoint = new Geometry("blue cube",new Box(Vector3f.ZERO, 0.1f, 0.1f, 0.1f));
   
       public static void main(String[] args){
          MouseRayHitMeshObject00 app = new MouseRayHitMeshObject00();
          app.setShowSettings(false);//disable config for start up
           app.start();
       }
   
       @Override
       public void simpleInitApp() {
          Material mat = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
          mat.setColor("m_Color", ColorRGBA.Blue);
          
          Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
          mat1.setColor("m_Color", ColorRGBA.White);
          
          Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
          mat2.setColor("m_Color", ColorRGBA.Green);
          
           Box b = new Box(Vector3f.ZERO, 1, 1, 1);
           Geometry box = new Geometry("blue cube", b);
           box.setModelBound(new BoundingBox());
           box.setMaterial(mat);
           rootNode.attachChild(box);
          
           Box b1 = new Box(Vector3f.ZERO, 1, 1, 1);
           Geometry box1 = new Geometry("blue cube 2", b1);
           box1.setLocalTranslation(new Vector3f(0,3,0));
           box1.setMaterial(mat2);
           rootNode.attachChild(box1);
          
           boxpoint.setMaterial(mat1);
           rootNode.attachChild(boxpoint);
          
          //this enble mouse cursor to show up
          flyCam.setDragToRotate(true);
          inputManager.setCursorVisible(true);

          initKeys();
       }
      
       private void initKeys() {
           inputManager.addBindingListener(this);
       }
      
       /** Custom Keybinding: Configure the action triggered by a binding */
       public void onBinding(String binding, float value) {
          if( binding.equals("FLYCAM_RotateDrag") ) {
             CheckMeshInterset();
           }
       }
      
       public void CheckMeshInterset(){
          
          Vector2f mousePos = new Vector2f();
          mousePos.x = Mouse.getX();
          mousePos.y = Mouse.getY();
          
          Vector3f worldCoords = cam.getWorldCoordinates(mousePos, 0);
          Vector3f worldCoords2 = cam.getWorldCoordinates(mousePos, 1);
           // Create a ray starting from the camera, and going in the direction
          Ray mouseRay = new Ray(worldCoords, worldCoords2.subtractLocal(
                    worldCoords).normalizeLocal());

          CollisionResults results = new CollisionResults();
          rootNode.collideWith(mouseRay, results);
          
          for (int i = 0; i < results.size(); i++){
             float dist = results.getCollision(i).getDistance();
             Vector3f pt = results.getCollision(i).getContactPoint();
             System.out.println("distance: "+dist);
               System.out.println("point: "+pt);
               boxpoint.setLocalTranslation(pt);
              
               CollisionResult result = results.getClosestCollision();
               System.out.println("point:"+result.getGeometry());
          }
       }

      @Override
      public void onPostUpdate(float arg0) {
         // TODO Auto-generated method stub
      }

      @Override
      public void onPreUpdate(float arg0) {
         // TODO Auto-generated method stub
      }
}



The blue cube works and display the white cube of the location hit. The green cube doesn't work. Not sure if I coded right.
Darknet said:

I manage to look around the forums. But I came in the dead end. Not sure what wrong with the coding. I got two object and one them not detecting mouse ray check on top cube.



           Geometry box1 = new Geometry("blue cube 2", b1);
           box1.setLocalTranslation(new Vector3f(0,3,0));



The blue cube works and display the white cube of the location hit. The green cube doesn't work. Not sure if I coded right.


It seems to be the same issue I see. Transformations are not handled properly with regards to ray casting, as one of the developers stated earlier in this thread. I'm not sure what the progress is on this though. I saw a checkin in the svn history that indicated that some fix had been made with regards to CollisionResult and Geometry param, but still the detection is broken.