When rotating a GhostControl to a position that is not fully aligned with X, Y or Z axis, the collision shape is no more recognized.
The whole “XYZ-bounding-box” described by the rotated collisionShape responds to overlap, instead of the only collisionShape.
Note that PhysicsCollisionGroupListener and GhostControl’s Overlapping objects return both the same (invalid?) result.
Here is a sample code to show what I mean :
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.shapes.CylinderCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.GhostControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
public class Main extends SimpleApplication{
private GhostControl sensor;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
// physics
BulletAppState bullet = new BulletAppState();
this.getStateManager().attach(bullet);
bullet.setDebugEnabled(true);
PhysicsSpace space = bullet.getPhysicsSpace();
// rotated cylinder ghost control
float height = 15f;
float radius = .5f;
Node base = new Node("cylinder_base");
base.setLocalTranslation(0, 0, 0);
Node center = new Node("cylinder_center");
base.attachChild(center);
center.setLocalTranslation(0, height / 2, 0);
CylinderCollisionShape sensorShape = new CylinderCollisionShape(new Vector3f(radius, height / 2, radius), 1);
sensor = new GhostControl(sensorShape);
center.addControl(sensor);
rootNode.attachChild(base);
base.setLocalTranslation(new Vector3f(0, 0, 0));
space.addAll(base);
base.rotate(45 * FastMath.DEG_TO_RAD, 0, 45 * FastMath.DEG_TO_RAD);
// some objects to collide with
// only obj_1 should collide.
Node o1 = createObject("obj_1");
rootNode.attachChild(o1);
o1.setLocalTranslation(new Vector3f(0, 0, 0));
space.addAll(o1);
Node o2 = createObject("obj_2");
rootNode.attachChild(o2);
o2.setLocalTranslation(new Vector3f(0, 7, 0));
space.addAll(o2);
Node o3 = createObject("obj_3");
rootNode.attachChild(o3);
o3.setLocalTranslation(new Vector3f(0f, 0, 7));
space.addAll(o3);
Node o4 = createObject("obj_4");
rootNode.attachChild(o4);
o4.setLocalTranslation(new Vector3f(-2f, 0, 0));
space.addAll(o4);
}
private Node createObject(String name){
Node obj = new Node(name);
RigidBodyControl control = new RigidBodyControl(new SphereCollisionShape(.1f), 0);
obj.addControl(control);
control.setKinematic(true);
return obj;
}
@Override
public void simpleUpdate(float tpf) {
for(PhysicsCollisionObject obj : sensor.getOverlappingObjects()){
System.out.println("detecting : "+obj.getUserObject());
}
}
@Override
public void simpleRender(RenderManager rm) {
}
}
Am I doing something wrong ?
Or is there any other way achieve what I want (a rotated sensor reporting collisions only inside its shape) ?