Sign in to follow this  
kombatminipig

Verlet integration for angular movement using quaternions

Recommended Posts

I'm having a bit of trouble getting my verlet integration to work. I based my code on Baltmans paper on rigid bodies. The problem with it seems to be that the angular acceleration created by the torque seems to act as an angular velocity instead. Whenever I turn off the torque my object stops instantaneously, no motion seems to be retained through the verlet. My code is as follows: void Physics::calculateAngularVelocityVerlet( CState* state ) { const D3DXQUATERNION direction = state->get_direction(); const D3DXQUATERNION direction_old = state->get_direction_old(); const float dT = static_cast<float>( Common::getTimer( )->deltaTime( ) ); const D3DXVECTOR3 angular_torque = ( Common::Vec3Transform( &state->get_torque(), state->get_I_World_Inverse() ) ); D3DXQUATERNION direction_old_conjugate; D3DXQuaternionConjugate( &direction_old_conjugate, &direction_old ); D3DXQUATERNION angular_delta; D3DXQuaternionMultiply( &angular_delta, &direction, &direction_old_conjugate ); D3DXQuaternionNormalize( &angular_delta, &angular_delta ); D3DXQUATERNION direction_prim = angular_delta*direction; D3DXQuaternionNormalize( &direction_prim, &direction_prim ); D3DXQUATERNION angular_acceleration = 0.5*direction_prim*D3DXQUATERNION( angular_torque.x, angular_torque.y, angular_torque.z, 0 )*static_cast<float>( pow( dT, 2 ) ); D3DXQUATERNION direction_new = direction + angular_acceleration; D3DXQuaternionNormalize( &direction_new, &direction_new ); state->set_direction( direction_new ); state->set_direction_old( direction ); } Anybody see what's wrong? [Edited by - kombatminipig on March 20, 2007 2:05:50 PM]

Share this post


Link to post
Share on other sites
Hi, I don't use DX, so I can't read your code. However, following unoptimesed code, assuming timestep = 1.0, did orientation verlet integration quite successfully for me (it works correct only if angle between orns is smaller 180 degrees, good for ragdolls, bad for wheels).


// position...

pvec vel = (now[i] - old[i]) * damping;
pvec acc = force;
pvec mov = vel + acc;
old[i] = now[i] + mov; // old & new swapped afterwards

// orientation...

pquat avel = oldo[i].Inversed () * nowo[i];
//damp...
/*optional line*/ pquat idnt; idnt.Idnt (); // avel.Lerp (&avel, &idnt, adamping); // apply angular damping
avel.Normalize();// todo: required ?
oldo[i] = nowo[i] * avel;

Share this post


Link to post
Share on other sites
I'm not familiar with the concept of vertlet integration, but it's pretty obvious from your code that no direction change will occur if you stop having any torque. It's been a little while since I've studied torque, but I'm pretty sure the equations are almost completely analogous to linear motion...


You're going to need another variable in your state to keep track of angular velocity in any event. pseudo-code:


angular_acceleration = torque // (I assume the direction_prim*D3DXQUATERNION( angular_torque.x, angular_torque.y, angular_torque.z, 0 ))
angular_velocity += angular_acceleration*dt // stored variable
direction += angular_velocity*dt


Share this post


Link to post
Share on other sites
Okay, I just did a little research on verlet integration: one of the fundamental assumptions it makes is that the angular acceleration is constant. In other words, it's probably doing the *right* thing by stopping when you suddenly remove the acceleration. If your simulation cannot guarantee a constant angular acceleration, you'll need to switch to a different integration algorithm...such as the Euler integration I suggested previously or something of higher order

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this