Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Member Since 05 Nov 2005
Offline Last Active Yesterday, 12:15 PM

Posts I've Made

In Topic: Rigid Body Physics - Inertia Tensor Space

28 April 2015 - 04:48 AM

I was pointed out by a friend that in the modified version I should skip the last line. So the coude should look this:

        oriMat = quaternion.ToMatrix(self.ori)
        self.totalTorque = vector.Transform(self.totalTorque, matrix.Inverted(oriMat))
        angAcc = vector.Transform(self.totalTorque, matrix.Inverted(self.inertia_local))

And indeed that works. I wrote down on paper all these transforms and this code gives the exact same series of transforms as the original one.



angAcc = torque * inertia^-1 = torque_world * (inertia_local * localToWorld)^-1 = torque_world * localToWorld^-1 * inertia_local^-1

Clearly this gives angAcc in world-space what I need.


The modified new:

angAcc = torque * inertia^-1 = (torque_world * localToWorld^-1) * inertia_local^-1 = torque_world * localToWorld^-1 * inertia_local^-1

This I would expect to give me angAcc in local-space (which further needs to be mul'led by localToWorld to be in world space) but math clearly shows this is the same as the previous formula.


Anyone sees what is wrong with my understanding? :)

In Topic: Rigid Body Physics - Inertia Tensor Space

20 April 2015 - 03:46 AM

I am glad it works, but personally I would be suspicious and assume I might potentially miss a transform somewhere.

I'm almost  sure this code works fine. The rigid body behaves quite predictably and very similar to simulation I made in Unity.

I could share my code if anyone wanted to play with it.


I'd also be happy if anyone could look again at the original code, which works, and its other variant that I think should work as well but for some reason doesn't.

Original code:

        oriMat = quaternion.ToMatrix(self.ori)
        inertia_world = self.inertia_local * oriMat
        angAcc = vector.Transform(self.totalTorque, inertia_world)

To recap: oriMat is effectively local-to-world transform. self.totalTorque is torque in world space. So this code transforms local inertia to world inertia and uses its inverse along with world torque to compute world angular acceleration.


Modified version:

        oriMat = quaternion.ToMatrix(self.ori)
        self.totalTorque = vector.Transform(self.totalTorque, matrix.Inverted(oriMat))
        angAcc = vector.Transform(self.totalTorque, matrix.Inverted(self.inertia_local))
        angAcc = vector.Transform(angAcc, oriMat)

Here I wanted to do the torque-inertia transform in local space. To do so, I transform self.totalTorque to rigid body's local space using inverse of oriMat. Then I mul that by inverted local inertia to get angular acceleration in local space. Finally, I transform angular acceleration to world space by transforming it with oriMat.

For some reason this variant doesn't yield correct behaviour of my rigid body and I really can't tell why. Anyone?

In Topic: Normal Map Generator (from diffuse maps)

18 April 2015 - 04:57 AM

Okay so that's solution for the brick texture. But I have dozens of other textures as well and really no time to be that careful about generating their normals maps, given that 99% of players won't notice any difference at all ;)

In Topic: Rigid Body Physics - Inertia Tensor Space

18 April 2015 - 04:42 AM

I think we're misunderstanding each other a bit here smile.png.

First of all, the code I posted works perfectly fine. And I transform the local inertia tensor to world inertia tensor (in column-major order) like this:

I_world = R * I_local

which is these parts of my code (note row-major order):

    oriMat = quaternion.ToMatrix(self.ori)
    inertia_world = self.inertia_local * oriMat

And I think this the "real" world inertia tensor. In general case, when you have a vector V in some local space, have local-to-world matrix transform, and want to get vector V in world space you do this:

V_world = local-to-world * V_local

not this:

V_world = local-to-world * V_local * world-to-local

I think your solution:

I_world = R * I_local * transpose(R)

is only "valid" in this specific formula:

L = R * I_local * transpose(R) * omega_world

but it's not because of this:

L = ( R * I_local * transpose(R) ) * omega_world

but because of this:

L = R * I_local  * ( transpose(R) * omega_world )

The "interpretation" for me here is that we take omega_world, transform it to local space (hence mul by transpose of R), then we can mul by local inertia (because omega is now in local space) and finally we take all this to world space by mul with R.


Sorry guys but I'm a proponent of row-major order and I'm going to use it ;).

In Topic: Rigid Body Physics - Inertia Tensor Space

17 April 2015 - 08:02 AM

I think I understand Dirk's explanation but it is described in terms of angular momentum whereas what I need is angular acceleration. I also looked again at those Siggraph notes and it appears they compute angular velocity using the inertia (1) and angular momentum. In my code however I compute angular velocity by integrating angular acceleration, which is computed from torque and intertia (2). Any "my" inertia (2) is different than inertia (1), that is, I compute world inertia using just one local-to-world matrix whereas world inertia (1) is computed using local-to-world and world-to-local.

I can't see where the Siggraph notes make use of the torque.