CollisionShapeFactory.createMeshShape() always using BoundingBox

Hi again !

I’m currently facing a really annoying problem with collision shape creation. I want to have a collision shape from a mesh but no matter what even if the physics debug is correct the mesh effective shape is the bounding box this object.

Here is the situation in game with physics debug enabled

As you can see the shape is correct and exactly what I want ! But the effective shape is the bounding box of this object which is shown here

Here is the algorithm used for this

    //The node older
    TriggerHolder n = (TriggerHolder) s;
    //Which is hidden since the game is starting
    n.setCullHint(Spatial.CullHint.Always);
    //A new Ghost Listener is created
    GhostListener ghostL = GhostFactory.getInstance().createGhost(TriggerType.valueOf((String) n.getUserData("TriggerType")), n);
    ghostL.registerWithInput(inputManager);
    //Simply some action to do
    for(GhostAction g : n.getActionsList()){
        ghostL.addAction(g);
        g.gameReady(this);
    }
    ghostL.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);
    ghostL.setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_01);
    //The ghost is added here
    n.addControl(ghostL);
    bulletAppState.getPhysicsSpace().add(n);

And the ghost listener

public abstract class GhostListener extends GhostControl {
    public GhostListener(Node n) {
        super(CollisionShapeFactory.createMeshShape(n));
    }
}

I can’t put a video of the problem or even some detailed code if you want.

A ghost object always uses the AABB for collision (as its javadoc says).

1 Like

meaning Axis Aligned Bounding Box.

1 Like

Ok I get it now ! Thanks you guys !

But still, how can I surpass this problem ? Do you have any idea ?

You didn’t say what your problem was. If you just want to check collisions with a mesh shape theres multiple ways. Normal rigidbodies, sweep tests etc.

In fact I need to define an area where I can check if the player enter, leave, on is inside, so I decided to use a GhostControl and it work perfectly . But I need this area to be strictly determined by a Box. I thought the GhostControl was designed to be this kind of physics object since it detect collision without colliding with the other physical object.

The ghost object is exactly what I need but I can’t use it as I want because I can’t define it to be the exact MeshShape of my object. So What should I use to define an area that correspond to a MeshShape which is in the physics space, detect collisions but doesn’t collide with it ?

I think I already mentioned sweep tests. Also rigidbodies with a special collision group check would work.

My bad, I just found my answer :frowning:

http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:bullet_pitfalls

Well, I found a really tricky answer.

I managed to reproduce the Ghost behaviour by checking the collision between the Node and the Player by using their respective bounding box. So I post the answer for people like me :smiley:

public class GhostListener implements Control {

    protected ArrayList<GhostAction> actions = new ArrayList<GhostAction>();
    private float lastCol = 0f;
    private float threshold = 0.3f;
    private InputManager inputManager;
    private Spatial target;
    private BoundingBox player;

    public GhostListener() {
    }

    public void addAction(GhostAction action) {
        actions.add(action);
    }

    @Override
    public void update(float tpf) {
        lastCol += tpf;
        if (lastCol > threshold) {
            ghostUpdate(tpf);
            lastCol = 0f;
        }
    }

    public void setThreshold(float t) {
        this.threshold = t;
    }

    protected void ghostUpdate(float tpf) {
        //Complete
    }

    public int getOverlappingCount() {
        CollisionResults results = new CollisionResults();
        target.collideWith(player, results);
        if(results.size() > 1){
            return 1;
        }else{
            return 0;
        }
    }

    public void registerWithInput(InputManager inputManager) {
        this.inputManager = inputManager;
    }

    public void registerGhost(BoundingBox player) {
        this.player = player;
    }

    public Control cloneForSpatial(Spatial spatial) {
        GhostListener g = new GhostListener();
        return g;
    }

    public void setSpatial(Spatial spatial) {
        this.target = spatial;
    }

    public void render(RenderManager rm, ViewPort vp) {
    }

    public void write(JmeExporter ex) throws IOException {
    }

    public void read(JmeImporter im) throws IOException {
    }
}

But I feel like something isn’t right…But anyway, it does what it should do !

Thank you for your patience

Note: bounding boxes are also axis aligned.

Edit: though the way you are doing it with collideWith() perhaps it doesn’t matter down at the leaves.

Yeah the bounding box is axis aligned too. But since the player has a Capsule Shape and the x,z orientation doesn’t matter and is always y aligned. In this case it works perfectly well ! (Perhaps ?)

I looked at Sweep Test and it seems like it is really “hacking” the physics engine and I don’t like it.
And Rigidbody group… I don’t know how to implement it right now.

I’ll update this post if I find any better solution or any undesired behaviour. Ty :blush:

SweepTest isn’t hacking. And for the RigidBody, just set a collision group, make a CollisionGroupListener, add it to the physics space and return “false” to not have it actually do anything when it collides.