Collidable geometry

i need collide geometry

                        shootables.collideWith(area, results);

but i have error geometry is not implements collidable
i search in forum next example

PhysicsNode cubeNode= new PhysicsNode(cubeGeom, new BoxCollisionShape(new Vector3f(1.0f, 1.0f, 1.0f)),1.0);

but i cant import PhysicsNode class (deprecated?)

how to collide geometry?

Are you sure? Geometry extends Spatial which implements Collidable.

Other possibilities are AbstractTriangle/Triangle, BoundingVolume/BoundingBox/BoundingSphere, Ray and SweepSphere.

Yes Geometry does indeed implement the Collidable interface. Are you certain that this is the error you are getting?

You should always post the full stack-trace for the error so that we can know exactly what is going on.

I have a feeling you’re actually getting a “collision not supported” exception from trying to collide 2 incompatible Collidables. Or your “collidables” variable is a typo and you’re accidentally passing in a list named “collidables” when you meant to pass in a single non-plural variable named “collidable” that was retrieved from a list of collidables.

But I’m just taking random guesses, this line of code alone is extremely obscure and on its own doesn’t tell us much:

What is “shootables”?

Is it a Geometry? Considering it is plural, it sounds like it could actually be a list.
And what is “Area” is it a bounding volume, or is it also another Geometry?

These small details are extremely important and without them it makes it harder for us to help quickly without a bunch of follow-up questions. Even just a few extra lines of code showing how you assign your variables named “collidables” and area would be enough context to help get the the bottom of the issue.

package mousetest;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.Collidable;
import com.jme3.collision.CollisionResults;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Rectangle;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.RectangleMesh;
import java.time.Instant;

/**
 * This is the Main Class of your Game. It should boot up your game and do initial initialisation
 * Move your Logic into AppStates or Controls or other java classes
 */
public class MouseTest extends SimpleApplication {

    public static void main(String[] args) {
        MouseTest app = new MouseTest();
        app.setShowSettings(false); //Settings dialog not supported on mac
        app.start();
    }
    Node shootables;
    BulletAppState bulletAppState;
    
    @Override
    public void simpleInitApp() {
        setUpLight();
        inputManager.setCursorVisible(true);
        flyCam.setDragToRotate(true);
        shootables = new Node("Shootables");
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        
        Spatial model = assetManager.loadModel("Models/level.glb");
        shootables.attachChild(model);
        
        shootables.attachChild(makeCube("a Dragon", -2f, 0f, 1f));
        shootables.attachChild(makeCube("a tin can", 1f, 0f, 0f));
        shootables.attachChild(makeCube("the Sheriff", 0f, 0f, -2f));
        shootables.attachChild(makeCube("the Deputy", 1f, 0f, -4f));

        rootNode.attachChild(shootables);
        inputManager.addMapping("Target",new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); // trigger 2: left-button click
        
        inputManager.addListener(actionListener,"Target");
        

    }
    
     private Geometry makeCube(String name, float x, float y, float z) {
    Box box = new Box(1, 1, 1);
    Geometry cube = new Geometry(name, box);
    cube.setLocalTranslation(x, y, z);
    Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat1.setColor("Color", ColorRGBA.randomColor());
    cube.setMaterial(mat1);
    return cube;
  }
    Vector3f startPoint;
    Vector3f endPoint;
    private boolean press = false;
    Geometry area;
    long areaDeleteTime = 0;
    
    final private ActionListener actionListener = new ActionListener() {
            @Override
            public void onAction(String name, boolean keyPressed, float tpf) {
                if (name.equals("Target") ) {
                    if(keyPressed){
                       
                        Vector3f origin = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);

                        Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);

                        direction.subtractLocal(origin).normalizeLocal();


                        CollisionResults results = new CollisionResults();
                        //create ray
                        Ray ray = new Ray( cam.getLocation() , direction );


                        //collide mouse click wit npc node
                        shootables.collideWith( ray, results );

                        if(results.size() > 0){
                           press = true;
                           startPoint = results.getCollision(0).getContactPoint();
                        }
                    
                    }
                    
                    if(!keyPressed && press){
                        Vector3f origin = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);

                        Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);

                        direction.subtractLocal(origin).normalizeLocal();


                        CollisionResults results = new CollisionResults();
                        //create ray
                        Ray ray = new Ray( cam.getLocation() , direction );
                        

                        //collide mouse click wit npc node
                        shootables.collideWith( ray, results );

                        if(results.size() > 0){
                            
                            endPoint = results.getCollision(0).getContactPoint();
                            Rectangle rectangle = new Rectangle();
                            
                            if(startPoint.z > endPoint.z){
                                rectangle.setA(new Vector3f(startPoint.x,startPoint.y+0.3f,startPoint.z));
                                rectangle.setB(new Vector3f(endPoint.x,startPoint.y+0.3f ,startPoint.z));
                                rectangle.setC(new Vector3f(startPoint.x,endPoint.y+0.3f ,endPoint.z));
                            }else{
                                rectangle.setA(new Vector3f(startPoint.x,startPoint.y+0.3f,startPoint.z));
                                rectangle.setC(new Vector3f(endPoint.x,startPoint.y +0.3f,startPoint.z));
                                rectangle.setB(new Vector3f(startPoint.x,endPoint.y +0.3f,endPoint.z));
                            }

                            RectangleMesh mesh = new RectangleMesh(rectangle);

                            
                            area = new Geometry("OurMesh", mesh); // using our custom mesh object
                            Material mat = new Material(assetManager,
                                "Common/MatDefs/Misc/Unshaded.j3md");
                           
                            mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
                            mat.setColor("Color", ColorRGBA.Blue);
                            area.setQueueBucket(Bucket.Transparent);

                            area.setMaterial(mat);
                            
                            RigidBodyControl collidable = new RigidBodyControl(1f);

                            area.addControl(collidable);


                            
                            rootNode.attachChild(area);
                            
                            areaDeleteTime = Instant.now().getEpochSecond();
                        }
                        
                        
                         results = new CollisionResults();
                        // 2. Aim the ray from cam loc to cam direction.
                        // 3. Collect intersections between Ray and Shootables in results list.
                        shootables.collideWith(area, results);
                        // 4. Print the results
                        System.out.println("----- Collisions? " + results.size() + "-----");
                        for (int i = 0; i < results.size(); i++) {
                          // For each hit, we know distance, impact point, name of geometry.
                          float dist = results.getCollision(i).getDistance();
                          Vector3f pt = results.getCollision(i).getContactPoint();
                          String hit = results.getCollision(i).getGeometry().getName();
                          System.out.println("* Collision #" + i);
                          System.out.println("  You shot " + hit + " at " + pt + ", " + dist + " wu away.");
                        }
                        
                    }
                }
            }
        };
    @Override
    public void simpleUpdate(float tpf) {
        if(area != null && areaDeleteTime < Instant.now().getEpochSecond()){
            rootNode.detachChild(area);
        }
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //add render code here (if any)
    }
    
    private void setUpLight() {


    // We add light so we see the scene
    AmbientLight al = new AmbientLight();
    al.setColor(ColorRGBA.White.mult(5.3f));
    rootNode.addLight(al);

    DirectionalLight dl = new DirectionalLight();
    dl.setColor(ColorRGBA.White);
    dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
    rootNode.addLight(dl);

    DirectionalLight dl2 = new DirectionalLight();
    dl2.setColor(ColorRGBA.White);
   dl2.setDirection(new Vector3f(100,3,26).normalizeLocal());
   rootNode.addLight(dl2);

    DirectionalLight dl3 = new DirectionalLight();
    dl3.setColor(ColorRGBA.White);
   dl3.setDirection(new Vector3f(-100,3,26).normalizeLocal());
   rootNode.addLight(dl3);

}
}

area is geometry
shootable is node of objects

error

com.jme3.collision.UnsupportedCollisionException: Collidable:OurMesh (Geometry)
	at com.jme3.collision.bih.BIHTree.collideWith(BIHTree.java:470)
	at com.jme3.scene.Mesh.collideWith(Mesh.java:1036)
	at com.jme3.scene.Geometry.collideWith(Geometry.java:471)
	at com.jme3.scene.Node.collideWith(Node.java:619)
	at com.jme3.scene.Node.collideWith(Node.java:619)
	at mousetest.MouseTest$1.onAction(MouseTest.java:169)
	at com.jme3.input.InputManager.invokeActions(InputManager.java:174)
	at com.jme3.input.InputManager.onMouseButtonEventQueued(InputManager.java:451)
	at com.jme3.input.InputManager.processQueue(InputManager.java:873)
	at com.jme3.input.InputManager.update(InputManager.java:923)
	at com.jme3.app.LegacyApplication.update(LegacyApplication.java:777)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:248)
	at com.jme3.system.lwjgl.LwjglWindow.runLoop(LwjglWindow.java:580)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:669)
	at java.base/java.lang.Thread.run(Thread.java:829)

Whenever you collide something against a node, it will just loop through the node’s children calling the collideWith() method on everything attached to that node.

In your case it is eventually trying to collide the “area” geometry against another geometry nested in the “shootable” node

And JME’s collision code does not support mesh vs mesh (aka geometry vs geometry) collisions, which you can see here in the source code where your stack trace is pointing:

The next best thing is to collide a geometry against another geometry’s bounding volume (which you can get with geometry.getWorldBound() which will not return as accurate of a collision, but typically works if the geometry represented by the BoundingBox is not overly comlpex

If you want more complex collisions between 2 geometries, then the next best thing is to do these types of collisions using real physics with a BulletAppState and mesh-accurate collision shapes for both collidables. Or if you want to use collidables, create an array of BoundingVolumes that represent your geometries so you can collide that against other geometries for a more accurate result.