AndresTraks / BulletSharp

.NET wrapper for the Bullet physics library
http://andrestraks.github.io/BulletSharp
MIT License
273 stars 59 forks source link

BulletSharp, OpenTK & Scale #61

Closed NovemberDev closed 4 years ago

NovemberDev commented 4 years ago

Hello,

Whenever I use this method:

public Matrix4 GetTransformation(bool inverted = true)
        {
            if(_transformationDirty && !OverrideMatrix)
            {
                Matrix4 rotation = Matrix4.CreateRotationX(_rotation.X) * Matrix4.CreateRotationY(_rotation.Y) * Matrix4.CreateRotationZ(_rotation.Z);
                Matrix4 scale = Matrix4.CreateScale(Scale);
                Matrix4 translation;

                if (inverted)
                    translation = Matrix4.CreateTranslation(new Vector3(-1.0f, 1.0f, -1.0f) * _position);
                else
                {
                    translation = Matrix4.CreateTranslation(_position);
                }

                _transformationMatrix = scale * rotation * translation;
                _transformationDirty = false;
            }

            return _transformationMatrix;
        }

and replace Matrix4.CreateScale with Matrix4.Identity, my collisions work, but when I leave it that way, they won't work at all. I tested this with a BoxShape (50, 0.1, 50) and falling Cubes (BoxShapes).

When I put these lines into the demo project:


            Matrix4 rotation = Matrix4.CreateRotationX(0f) * Matrix4.CreateRotationY(0f) * Matrix4.CreateRotationZ(0f);
            Matrix4 scale = Matrix4.CreateScale(new Vector3(50f, 0.1f, 50f));
            Matrix4 translation = Matrix4.CreateTranslation(0f, -50f, 0f);

            // create the ground
            CollisionShape groundShape = new BoxShape(50, 50, 50);
            collisionShapes.Add(groundShape);
            CollisionObject ground = LocalCreateRigidBody(0, scale * rotation * translation, groundShape);
            ground.UserObject = "Ground";

I get a very weird effect that I don't quite understand. So what is the deal with scaling and how would I do it in this case?

AndresTraks commented 4 years ago

Bullet doesn't support scaling the transformation matrix. Try this: groundShape.LocalScaling = new Vector3(50f, 0.1f, 50f);

You'll need different shapes for different sized boxes.

NovemberDev commented 4 years ago

Thank you for the quick response!

I just tried that and there still is no collision with the scaled ground: https://streamable.com/1enu0

NovemberDev commented 4 years ago

I solved it!

If someone happens to have the same issue, here is what I did:

// don't apply rotation or scale
DefaultMotionState myMotionState = new DefaultMotionState(Matrix4.CreateTranslation(entity.Position));
// when you sync your transforms, apply scale:
Entity.TransformationMatrix = Matrix4.CreateScale(Entity.Scale) * World.CollisionObjectArray[i].WorldTransform;

Thank you for helping me :)

AndresTraks commented 4 years ago

There are a few ways to work with scales. 1) Pass the required dimensions to the BoxShape constructor and render a graphical box shape of the same size. Keep LocalScaling = 1.

2) Pass the required dimensions to the BoxShape constructor and render a unit box (size 1) scaled by the dimensions given to the BoxShape. Keep LocalScaling = 1. (I think this is what you did.)

3) Create a unit box "new BoxShape(1)" and scale it using LocalScaling. The graphics engine should render a unit box scaled by the dimensions given to the BoxShape and also by LocalScaling.

LocalScaling is more useful for complex shapes, e.g. if you have a triangle mesh shape that is difficult to scale otherwise.