   self righting an object in 3D
  Hi all quick question...I have a 3D object who's orientation is represented primarily by a quaternion. Derived from this I have it's forward, up right vectors and of course it's matrix. What I'd like to do is create the shortest rotation about it's own axes that will return it to facing up, forward and level as in a right handed coord system.This will in turn be fed into my simulation as a torque to apply to the body to rotate it slowly back to the intended orientation.Can anyone hint me in the right direction? My brain is... well, y'know that feeling ;).Thanks in advance!   
  I am not a expert in these.. My though is like this.You can get Euler angles from qutaernion , so looking that, it may be possible to find the shortest rotation. Other thing is if you know the current view direction , you can create a rotation matrix to make it point to the default direction(in RHS). that is fairly easy, using cross product of vectors.  But i am not sure whether it is the shortest rotation or not. But after creating a rotation matrix, it really doesn't matter whether it is shortest or longest (any you need to multiply with vector).;  Ok I've managed to do this using good old trig - here's my work:void SelfRight(void) {k8Vector yawAxis, pitchAxis, rollAxis;    //obtain fastest rotations about each individual axis compared to the 'right'ed axisVectorAxisAngleBetween(yawAxis,   _controlledObject->_forward, zAxisVector);VectorAxisAngleBetween(pitchAxis, _controlledObject->_up, yAxisVector);VectorAxisAngleBetween(rollAxis,  _controlledObject->_right, xAxisVector);    //set the thruster force direction to match the individual rotation components for each required rotation axisthruster._direction[0] = pitchAxis[0];thruster._direction[1] = yawAxis[1];thruster._direction[2] = rollAxis[2];    //damp the torque applied depending on how close we are to target yawfloat pwr = yawAxis[1]*_controlledObject->maxThrusterPower();if( yawAxis[1] < 0.f && _accumYaw < pwr ){ thruster._direction[1] = -thruster._direction[1];} else if( yawAxis[1] > 0.f && _accumYaw > pwr ){ thruster._direction[1] = -thruster._direction[1];}    //damp the torque applied depending on how close we are to target roll pwr = rollAxis[2]*_controlledObject->maxThrusterPower();if( rollAxis[2] < 0.f && _accumRoll < pwr ){ thruster._direction[2] = -thruster._direction[2];} else if( rollAxis[2] > 0.f && _accumRoll > pwr ){ thruster._direction[2] = -thruster._direction[2];}    //damp the torque applied depending on how close we are to target pitch   pwr = pitchAxis[0]*_controlledObject->maxThrusterPower();if( pitchAxis[0] < 0.f && -_accumPitch < pwr ){thruster._direction[0] = -thruster._direction[0];} else if( pitchAxis[0] > 0.f && -_accumPitch > pwr ){thruster._direction[0] = -thruster._direction[0];}}Seems to work nicely - seems a bit long winded, was hoping for a one-liner! By the way the _accum values are just the current angular velocity of the object in those specified self axes.   