Mouse Pick for multiple object

hello ervery body,

Here, i want to make game like common RTS game. I have two or more object. To make easy, suupose that i have two object terrain and house. I put house on terrain. I try to check pick on terrain with TrianglePickResults. it's  my code :


public class CheckMousePicking extends TrianglePickResults{
   private boolean isObjectClicked=false;
   private Vector3f objectLocation=null;
   @Override
   public void processPick() {
      // TODO Auto-generated method stub
      super.processPick();
      if (getNumber() > 0) {
         for (int num = 0; num < getNumber(); num++) {
            PickData pData = getPickData(num);
            List<Integer> tris = pData.getTargetTris();
            TriangleBatch mesh = (TriangleBatch) pData.getTargetMesh();
            for (int i = 0; i < tris.size(); i++) {
               int triIndex = tris.get( i );
               Vector3f[] vec = new Vector3f[3];
               mesh.getTriangle(triIndex, vec);
               [b]objectLocation = vec[0];[/b]
            }
            isObjectClicked=true;
         }   
      }
   }
   public void setIsObjectClicked(boolean isObjectClicked){
      this.isObjectClicked=isObjectClicked;
   }
   public boolean isObjectClicked(){
      return this.isObjectClicked;
   }
   public Vector3f getObjectLocation(){
      return this.objectLocation;
   }

}



  • it's work well to check if terrain pick or not. BUt the result doesn't accurate. There are some error, mainly if camera near to terrain( mean that camera only capture little triangle ). Are there any others better method to check pick?

  • it's difficult for me to differ the object clicked. Is Terrain or house?At my code above i try to use function

isObjectClicked()

    . But when i click house area, the result is house= true and terrain =true.Because  (i think ) there are any area at house which overlap with terrain area

 

To determine the object hit, you can test for Type



for(int pickIndex = 0; pickIndex < results.getNumber(); pickIndex++) {
   TriMesh mesh = (TriMesh) results.getPickData(pickIndex).getTargetMesh().getParentGeom();
         
   if(mesh instanceof JointMesh) {
      doDetectModel(mesh);
      return;
   } else  if(mesh instanceof Terrain) {
      doDetectTerrain(mesh);
      return;
   }

That great idea, But it don't work well. It can chect type of terrain Block.But for check Node it can't.There are error "incompatible type" . How to cast trimesh to Node?incompatible type

And that is correct as a node is not a TriangleMesh.



Presuming your house is a Node, you need to find what the geometry is within the house node. If it is a model, it more than likely is a jointMesh. If so, you can then nest from instanceof JointMesh to test whatever you can to determine what the jointMesh is. Using mesh.getName() for instance may help if you call your houses individual names. Either way you need something to determine what it is. You may also need to keep recursing over getParentGeom as your model may be made of many parts eg door has a parent named frame which has a parent named wall which has a parent named exterior which has a parent named myHouse1





The easiest way for you to understand what type you need to pick is to put a debug after getting pick results back and seeing what the results are, keep drilling down under the parentgeom.


sorry theprism, i can't understand u'r suggestion above. Would you mind re explaining for me with give some example?Sorry i am so stupid to understand what u said. :x

SceneGraph elements are made up from Spatials. Geometry and Node extend Spatial. TriMesh extends Spatial not Node. The pick results are TriMeshes.



Try this, it may help you understand what the pick results are and where you can determine if the user picked on your house





for(int pickIndex = 0; pickIndex < results.getNumber(); pickIndex++) {
         TriMesh mesh = (TriMesh) results.getPickData(pickIndex).getTargetMesh().getParentGeom();
         Spatial s = (Spatial)results.getPickData(pickIndex).getTargetMesh().getParentGeom();
         while(s.getParent() != null) {
            if(s instanceof Node) {
               System.out.println(" a node named " + s.getName());
            }
            s = s.getParent();
           
         }






Yes, It great!I can detect hitting object by differ the type. Thank for u helping. XD

The above code is highly unoptimised, you should detail the types to in if else blocks and return from the loop as soon as you can…

Be sure to check out this thread as well: jME forum link



Lists some interesting ways of solving the same problem. I especially like the inheritance approach.