Collision of spatial with Non Physical Control

Hi, I have a simple LaserControl used for every laser bullet I fire. How can I use collision detection from with in the control which could trigger removal of the spatial from rootNode and possibly trigger some effects? How can I see if it collides with anything in the rootNode. I want to keep everything non physical. Thanks for any help in advance.

Does something like this look like it might be part right… It crashes the game so I know something is wrong.

[java]
@Override
protected void controlUpdate(float tpf) {
//TODO: add code that controls Spatial,
//e.g. spatial.rotate(tpf,tpf,tpf);
spatial.move(getForward((Node) spatial, 60 * tpf));
CollisionResults results = new CollisionResults();
spatial.collideWith(spatial.getParent(), results);
if (results.size() > 0) {
spatial.removeFromParent();
}
}
[/java]

What’s the stack trace for the crash?

INFO: Child (Models/laser01/laser01-scene_node) attached to this node (Root Node)
Jan 30, 2013 5:16:37 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.collision.UnsupportedCollisionException
at com.jme3.collision.bih.BIHTree.collideWith(BIHTree.java:461)
at com.jme3.scene.Mesh.collideWith(Mesh.java:856)
at com.jme3.scene.Geometry.collideWith(Geometry.java:454)
at com.jme3.scene.Node.collideWith(Node.java:493)
at com.jme3.scene.Node.collideWith(Node.java:493)
at com.jme3.scene.Node.collideWith(Node.java:493)
at com.jme3.scene.Node.collideWith(Node.java:493)
at mygame.LaserControl.controlUpdate(LaserControl.java:36)
at com.jme3.scene.control.AbstractControl.update(AbstractControl.java:90)
at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:559)
at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:677)
at com.jme3.scene.Node.updateLogicalState(Node.java:146)
at com.jme3.scene.Node.updateLogicalState(Node.java:153)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:243)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
at java.lang.Thread.run(Thread.java:680)
Jan 30, 2013 5:16:37 PM com.jme3.renderer.lwjgl.LwjglRenderer cleanup
INFO: Deleting objects and invalidating state
Jan 30, 2013 5:16:38 PM com.jme3.scene.Node detachChildAt
INFO: Gui Node (Node): Child removed.
Jan 30, 2013 5:16:38 PM com.jme3.scene.Node detachChildAt
INFO: Gui Node (Node): Child removed.
Jan 30, 2013 5:16:38 PM com.jme3.input.lwjgl.LwjglMouseInput destroy
INFO: Mouse destroyed.
Jan 30, 2013 5:16:38 PM com.jme3.input.lwjgl.LwjglKeyInput destroy
INFO: Keyboard destroyed.
Jan 30, 2013 5:16:38 PM com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread
INFO: Display destroyed.

Have a read of the exception ( in particular the type and the first line of stack trace) and see if that gives you a clue…

You can also use the magnifying glass at the top right of this window to do a search … for example for UnsupportedCollisionException … and find all sorts of helpful replies…

OK, is it acceptable to pass the rootNode to the Control, the main problem I am having is doing this from with in a Control. Is the parent of spatial always… or ever the rootNode. How to I access the rootNode from a Control. So far, what I get from the search is I can’t check geometry to geometry collision, I need a bounding volume.

You need to somehow share the root node (or the application from which you can query the root node) with the control. That’s standard OO Java…so just pass the value any way you like.

The parent of a spatial is whatever node you placed it in. Take a look at the scene graph information in the tutorials.

Your search results sound correct, although it’s not something I’ve used myself so I can’t give you any more details. Try searching on a few more terms, for example bounding volume, geometry collision, maybe both combined, etc.

Thanks for the reply’s. I have code that doesn’t crash now.
[java]
protected void controlUpdate(float tpf) {
//TODO: add code that controls Spatial,
//e.g. spatial.rotate(tpf,tpf,tpf);
spatial.move(getForward((Node) spatial, 60 * tpf));
CollisionResults results = new CollisionResults();
spatial.collideWith(spatial.getParent().getWorldBound(), results);
if (results.size() > 0) {
spatial.removeFromParent();
}
}[/java]
With this the laser is added and then quickly removed before I even see it. I am not sure if this is because it is spawning in the ship instead of in front of it or because when it spawns in the rootNode that counts as collision with the rootNode.

Yeah, colliding it with root node - which includes itself…so its always going to ping.

Here is an update of my code. Not sure why it is still getting removed.
[java]
protected void controlUpdate(float tpf) {
//TODO: add code that controls Spatial,
//e.g. spatial.rotate(tpf,tpf,tpf);
spatial.move(getForward((Node) spatial, 60 * tpf));
boolean isremoved = false;
Node myroot = spatial.getParent();
List allSpatials = spatial.getParent().getChildren();
Iterator iterator = allSpatials.iterator();

    while (iterator.hasNext()) {
        //System.out.print(iterator.next().getName());
        Spatial spat = iterator.next();
        if (!spat.getName().equals(spatial.getName()) && !spat.getName().equals(myroot.getName())) {
            CollisionResults results = new CollisionResults();
            spatial.collideWith(spat.getWorldBound(), results);
            if (results.size() > 0 && !isremoved) {
                spatial.removeFromParent();
                isremoved = true;
            }   
        } 

    }
    
}[/java] 

Maybe I should try just passing the rootNode to the Controler’s Constructor.

I’m sorry, but I’ve run your code, and I can see no such trouble. Collision is well detected when it exists. And only then.

Wait, I think it might be because I loaded a scene and this is all occurring in the scene. I am in a sky box, and other things are in the scene. So how can I filter out the detection of collision with the scene but still detect collision of geometry that is part of the scene?

edit: yes I have confirmed it is because of collision with the scene, so I assume I need to make a loop checking for collision with all children of the scene, does this sound right anyone?

Here is my final code that works, I may want to make something cleaner however.
[java]
@Override
protected void controlUpdate(float tpf) {
//TODO: add code that controls Spatial,
//e.g. spatial.rotate(tpf,tpf,tpf);
spatial.move(getForward((Node) spatial, 60 * tpf));
boolean isremoved = false;
String myroot = spatial.getParent().getName();
List rootSpatials = spatial.getParent().getChildren();
Iterator rootiterator = rootSpatials.iterator();

    while (rootiterator.hasNext()) {
        Spatial spat = rootiterator.next();
        if (!spat.getName().equals(spatial.getName()) &&  !spat.getName().equals("New Scene")) {
            CollisionResults results = new CollisionResults();
            spatial.collideWith(spat.getWorldBound(), results);
            if (results.size() > 0 && !isremoved) {
                spatial.removeFromParent();
                isremoved = true;
            }   
        } 
    }
    
    Node scene01 = (Node) spatial.getParent().getChild("New Scene");
    List sceneSpatials = scene01.getChildren();
    Iterator sceneiterator = sceneSpatials.iterator();
    
    while (sceneiterator.hasNext()) {
        Spatial spat = sceneiterator.next();
        if (!spat.getName().equals(spatial.getName()) &&  !spat.getName().equals("Sky")) {
            CollisionResults results = new CollisionResults();
            spatial.collideWith(spat.getWorldBound(), results);
            if (results.size() > 0 && !isremoved) {
                spatial.removeFromParent();
                isremoved = true;
            }   
        } 
    }
    
}[/java] 

edit: Need to put everything after the first loop in an if (!isremoved) {}.

If you have a skybox, maybe it does collide with everything.
You should try and collide only with collideable objects. It will save time and headaches.

Please note also the you collision test gives you information on where the collision happened ON YOUR LASER. If you want to know which part of an object is hit, you should reverse your test :
spat.collideWith(spatial.getBounds(),…)

Thanks for the extra info.

Now I find my game slowing down when I fire a bunch of these lasers. I also have about 500 low poly space rocks in the rootNode, and the laser material uses a glow map. I wonder how I can speed this up. It starts at hundreds of fps and can drop down to 22fps. This is on a mac with an AMD 6770 GPU.

Do you remove your objects (including lasers) from the scene ? It should not slow down with time !
Do you have a test-case to share with us so that we could reproduce it ?