Wednesday, 13 July 2011

Developer Journal 112 - On Bullet Physics Constraints

I've been trying to work out how to set up some simple constraints. I looked at how the elbow joints worked in the Bullet Physics Rag Doll Demo. I created two blocks and created a hinge constraint between them but the blocks kept flying up into the air.

I read a post on the Bullet Physics Forum and the Bullet Physics manual. I did not understand pivot and axis points. I also kept thinking that for a hinge constraint you need to specify three points, one for each block and one for the pivot.


That was Friday. It came to me on Saturday morning in bed. You have to think about it the other way around. The easiest way is to image one block and one pivot point. Imagine the block is a door. The pivot point is the part where it attaches to the wall. You can have the pivot point further away from the door by attaching more wood to the door so that it reaches the wall.

Now imagine the block is your lower arm and the pivot point is the elbow. The upper arm is the other block and the pivot point is also the elbow. All this means that you don't need to specify three points for a hinge constraint, only two.

The next thing I realised was that the axis specifies the direction of the hinge. For a door, the direction of the hinge is vertical. If you were to do a chest thump, the elbow hinge direction is vertical. If you were to block your ears, your elbow hinge is roughly horizontal.


I went back and placed my new found ideas into practice but the blocks still kept flying up into the air. The problem was the object rotations. I took out the rotation code and left the objects with their default rotations and it worked! I could bend the hinge constraint between the two blocks.

The next problem was how do I make the joint bend slowly? The constraint refused to move at slow target velocities. The minimum was about 0.8 something per something. It did not matter whether the constraint had a large maximum impulse.


After fiddling around, I tried controlling the target angle. Still no luck. The problem was that when I got the current angle and added the increment, the increment was too small to matter got lost in the calculations. The solution was to have a separate counter that I could increase slowly over time and set that as the target angle. The other thing I had to do was to tell the blocks not to deactivate.

I could now vary the angle I want at the speed I wanted. There was a post on the Bullet Physics Forum which I participated in where another user had the same problem.

The next thing to do was to figure out how bend constraints in more than one direction at the same time. For example, your shoulder joint can go up, down, forward, back, twist clockwise, and twist anti-clockwise. The problem was that setting constraints such as the generic six degrees of freedom constraint required that I learn how to set rotations using quaternions.

So I tried converting my hinge constraint code that used a vector to the hinge constraint code that used a quaternion. I know how to use

btHingeConstraint( btRigidBody &rbA, btRigidBody &rbB, const btVector3 &pivotInA, const btVector3 &pivotInB, btVector3 &axisInA, btVector3 &axisInB, bool useReferenceFrameA=false )

I'm trying to learning how to use

btHingeConstraint( btRigidBody &rbA, btRigidBody &rbB, const btTransform &rbAFrame, const btTransform &rbBFrame, bool useReferenceFrameA=false )

in order to learn how to use

btGeneric6DofConstraint( btRigidBody &rbA, btRigidBody &rbB, const btTransform &frameInA, const btTransform &frameInB, bool useLinearReferenceFrameA )

With the hinge constraint code, I used a vector with the values ( 0.0f, 1.0f, 0.0f ).

I then got the quaternion back from the constraint. The quaternion had an axis vector of ( -1.0f, 0.0f, 0.0f ) and an angle of 1.571. Weird.

I also got the Euler yaw, pitch, and roll values which were ( 0.0f, 0.0f, -1.571 ) respectively. The Euler angles around Z, Y, X had the same values. Weird.


I realised that the strange quaternion axis was because we are looking down the negative X axis. That means that I could get the same result by looking down the positive X axis and negating the angle, so the values would be ( 1.0f, 0.0f, 0.0f ) and -1.571.

It worked! I can now use quaternions to set rotations! Muahahahaha!


No comments:

Post a Comment