Updating a RigidBodyControl's CollisionShape properly

So lets say I have a few box geometries in a node called object and attach a RigidBodyControl to it like so:

control = new PhyControl(2f);	
object.addControl(control);
bulletAppState.getPhysicsSpace().add(control);

This generates the right collision mesh and works great until any of the boxes are detached from the object node. Then the collisionshape stays the same as the beginning tutorial explains:

The collision shape is not automatically updated when the spatial mesh changes
You can update it by reattaching the control or by using the CollisionShapeFactory yourself.

Reattaching the control is a bit of an inconvenience for me since the chasecam is also attached as a control and needs to be moved to the end of the controls list (basicly reinstanciating it) if physics is reattached which isn’t ideal.

I tried doing this with the CollisionShapeFactory then and I have this code which gets called every time a box geometry is detached from the object:

	CollisionShape shape = CollisionShapeFactory.createBoxShape(object);
	bulletAppState.getPhysicsSpace().remove(control);
	control.setCollisionShape(shape);
	control.setMass(2f);
        bulletAppState.getPhysicsSpace().add(control);

I seem to need to remove the control from the physicsspace and re-add it later otherwise the app crashes with a nullpointer exception, but when I run this code the object becomes frozen and doesn’t react to forces or collisions, but the detached boxes work fine so the engine is running normally. Any clues?

I guess you’ll have to recreate the whole RigidBody.

Why exactly? If you want to be of any actual help, you might want to elaborate a bit.

I have a close situation on my Voxel Engine. When I detect a Mesh change, I do update the Geometry mesh, update the model bound and just recreate the CollisionShape:

Geometry geometry = (Geometry) spatial;
geometry.setMesh(mesh);
geometry.updateModelBound();

RigidBodyControl rigidBodyControl = geometry.getControl(RigidBodyControl.class);
rigidBodyControl.setCollisionShape(CollisionShapeFactory.createMeshShape(geometry));

As you can see, I don’t detach and attach the RigidBodyControl on physicsSpace. So try just update the MeshShape…

control.setCollisionShape(CollisionShapeFactory.createBoxShape(object));

And see what you got.

That was the thing that I tried first and already explained what happens in the first post. Funny thing though, tried what @normen suggested, however ludicrous it seems. It worked…

        Node n = playergrp.clone(false);
	
	CollisionShape shape = CollisionShapeFactory.createBoxShape(n);
	physics.getPhysicsSpace().remove(playerphysics);
	playerphysics.setCollisionShape(shape);
	playerphysics.setMass(1f);
	physics.getPhysicsSpace().add(playerphysics);

But why does it make a difference? It makes no sense at all.

Now I have to agree with you and ask the same question. After doing more tests and better usage of Bullet, I realized that my CollisionShapes was not being updated as wiki says:

The collision shape is not automatically updated when the spatial mesh changes
You can update it by reattaching the control or by using the CollisionShapeFactory yourself.

If I only use CollisionShapeFactory, it doesn’t work or i’m missing something.

The working code is this one:

Geometry geometry = (Geometry) spatial;
geometry.setMesh(mesh);
geometry.updateModelBound();

RigidBodyControl rigidBodyControl = geometry.getControl(RigidBodyControl.class);
rigidBodyControl.setEnabled(false);
rigidBodyControl.setCollisionShape(CollisionShapeFactory.createMeshShape(geometry));
rigidBodyControl.setEnabled(true;

I think the wiki is outdated or wrong, becase the Java docs gave me the tip:

com.​jme3.​bullet.​objects.​PhysicsRigidBody

public void setCollisionShape(CollisionShape collisionShape)
Sets a CollisionShape to this physics object, note that the object should not be in the physics space when adding a new collision shape as it is rebuilt on the physics side.

Parameters:
collisionShape - the CollisionShape to set

So I can’t just use CollisionShapeFactory, as wiki says. I need always detach and attach the object…right?

Well you need to detach the physics object from the physicsspace while you are making changes to the collisionshape or the thread crashes with a nullpointer exception. What you dont need to reattach is the control to the node.