Problem with overlapping GhostControllers (video inside)

Hello,



I’ve got a problem with overlapping GhostControllers. If I activate debugmode, the collisionshapes seem to be okay, but they’re triggering overlaps even if they don’t seem like touching each other. Here’s a video of my problem:



http://www.youtube.com/watch?v=-dcvOrlrGsc



Reading the collisions:

[java] for (Iterator<Projectile> projIt = projectiles.iterator(); projIt.hasNext();) {
boolean kill = false;
Projectile proj = projIt.next();
proj.update(rootNode, effects, tpf);

for (Iterator<Ship> sIt = ships.iterator(); sIt.hasNext();) {
Ship ship = sIt.next();
if(proj.overlaps(ship)){
ship.editHp(proj.getPower()*-1f);
kill = true;
}
}
if(proj.getLife() <= 0){
kill = true;
}
if(kill){
proj.destroy(rootNode, tpf);
projIt.remove();
}
}[/java]

The asteroid is a "Ship" object and projectiles are projectiles :P

[java] public boolean overlaps(Ship target){
if (this.ghost.getOverlappingObjects().contains(target.getGhost())) {
return true;
}
return false;
}[/java]

this.ghost is the projectile's ghost controller and target.getGhost() returns the target ship's ghost controller.

I tried reading the javadoc but didn't found any reason why this would happen :(
1 Like

Even though reading the collisions is inside the simpleUpdate() I also tried using PhysicsTickListener with the following control but it gave me exactly the same results.



[java]public class GhostControl2 extends GhostControl implements PhysicsTickListener{



private List<PhysicsCollisionObject> collisionList;



public GhostControl2(CollisionShape shape){

super(shape);

}



@Override

public void prePhysicsTick(PhysicsSpace space, float tpf){

}



@Override

public void physicsTick(PhysicsSpace space, float tpf){

this.collisionList = this.getOverlappingObjects();

}



public List<PhysicsCollisionObject> getOverlappingObjects2(PhysicsSpace space, float tpf){

physicsTick(space, tpf);

return this.collisionList;

}

}

[/java]

How are u moving your models?

The spatials the ghost controllers are attached to, are geometries, which I move with .setLocalTranslation() and .move()

Ok well that is right, hmm. I tried it myself and there are indeed some discrepancies. Perhaps Ghost with Ghost is not supported.



Other options are to use sweep tests with kinematic rigidbodies or ray casts.

I moved to raycasting and got pretty decent performance. I guess I could get even better if I cast the rays against more simple versions of the geometries. But thanks for confirming that there really is something with the ghostControl.

Are you using the Physics Ray Cast, or the standard geometry one? im talking about this one:



http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsRayCast.java

I’m using the standard one. The performance of the game actually improved a tiny bit even though I’m using the high poly meshes because updating the phyiscs space and constantly attaching new physics objects consumed a lot of performance.

Are you reusing collision shapes, for your bullets?

No, I’m using the same meshes as for the rendering. I disabled the whole bulletAppState to gain performance boost.

@pate5: I thought that for any ghost objects you were supposed to use GhostControl.setPhysicsLocation()?



@Normen: is that correct? Cause otherwise it looks like a bug to me.

you definitely move the spatial and the ghost control moves with it (just checked for confirmation). And cracked open a quick testcase to illustrate the problem. While small, there is a gap where collisions are being detected. And this is apparent in both ghost/ghost and ghost/rigidbody collisions.



[java]package com.mmm.util.test;



import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.collision.shapes.SphereCollisionShape;

import com.jme3.bullet.control.GhostControl;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.scene.Node;



public class TestGhostControl extends SimpleApplication {



private BulletAppState bulletAppState = new BulletAppState();

private SphereCollisionShape sphereCollisionShape = new SphereCollisionShape(1f);

private Node leftSphere;

private Node rightSphere;



public static void main(String[] args) {

new TestGhostControl().start();

}



@Override

public void simpleInitApp() {

stateManager.attach(bulletAppState);



// Left sphere

leftSphere = new Node("leftSphere");

leftSphere.move(-4, 0, 0);

leftSphere.addControl(new GhostControl(sphereCollisionShape));

bulletAppState.getPhysicsSpace().add(leftSphere);

rootNode.attachChild(leftSphere);



// Input Mappings

inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_A));

inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_D));

inputManager.addListener(analogListener, "left", "right");

flyCam.setEnabled(false);



// Right sphere

rightSphere = new Node("rightSphere");

//rightSphere.addControl(new RigidBodyControl(sphereCollisionShape, 0));

rightSphere.addControl(new GhostControl(sphereCollisionShape));

bulletAppState.getPhysicsSpace().add(rightSphere);

rootNode.attachChild(rightSphere);



bulletAppState.getPhysicsSpace().enableDebug(assetManager);

}



@Override

public void simpleUpdate(float tpf) {

if (leftSphere.getControl(GhostControl.class).getOverlappingCount() > 0) {

fpsText.setText("Colliding");

}

}

private AnalogListener analogListener = new AnalogListener() {

public void onAnalog(String name, float value, float tpf) {

if (name.equals("left")) {

leftSphere.move(-value, 0, 0);

// leftSphere.getControl(GhostControl.class).setPhysicsLocation(new Vector3f(-value, 0, 0));

} else if (name.equals("right")) {

leftSphere.move(value, 0, 0);

}

}

};

}[/java]

I noticed it says this on the javadoc:

“GhostObject can keep track of all objects that are overlapping. By default, this overlap is based on the AABB. This is useful for creating a character controller, collision sensors/triggers, explosions etc.”



If its based on AABB, doesn’t that imply that the collision shape is ignored?



@Normen: Can you provide an explanation for this?

ah right, hmmm. Well i’m using Nodes, so its taking the AABB of my collision shape?



Heres the screenshot from the testcase:

I know that bullet by default has a small margin when detecting collision … Perhaps that is it? Can you try it with AABB collision shape maybe and see if the issue appears?

I guess it’s just using the bounding boxes. If you watch my video you can see a huge invisible box around the asteroid.

The gap is definitely smaller with the BoxCollisionShape, although the camera angle is different to the first one. Shown below there is no collision yet: