AndresTraks / BulletSharpPInvoke

.NET wrapper for the Bullet physics library using Platform Invoke
http://andrestraks.github.io/BulletSharp/
150 stars 97 forks source link

No easy way to set rotation on a rigid body #22

Open Phong13 opened 8 years ago

Phong13 commented 8 years ago

Hi Andres,

This is more of a feature request and discussion than a bug, but I don't seem to have a way to get hold of you other than the Issue form.

I only seem to be able to rotate a rigid body by: getting the world transform, creating a rotation matrix, multiplying the matricies and writing the result back to the rigidbody world transform. This feels a lot heavier than it needs to be. Is there an easier way that I am missing? What I would like is a SetRotation (Quaternion q) method in the matrix class.

I also noticed that Bullet uses the btTransform class which is a 3x3 matrix and vector rather than the full 4x4 matrix. Is there a reason BulletSharp uses Matrix instead of wrapper for btTransform?

Thanks.

AndresTraks commented 8 years ago

Hi, The Matrix class in BulletSharp comes from SlimDX and just happens to not include a SetRotation method. Adding this and other methods from Bullet is not a problem.

Keep in mind that Matrix is a value type and doesn't wrap a native btTransform directly. This means that if you do this: collisionObject.WorldTransform.SetRotation(...) then what happens is that the WorldTransform value is copied into a temporary variable, the variable will have its rotation set and not written back to WorldTransform. So you still need to use a temporary variable, apply the operations and the write the variable back to the property.

It would be possible to make a Matrix class that points to a native btTransform and where all operations are performed directly in native memory (so SetRotation would apply immediately). But then both managed and unmanaged heap memory must be allocated for the results of many other matrix operations, which makes lots of work for the garbage collector. This is the main reason to avoid a btTransform wrapper. There's also some overhead for frequently going from managed to native mode.

btTransform is composed of a 3x3 rotation matrix and a 1x3 translation vector. It is still actually a 4x4 matrix in memory, because each row contains an additional entry for 16-byte memory alignment that is required for fast SSE instructions. Bullet can get away with 3x3, because it doesn't need shearing or perspective transforms. SlimDX is for graphics, so its Matrix class does use the fourth elements. It might be useful to keep the fourth column in BulletSharp, because matrices are often converted between BulletSharp and other graphics frameworks, so this would avoid any surprises. But this is open for discussion.

Good questions! :)

Phong13 commented 8 years ago

I think I will add a GetRotation, SetRotation(Quaternion q) method to the Matrix class. It seems to be a reasonably efficient solution for minimal work.

Phong13 commented 8 years ago

I added these, but while I was doing it I was wondering if the scaling ability should be removed from the Matrix class. It is more efficient if the rotation does not have to deal with scale, and a naive user may be tempted to scale the matrix which will break the btTransform class when they write it to the native object. Can you think of any drawback to removing the scaling ability from the Matrix class?

AndresTraks commented 8 years ago

Can you think of any drawback to removing the scaling ability from the Matrix class?

Not really. The original C++/CLI BulletSharp was focused on integration with existing graphics libraries, so supporting btTransform functions wasn't a priority. I don't think the PInvoke version will ever use Matrix classes from other frameworks. Dropping scaling/shearing will make some methods faster too, so I think it's a good idea. I'll look into cleanly rewriting the Matrix class based on Bullet code. Bullet-XNA has a working implementation, but it also includes scaling and extra stuff: https://github.com/xexuxjy/bullet-xna/blob/master/BulletXNA/LinearMath/IndexedMatrix.cs