Collision between scenegraph and Spatial

Hi guys,

first real snag I’ve hit while working with the monkey. Hope to get some input and/or clarification.

My goal is to obtain a list of Geometry-objects that my Spatial player collides with in the scene graph.

The docs: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:collision_and_intersection state

Mesh and Scene Graph Collision

One of the supported Collidables are meshes and scene graph objects. To execute a collision detection query against a scene graph, use Spatial.collideWith(). This will traverse the scene graph and return any mesh collisions that were detected. Note that the first collision against a particular scene graph may take a long time, this is because a special data structure called |Bounding Interval Hierarchy (BIH) needs to be generated for the meshes. At a later point, the mesh could change and the BIH tree would become out of date, in that case, call Mesh.createCollisionData() on the changed mesh to update the BIH tree.

All right.
[java]
class MyAwesomePlayer extends Node implements blablabla { … };

MyAwesomePlayer player = new MyAwesomePlayer(“foo”);
Spatial loadedModel = player.getMyFunkySpatialChildOfPlayerNode();

CollisionResults col = new CollisionResults();
loadedModel.collidesWith(rootNode, col);

[/java]

This gives me a neato:

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:853) at com.jme3.scene.Geometry.collideWith(Geometry.java:454) at com.jme3.scene.Node.collideWith(Node.java:492) at ScaryForest.simpleUpdate(ScaryForest.java:176) at com.jme3.app.SimpleApplication.update(SimpleApplication.java:241) 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) Dec 28, 2012 11:36:51 AM com.jme3.renderer.lwjgl.LwjglRenderer cleanup

Can someone provide some insight? What exactly does this Exception mean?

I can dig into your SVN repository and take a peek myself, but I thought I’d give this forum a chance first.

its because geometry - geometry collisions are not supported. You need to do geometry - boundingVolume or boundingvolume - boundingvolume

Fine. The documentation actually mentions that on the same page as an “important point”, but it’s not exactly clear, is it? Anyway, moving along…

What actually initiates a traverse of the scene-graph then? Specifically,

[java]
rootNode.collideWith(player.getWorldBound(), col);
[/java]
or
[java]
player.getWorldBound().collideWith(rootNode, col);
[/java]
One of them gives me a Exception (guess which one!). If you guessed the bottom, you are correct, the reason being that the implementation of collideWith() that the object returned on player.getWorldBound() does not like getting a Node as it’s first argument. Fair enough, this is geometry/boundingVolume-collisions after all.

As such, I guess the first one is the right one to use, and it makes sense as well because that means that the Node.collideWith() is special and actually initiaties a traverse of the scene graph.

However, I’m not out of the woods yet. When calling rootNode.collideWith() I do not seem to get all the collisions between Geometry-nodes in my scene graph and the player bounding volume. Specifically, I do
[java]
for(int i = 0; i < 400; i++) { rootNode.attachChild(new Geometry(“foobox”, new Box(blablabla)); }
[/java]
None of these are reported as collisions when I move my player around in the scene. Ideas?

Clearly, I am an idiot!

I figured it out. For people that run across this thread in the future, my mistake was quite simply that I used CollisionResults.getClosestCollision(), and did not iterate over the full collection of Collisions, hence the sceneGraph-iteration worked just fine, I just never picked up the result.

[java]
CollisionResults col = new CollisionResults();
rootNode.collideWith(player.getWorldBound(), col);

for(Iterator it = col.iterator(); it.hasNext():wink: {
Geometry g = it.next().getGeometry();
if(g.getName().equals(“foobox”)) {
g.removeFromParent();
}
[/java]

Feel free to close this post and/or use it as a shining example of idiocy in the future.

Thanks,

[/java]

1 Like