Hi All
I am trying to implement some sort of collision detection in my game. I am using a BoundingSphere, but it seems to only work when there are a couple of things to collide with - any more in the scenegraph and I get an UnsupportedCollisionException. If I use a ray, then it doesn’t seem to matter how many things there are…
If I have 13 nodes in my scene graph as below, then I can do collisions all day:
npcs (Node)
generic characterNode a4711f67-2d17-4996-9c64-3b44eb22b519 (Node)
generic spatial b405b184-9a2f-49db-8ac5-37623258c07f (Node)
Oto-geom-1 (Geometry)
generic characterNode 974f19a2-f862-4283-9184-531409169e26 (Node)
generic spatial 458a33e5-4f35-4d15-a67c-3b10e30c6eab (Node)
Oto-geom-1 (Geometry)
generic characterNode db9ceaad-4c4c-4aa9-bb62-120cf61cae75 (Node)
generic spatial 4d2fe784-43c9-4dae-b739-53f5c2819c37 (Node)
Oto-geom-1 (Geometry)
generic characterNode b78a11c9-8210-4ffe-bba7-99e076e73671 (Node)
generic spatial 45f507cd-3600-49ec-8563-1cf5c5f53298 (Node)
Oto-geom-1 (Geometry)
If I add one more characterNode which makes it 16 nodes in my scene graph as below, then I get UnsupportedCollisionException: With: BoundingSphere : as soon as I try and collide anything whether it collides or not:
npcs (Node)
generic characterNode 33cbff0d-450b-46a4-9fbd-a9f2be533fc0 (Node)
generic spatial 050ae9c1-d286-4cea-bd7d-1ad8d466613c (Node)
Oto-geom-1 (Geometry)
generic characterNode 81f9189b-9173-498a-bdb1-58aa18fcef52 (Node)
generic spatial 02345d83-03eb-4c0b-9f78-3b37f5ad1c2b (Node)
Oto-geom-1 (Geometry)
generic characterNode ffbaeef8-c34f-4ab7-9c51-81445994f6a9 (Node)
generic spatial faf6cf6c-1f5c-4b85-aff8-abbed9f9470b (Node)
Oto-geom-1 (Geometry)
generic characterNode 0a2aa0fb-4b83-43f0-95dc-57bbe69b6583 (Node)
generic spatial fe49ba9d-7607-486c-8536-1e3f489037ee (Node)
Oto-geom-1 (Geometry)
generic characterNode 03c70abe-8eb3-4c64-9da9-08fa0a88703b (Node)
generic spatial 6c75b57a-911e-4b7d-8db5-621f7dadd8fa (Node)
Oto-geom-1 (Geometry)
Here is the full stack trace:
Oct 26, 2015 4:16:02 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.collision.UnsupportedCollisionException: With: BoundingSphere
at com.jme3.bounding.BoundingBox.collideWith(BoundingBox.java:822)
at com.jme3.scene.Node.collideWith(Node.java:579)
at mygame.InfluenceControl.controlUpdate(InfluenceControl.java:77)
at com.jme3.scene.control.AbstractControl.update(AbstractControl.java:112)
at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:661)
at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:808)
at com.jme3.scene.Node.updateLogicalState(Node.java:220)
at com.jme3.scene.Node.updateLogicalState(Node.java:231)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:249)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:152)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:192)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:233)
at java.lang.Thread.run(Thread.java:745)
Hers is the code, I hope its enough. You’ll note that I have tried it with a boundingbox as well, with the same unfortunate results:
package mygame;
import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.bullet.BulletAppState;
import com.jme3.collision.CollisionResults;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.Savable;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import java.io.IOException;
public class InfluenceControl extends AbstractControl implements Savable, Cloneable {
private Float updateNum = 0f;
public Boolean influenceSpent = false;
private BulletAppState bulletAppState;
private float speed = 1100f;
private Node nodeToInfluence;
//private BoundingSphere bs;
private Vector3f position;
InfluenceInventory influence;
Geometry anInfluenceArea;
public InfluenceControl(BulletAppState bulletAppState, Node nodeToInfluence, Vector3f position, InfluenceInventory influence, Geometry anInfluenceArea) {
this.bulletAppState = bulletAppState;
this.nodeToInfluence = nodeToInfluence;
this.influence = influence;
this.position = position;
this.anInfluenceArea = anInfluenceArea;
/* sphere to begin with, but, influence.getMethod() will give us sphere, ray or arc which we should use */
}
/**
* This method is called when the control is added to the spatial, and when
* the control is removed from the spatial (setting a null value). It can be
* used for both initialization and cleanup.
*/
@Override
public void setSpatial(Spatial spatial) {
super.setSpatial(spatial);
/* Example:
if (spatial != null){
// initialize
}else{
// cleanup
}
*/
}
/**
* Implement your spatial's behaviour here. From here you can modify the
* scene graph and the spatial (transform them, get and set userdata, etc).
* This loop controls the spatial while the Control is enabled.
*
* @param tpf
*/
@Override
protected void controlUpdate(float tpf) {
if (!influenceSpent) {
System.out.println("Influence Area testing collisions");
BoundingSphere bs = new BoundingSphere(1f, new Vector3f(0, 0, 0));
BoundingBox bb = new BoundingBox(new Vector3f(0, 0, 0), 1, 1, 1);
Ray ray = new Ray(new Vector3f(0, 0, 0), new Vector3f(10, 10, 10));
CollisionResults results = new CollisionResults();
nodeToInfluence.collideWith(bs, results);
//nodeToInfluence.collideWith(ray, results);
//anInfluenceArea.collideWith(nodeToInfluence , results);
if (results.size() > 0) {
System.out.println("Influenced this many " + results.size());
// Iterator it = results.iterator();
//
// while(it.hasNext()){
// System.out.println(results.size() + "Influenced this" + it.next().toString());
// }
} else {
System.out.println("Influenced Nothing");
}
if (updateNum > 3) {
//System.out.println("Influence spent");
influenceSpent = true;
bulletAppState.getPhysicsSpace().removeAll(spatial);
spatial.removeFromParent();
}
updateNum += tpf;
}
}
@Override
public Control cloneForSpatial(Spatial spatial) {
final InfluenceControl control = new InfluenceControl(bulletAppState, nodeToInfluence, position, influence, anInfluenceArea);
/* Optional: use setters to copy userdata into the cloned control */
// control.setIndex(i); // example
System.out.println("spatial is " + spatial);
control.setSpatial(spatial);
return control;
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
/* Optional: rendering manipulation (for advanced users) */
}
@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
// im.getCapsule(this).read(...);
}
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
// ex.getCapsule(this).write(...);
}
}