I implemented simple rigid body system (simulating a simple box in 3D) and am confused about the space the inertia tensor should be, or to be more precise, how to compute the proper space.
I'll just dive into pretty simple code (Python).
Force addition to rigid body:
def AddForce(self, force, point):
self.totalForce = self.totalForce + force
oriMat = quaternion.ToMatrix(self.ori)
r = point - self.pos
torque = vector.Cross(r, force)
self.totalTorque = self.totalTorque + torque
Note here that ori is orientation quaternion. Point, self.pos and forces are all provided in world space.Now integration:
def Integrate(self, deltaTime):
linAcc = 1.0/self.mass * self.totalForce
oriMat = quaternion.ToMatrix(self.ori)
inertia_world = self.inertia_local * oriMat # HERE
matrix.Invert(inertia_world)
angAcc = vector.Transform(self.totalTorque, inertia_world)
self.pos = self.pos + self.linVel*deltaTime
self.ori = quaternion.AddVector(self.ori, self.angVel*deltaTime)
self.ori = quaternion.Normalized(self.ori)
self.linVel = self.linVel + linAcc*deltaTime
self.angVel = self.angVel + angAcc*deltaTime
self.totalForce = vector.Vector3()
self.totalTorque = vector.Vector3()
As you can see, in line "HERE" I calculate the inertia tensor in world space, by simply multiplying the local inertia matrix by the rigid body's orientation matrix (which is effectively the local-to-world matrix without the translation part).Note that I use row-major matrix order.
The way I transform the local inertia tensor seemed natural to me this way. I have local space, I have local-to-world transform, so I just mul by that matrix to get inertia in world space. And it works just fine. I even made a simple simulation in Unity using their rigid body to make sure that my behaves more or less the same. And it does.
However, I googled a bit about the inertia tensor transform and found that people do it differently. For instance here:
http://gamedev.stackexchange.com/questions/70355/inertia-tensor-and-world-coordinate-conversion
or here:
http://www.pixar.com/companyinfo/research/pbm2001/pdf/notesg.pdf (code on page G22).
They both suggest "embedding" the local tensor matrix in between local-to-world and transpose(local-to-world). But when I do this in my simulation it simply works incorrectly.
Any idea where this difference comes from?