CollisionShape incorrect for scaled spatials

Hello monkeys,
I know, this issue has been discussed already, but I still don’t get it working, so I decided to create a new topic.

To my problem: Normally I have one collision geometry in my model hierarchy, for example it could look like that.

In the picture on the right you can see the selected collision geometry in scene composer.

Due to some physic issues in the past I decided to add physic controls in code. What I want to do is to generate a static physic control / RigidBodyControl for each geometry called “Collision” , does work so far. BUT … When I scale the model in scene composer for example to create some bigger or smaller palms, the collsision shape doesn’t fit the “new” size, it semms not be scaled.

I created a small test case to illustrate the problem.

@Override
public void simpleInitApp() {
    
    flyCam.setMoveSpeed(50);

    BulletAppState bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);

    bulletAppState.setDebugEnabled(true);

    
    // palm1 is the palm on the left
    Node palm1 = (Node) assetManager.loadModel("Models/SceneModels/Trees/Palms/Palm01.j3o");
    palm1.setLocalTranslation(-3, 0, 0); 
    palm1.depthFirstTraversal(new SceneGraphVisitor() {
        @Override
        public void visit(Spatial spatial) {
            if (spatial.getName().equals("Collision")) {
                CollisionShape cs = CollisionShapeFactory.createMeshShape(spatial);
                RigidBodyControl control = new RigidBodyControl(cs, 0);
                spatial.addControl(control);
                control.setKinematic(true);
                bulletAppState.getPhysicsSpace().add(control);
            }
        }
    });

    
    // palm2 is the palm on the right, it also is scaled
    Node palm2 = (Node) assetManager.loadModel("Models/SceneModels/Trees/Palms/Palm01.j3o");
    palm2.setLocalTranslation(260, 0, 0);
    palm2.scale(2,2,1); // ONLY DIFFERENT LINE FOR PALM 2, rest is the same
    palm2.depthFirstTraversal(new SceneGraphVisitor() {
        @Override
        public void visit(Spatial spatial) {
            if (spatial.getName().equals("Collision")) {
                CollisionShape cs = CollisionShapeFactory.createMeshShape(spatial);
                RigidBodyControl control = new RigidBodyControl(cs, 0);
                spatial.addControl(control);
                control.setKinematic(true);
                bulletAppState.getPhysicsSpace().add(control);
            }
        }
    });
    
    
    rootNode.attachChild(palm1);
    rootNode.attachChild(palm2);
    
    /**
     * A white ambient light source.
     */
    AmbientLight ambient = new AmbientLight();
    ambient.setColor(ColorRGBA.White);
    rootNode.addLight(ambient);
}

The following screenshot Shows the result:

I hope someone can help me!

Greetings, Domenic

Maybe you should try scaling the colision shape as well.

Tried that, but the shape is always getting “worse” :laughing:

Back away from the computer before it explodes.

…or did ‘worse’ mean something different than I imagined?

AKA: can you be more precise in your description.

What do you mean by “worse”?

Okay, seriously, if I scale the collision shape for example like that

cs.setScale(palm2.getLocalScale());

the collision shape is like extremely stretched. Have a look at that screenshot:

EDIT: Sorry because of my unprecise discription :worried:

Maybe I’m oblivious of something obvious, but the collision shape appears to match the mesh, the two just appear not to be in the same location.

What is palm2.getLocalScale() and what is cs.getScale()?
e.g. when palm2.getLocalScale used to be 2 and then you scaled it by 2 you have a new local scale of 4.
Then it’s possible though that you only need to scale the collissionShape by 2.

On the other hand: Doesn’t the RigidBodyControl offer something like re-scaling (At least you have to use warp over setLocalTranslation).
Also: Attach the RBC directly to the “Scene” or else it can’t regenerate or something since it has no clue what Colission is (probably an empty node)

No, it doesn’t fit, it is just because you can not see the whole model in this picture.

When I do the following:

Node palm3 = (Node) assetManager.loadModel("Models/SceneModels/Trees/Palms/Palm01.j3o");
palm3.scale(0.5f);
palm3.addControl(new RigidBodyControl(0));
bulletAppState.getPhysicsSpace().addAll(palm3);

It does work, even with the scale! But then the whole mesh gets a mesh collision shapes, like the leaves what is unnecessary, because the player can’t reach them anyway.

You could perhaps scale the model in Blender or whatever you use for modeling but that’s too easy, am I not right? :laughing:

palm2.getLocalScale is the scale from the palm model.
cs.setScale is to set the scaling of the collisions shape.

I am using kinematic mode, so there is no reason for me to use the warp function!?

Yes and to much work :wink:

So, I think I am doing something wrong here in general.

Exactly: When for some reason the palm scale is different than the collison shape you could get what you have.
That happens when the ColissionShape is drawn at scale 1 when using the 0.5 scale model as source.
And for your Code: Simply add the Control to the bark then?

Why the bark? Just tried that, doesn’t work. Oh my god, I have no idea how to solve that problem …

Because I thought the bark to be the palm without the leaves?
Anyway how about simply not Scaling after adding the RBC or adding the Control at the very least point

Please have a look at my first post, there you can see that there are 3 geometries. Of course I could just use the bark, but I would have the same problem. The palm is just an example. For example I also got a fence model where I have a scaled cube as collision object. The same happens there as well.

Is this not what I am doing right now? I first scale the model and then I add the control.

I think the problem here is that when you add a static RigidBodyControl to a geometry and scale the node the geometry is attached to the scaling of the node will just be ignored, because the control doesn’t even know the node.
Is there an option to just add a rigidbodycontrol to that collision geometry and make it know the father (“Scene”) without rewriting RigidBodyControl itself ???

EDIT:

I have a solution for now, I am not very happy with that but it works for me for now. I created a empty class, copy and pasted the whole CollsionShapeFactory. Then I changed the following line in the createCompoundShape method.
From:

} else if (spatial instanceof Geometry) {

To:

} else if (spatial instanceof Geometry && (spatial.getName().equals("Collision") || spatial.getName().equals("CollisionBox"))) {

It is like a filter, only geometries with this name will be added to the collision shape.

I would really appreciate it, if someone could provide a cleaner solution.