Sign in to follow this  

Inertia tensor, minor but irritating problem

Recommended Posts

My rotations are working correctly, but they are all relative to body space. If I yaw my object by applying a torque on the Y axis, then add a torque along the X axis (pitch), it pitches, relative to the object's new heading. All I'm doing to add torque is adding it directly by axis. I've checked all my math, and the rotations don't seem to have any problem other than this, but this is a problem. Anyhow, here's the important code, in C:

MatrixMultiply(TensorTemp, Object[0].state.orientation, Object[0].state.InverseBodyInertiaTensor);
MatrixMultiply(Delta.InverseWorldInertiaTensor, TensorTemp, OrientationTranspose);

VectorByMatrixMultiply(AngularMomentumTemp, Delta.InverseWorldInertiaTensor, Object[0].state.angular_momentum);

// Convert angular momentum from vector to matrix
MatrixSkewSymmetric(AngularVelocity, Object[0].state.angular_momentum);  
// Scale momentum by time
MatrixByScalarMultiply(AngularVelocity, AngularVelocity, Delta.time);
// Convert angular momentum by axis to angular velocity by direction
MatrixMultiply(AngularVelocityTemp, AngularVelocity, Object[0].state.orientation);
// Add velocity to orientation
MatrixAdd(Object[0].state.orientation, Object[0].state.orientation, AngularVelocityTemp);

// Fix numerical drift so it doesn't discomboobulate our objects
MatrixOrthoNormalize(Object[0].state.orientation, Object[0].state.orientation);

// Translate force into momentum
Object[0].state.linear_momentum[Xcoord] += Delta.force[Xcoord] * Delta.time;
Object[0].state.linear_momentum[Ycoord] += Delta.force[Ycoord] * Delta.time;
Object[0].state.linear_momentum[Zcoord] += Delta.force[Zcoord] * Delta.time;

Object[0].state.angular_momentum[Xcoord] += Delta.torque[Xcoord] * Delta.time;
Object[0].state.angular_momentum[Ycoord] += Delta.torque[Ycoord] * Delta.time;
Object[0].state.angular_momentum[Zcoord] += Delta.torque[Zcoord] * Delta.time;

And here's my object local to worldspace transformation code (using Direct3D 9):
	for (int i = 0; i < 36; i++)
		ModelVertexBuffer[i].position.x = 
			ObjectModel[0].vertex[i].position.x * Object[0].state.orientation[0][0] +
			ObjectModel[0].vertex[i].position.y * Object[0].state.orientation[1][0] +
			ObjectModel[0].vertex[i].position.z * Object[0].state.orientation[2][0] +

		ModelVertexBuffer[i].position.y = 
			ObjectModel[0].vertex[i].position.x * Object[0].state.orientation[0][1] +
			ObjectModel[0].vertex[i].position.y * Object[0].state.orientation[1][1] +
			ObjectModel[0].vertex[i].position.z * Object[0].state.orientation[2][1] +

		ModelVertexBuffer[i].position.z = 
			ObjectModel[0].vertex[i].position.x * Object[0].state.orientation[0][2] +
			ObjectModel[0].vertex[i].position.y * Object[0].state.orientation[1][2] +
			ObjectModel[0].vertex[i].position.z * Object[0].state.orientation[2][2] +


	g_pObjectVB->Lock( 0, 36 * sizeof(CUSTOMVERTEX), (void**)&pVertexes, 0 );

	memcpy( pVertexes, ModelVertexBuffer, 36 * sizeof(CUSTOMVERTEX) ); 


Thanks for your attention.

Share this post

Link to post
Share on other sites
Well, I've tried to cancel out the local effects of the rotation to make the rotation added from torque valid in a world reference frame by multiplying the torque by the orientation matrix transpose (inverse rotation matrix), and it works, for all of about 90 degrees. As it spins, it slows down and eventually locks at 90. I'm sure the reason why will become apparent if I think on it for a while, it's even kinda halfway there already...But I don't know if it will bring me any closer to my answer :)

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