## NewtonCompoundCollisionCalculateInertialMatrix

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

### NewtonCompoundCollisionCalculateInertialMatrix

Are there plans to make a function like NewtonCompoundCollisionCalculateInertialMatrix ?

I need a generalized way to calculate full inertia matrixes and a center of mass for a arbitrary compounds collisions.

I guess you could assume the same mass density for all shapes.

right now I'm using NewtonConvexCollisionCalculateInertialMatrix. (which seems to expect only one convex shape?).

I need a routine that actually sums up volumes of all shapes and based on each shape's offset from some arbitrary center calculates the COM and FULL Inertial Matrix.
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

### Re: NewtonCompoundCollisionCalculateInertialMatrix

coumpounds are assume to be convex.
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: NewtonCompoundCollisionCalculateInertialMatrix

So NewtonConvexCollisionCalculateInertialMatrix() is all I should need? I am seeing weird behalvior when I change my PhysicsWorldScale parameter - when all shapes are smaller the Inertia still seems large (hard to rotate the objects)

Is NewtonConvexCollisionCalculateInertialMatrix() fully accounting for all subshapes and offsets or is there still work there?
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

### Re: NewtonCompoundCollisionCalculateInertialMatrix

I calculate a unit inertia,
you need to multiply by the mass;

if you look at the function
NewtonBodySetMassProperties (rigidBody, mass, collision);

it call this, you see that It takes the mass as parameter,

Code: Select all
`void dgBody::SetMassProperties (dgFloat32 mass, const dgCollisionInstance* const collision){   // using general central theorem, to extract the Inertia relative to the center of mass    dgMatrix inertia (collision->CalculateInertia());   dgVector origin (inertia.m_posit);      for (dgInt32 i = 0; i < 3; i ++) {      inertia[i][i] = (inertia[i][i] + origin[i] * origin[i]) * mass;      for (dgInt32 j = i + 1; j < 3; j ++) {         dgFloat32 crossIJ = origin[i] * origin[j];         inertia[i][j] = (inertia[i][j] + crossIJ) * mass;         inertia[j][i] = (inertia[j][i] + crossIJ) * mass;      }   }   // although the engine fully supports asymmetric inertia, I will ignore cross inertia for now   //SetMassMatrix(mass, inertia[0][0], inertia[1][1], inertia[2][2]);   SetCentreOfMass(origin);   SetMassMatrix(mass, inertia);}`

if you look at

Code: Select all
`void NewtonConvexCollisionCalculateInertialMatrix(const NewtonCollision* convexCollision, dFloat* const inertia, dFloat* const origin){   TRACE_FUNCTION(__FUNCTION__);   dgCollisionInstance* const collision = (dgCollisionInstance*)convexCollision;//   dgVector tmpInertia;//   dgVector tmpOringin;//   collision->CalculateInertia(tmpInertia, tmpOringin);   dgMatrix tmpInertia (collision->CalculateInertia());   inertia[0] = tmpInertia[0][0];   inertia[1] = tmpInertia[1][1];   inertia[2] = tmpInertia[2][2];   origin[0] = tmpInertia[3][0];   origin[1] = tmpInertia[3][1];   origin[2] = tmpInertia[3][2];}`

they both use the same function

dgMatrix tmpInertia (collision->CalculateInertia());
then by the body one scale the diagonal and of diagonal by the mass and the
also apply the central theorem, for the case when the inertia is off.
you probably for no have to do that ,
but you can just copy the bit of code and do on your side.
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: NewtonCompoundCollisionCalculateInertialMatrix

the way is set u is that you use function blindly
NewtonBodySetMassProperties (rigidBody, mass, collision);

the will do the job correctly assuming the body is a dynamics body with some sort of axis of symmetry.
because it is a NewtonCreateDynamicBody

if you nee to use weird inertia where the off diagonal of the body have a significant value compared to the diagonal, the you moust cerate your body using function
NewtonBody* NewtonCreateAsymetricDynamicBody

then say to know the mass of you a scale body, you do no use calculate inertia, instead you use
dFloat NewtonConvexCollisionCalculateVolume (const NewtonCollision* const convexCollision);

this give you the volume which is a scalar value, so you can calculate the mass of the body by simple doing

mass = density * NewtonConvexCollisionCalculateVolume (convexCollision);

where convex collision can be a compound or any convex primitive.

you can also make heterogeneous inertia using convex and scale.

say you have a dumbbell with one side made of iron and the other made of led.
the but have the same volume by the have different mass.

you make the collision and make the body with the collision that have the two shape with the same size.
you make a keeper chapel that scale one of the bell by the ration of the density of the of iron and led, now you have a compound with sub shape the will have a uniform density by different sizes.

calling NewtonBodySetMassProperties (rigidBody, mass, collision);
will set the correct inertia.
so you can see that mass is a much better parameter than density for these kind of exoteric stuff.
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: NewtonCompoundCollisionCalculateInertialMatrix

ok thanks, Im confused as to the state of SetMassProperties - it looks like it is doing computation on the cross interia elements. but it still says :
Code: Select all
`// although the engine fully supports asymmetric inertia, I will ignore cross inertia for now`

honestly Id rather have it computing the full thing.
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

### Re: NewtonCompoundCollisionCalculateInertialMatrix

I can guarantee you that you do not want to simulate with general asymmetric inertia.
all the literature I ever read about dynamics, the first thing is decompose the body alone the principal axis of the inertia.

As a matter of practicality, the newton library assumes the axis of the body will be either aligned or closely aligned to the principal axis of inertia or in the case that is not like spheres or boxes is because the body has one or two axis of simetry.

this covers about 90% of all rigid body dynamics: cars, airplains, people, etc.
when you add that object that are not quite symmetric has the principal axis are almost aligned, them that's more than 99% in my opinion.

them you are left with the objects that are truly asymetrics objects like asteroid or the rattle back.
For those we still use the principal axis but we store the aligment axis in another matrix, then it is used each time to compute the full inertia which will generate the cross inertia each time.

the reason that comment is there is because the math of a problem always gives you many solutions, but the physics does not need to use them all.
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: NewtonCompoundCollisionCalculateInertialMatrix

ok - Im using NewtonBodySetMassProperties() now. If I want to have seperate densities for subshapes I'll have to tear out some code and make my own matrix.
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

### Re: NewtonCompoundCollisionCalculateInertialMatrix

all you need to do is calculate the mass using the volume of the scaled collision and the density.
and it should work for most objects.

for the more complex ones, is the same but now is the mass is summation of densities * volumes of each sub shape.
once you get it you see is much easier then calculation inertias, you can even see it is the same process repeated over an over, but in scalar arithmetic rather that matrixes or vector since the engine does the heavy work for you, here is the proof.

mass = sum (density0 * voume0 + density1 * voume2 + density3 * voume3 + ...)

if the density is uniform, it becomes

mass = sum (density * voume0 + density * voume2 + density * voume3 + ...)

mass = density * sum (voume0 + voume2 + voume3 + ...)

but that's the total volume

mass = density * volume.

and that why there is a CalcVolume function and no a CalcInertia using density or mass.
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: NewtonCompoundCollisionCalculateInertialMatrix

I think I got it! I am now using 2 passes when forming my bodies which I think is what you were saying.

1st pass: create body with all subshapes scaled by their material density. calculate and store inertia matrix and COM.
2nd pass. create body with all subshapes scaled normally. apply saved interia matrix and COM.
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

### Re: NewtonCompoundCollisionCalculateInertialMatrix

no quite. these are the steps.

1 make a collision shape with the scale you want
2 make a rigid body
3 get the collision volume.
4 calculate the mass as volume × density
5 set the mass property, pass in the mass and collision.

if the body has a heterogeneous collision shape.
step 2.5 you iterate over each sub shape setting the scale of those sub shapes which do not have a density ratio of one.

that's all you need to do.
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: NewtonCompoundCollisionCalculateInertialMatrix

Ok, I am no longer recreating the rigid body unnecessarily in my routine.

Now Taking a few steps back for testing purposes I have setup a test:

I spawn 2 "Dumbbell" setups which are simply 2 cubes attached to each other with distance between them. There is no shape for the rod between them. The Density of both cubes is always 1.

The First Setup:
2 RigidBodies attached with a dCustom6dof contraint with no rotational or translational freedom (fixed).

The Second Setup:
1 RigidBody with a compound with 2 subshapes.

Both setups are spawned in the world. And I expect that (ignoring effects coming from the joint solver) both setups would behalve similarly.

However something is wrong because the second setup shows allot more resistance to rotational change.

Last edited by MeltingPlastic on Tue Oct 30, 2018 4:57 pm, edited 1 time in total.
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

### Re: NewtonCompoundCollisionCalculateInertialMatrix

I know I'm pounding this to death.

Is there a physics rule that a rigid body can not have mass distributed in 2 separate Islands? I cant image this would be the case because I could just add a thin rod shape to connect the 2 islands.
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

### Re: NewtonCompoundCollisionCalculateInertialMatrix

MeltingPlastic wrote:Is there a physics rule that a rigid body can not have mass distributed in 2 separate Islands?

I do not know what that means.
Julio Jerez
Moderator

Posts: 11153
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

### Re: NewtonCompoundCollisionCalculateInertialMatrix

By Island I mean a volumetric region with mass.

Usually in physics papers I am looking at a rigid body has all its mass connected. It may be shaped weirdly - like an asteroid. But its all connected.

Anyway - do you agree the dynamics of both tests should be similar in the demo given I am doing the computation right?
MeltingPlastic

Posts: 221
Joined: Fri Feb 07, 2014 11:30 pm

Next