Compound collision and center of mass

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: Compound collision and center of mass

Postby Julio Jerez » Mon Jul 23, 2012 1:20 pm

where is that at?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound collision and center of mass

Postby PJani » Mon Jul 23, 2012 2:19 pm

Julio Jerez wrote:The above code assumes uniform density, on a compound, by you can do a very simple trick. to get it do the inertia for different density.
Basically the trick is to prescale the sub shapes to match and shape of a uniform density.
This is how. Say the compound only has one box. Of dimension (X x Y x Z)
The inertia of any object of uniform mass is given by
Sum (Mi * xi * xi)
Since the mass if uniform you can actually factor the mass from the equation and use the sumation of each point particle. thist is a practice used in mechanical and civil
engineering when for specifying the shape of Beam and othe premaded construction materials. For cross sections it is called Area of Inertia, for a volume is called Volume of Inertia.
This simplifies dealing with building material of the same shape but of different marterials.
a typical exercise in mechanic 101 is to calculate the size a Wood Beam would have to be to have the strength of a give steel steal bean of the same shape.
The answerer is you multiple the steel beam cross section size by the square root of the ratio of densities between wood and steel.
You can do the same for a compound collision, here are the steps:

-make your compound collision
-save the scale of each shape.
-take the mass of any of the shape in the compound (the first is just as s good)
-iterate over the rest of all shapes
-For each shape set the scale to be ShapeScale = sqrt (shapeMass / referenceMass)
-calculate the inertia of the scaled compound.
-Multiply the inertia o feth scaled compound by (Numbershapes * referenceMass) his is the total inertia
-Interate again restoring the original size of each sub shape



Pardon :D i forgot to specify from where i took that :D

Btw i have problem... i have to call BeginCompound EndCompound so scales are properly taken in account
-make your compound collision
-save the scale of each shape.
-take the mass of any of the shape in the compound (the first is just as s good)
NewtonCompoundCollisionBeginAddRemove
-iterate over the rest of all shapes
-For each shape set the scale to be ShapeScale = sqrt (shapeMass / referenceMass)
NewtonCompoundCollisionEndAddRemove


-calculate the inertia of the scaled compound.
-Multiply the inertia o feth scaled compound by (Numbershapes * referenceMass) his is the total inertia
NewtonCompoundCollisionBeginAddRemove
-Interate again restoring the original size of each sub shape
NewtonCompoundCollisionEndAddRemove

I dont know how good idea is to call so much times begin/end compound
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Compound collision and center of mass

Postby Julio Jerez » Mon Jul 23, 2012 3:43 pm

I think that is a typo.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound collision and center of mass

Postby PJani » Mon Jul 23, 2012 5:00 pm

I have one REALY REALY REALY weird bug when using scaling...it seems that some how sub collisions must be realigned when scaling and they are not scaling from their local center! that why i have miss aligned com
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Compound collision and center of mass

Postby PJani » Mon Jul 23, 2012 6:50 pm

Seriusly i am not joking i have sub collision located at position 0,0,0 and when i scale it up it moves from 0,0,0 to some other x,x,x position

i am using NewtonCollisionSetScale

this is how my code looks
Code: Select all
      Ogre::Vector3 inertia(0,0,0);
      Ogre::Vector3 com(0,0,0);

      if(m_collisions.size())
      {
         CollisionInfoMap::iterator it = m_collisions.begin();
         float refMass = it->second.mass;
         if(refMass>0)
         {
            NewtonCompoundCollisionBeginAddRemove(m_compound);

            float invRefMass = 1/refMass;
            for(;it!=m_collisions.end();it++)
            {
               NewtonCollision* nc = NewtonCompoundCollisionGetCollisionFromNode(m_compound, it->second.handle);

               float mass = it->second.mass;

               dFloat scale = (mass * invRefMass);

               //std::cout << scale << std::endl;

               dFloat sX,sY,sZ;

               NewtonCollisionGetScale(nc,&sX,&sY,&sZ);
               NewtonCollisionSetScale(nc,sX*scale,sY*scale,sZ*scale);
            }

            NewtonCompoundCollisionEndAddRemove(m_compound);

            NewtonConvexCollisionCalculateInertialMatrix(m_compound, &inertia.x, &com.x);

            inertia *= m_collisions.size() * refMass;

            //NewtonCompoundCollisionBeginAddRemove(m_compound);

            //it = m_collisions.begin();
            //for(;it!=m_collisions.end();it++)
            //{
            //   NewtonCollision* nc = NewtonCompoundCollisionGetCollisionFromNode(m_compound, it->second.handle);

            //   float mass = it->second.mass;

            //   float scale = (mass * invRefMass);

            //   float sX,sY,sZ;

            //   

            //   NewtonCollisionGetScale(nc,&sX,&sY,&sZ);
            //   NewtonCollisionSetScale(nc,sX/scale,sY/scale,sZ/scale);
            //}

            //NewtonCompoundCollisionEndAddRemove(m_compound);
         }
      }


Please Julio check this because it looks like a bug. I will even create test demo if you need for your sandbox
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Compound collision and center of mass

Postby Julio Jerez » Tue Jul 24, 2012 7:02 am

there is no bug, the scale is applied globally not locally.
the form general of the transform matrix is like this

p = M * S * W

p = the location of a point in the collision
M = the collision local matrix
S = is a diagonal matrix representing the scale
W is the Rigid body matrix

when the position component of M is zero, scaling work relative to the origin
say is a box (1 x 1 x 1) at location zero, is scaled by 2 it will be a box (2 x 2 x 2) at location zero
but is the same box is a location (1, 2, 1) it will be a box (2 x 2 x2) at location (2, 4, 2) after scaling

This is the correct way to apply scale.

if you want a local Scale this above method also support that.
basically all it need to not is calculate the scale matrix using a similar transformation
this is possible because in the above equation S is a general matrix, no assumption is made anywhere that is a diagonal matrix.
For a local scale the S should be set like as follows
-first transform the shape to the origin by applying inv (M)
-then scale the shape by multiplying by S
-Transform the body back to it old position by mutip[ly by M

you get

p = M * (inv(M) * S * M) * W

as you can see when the above expression is executed you get

p = S * M * W

as it is now although the expression for scaling is Generic, the for simplicity the interface only expose the
an way to pass a diagonal scale matrix, in the case of a local scaling inv(M) * S * M
becomes a PSD matrix (Symmetric Positive definitive)
for most without training on linear algebra massing a matrix of that type to simply scale and shape, is too complicated and confusing,. therefore is decided to expose the diagonal matrix which use three numbers:

void NewtonCollisionSetScale (const NewtonCollision* const collision, dFloat scaleX, dFloat scaleY, dFloat scaleZ);

what I can do is that I can add a secund funtion

void NewtonCollisionSetLocalScale (const NewtonCollision* const collision, dFloat scaleX, dFloat scaleY, dFloat scaleZ);
that will do the above calculation ans set the proper matrix.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound collision and center of mass

Postby Julio Jerez » Tue Jul 24, 2012 7:40 am

Ok I added the local scale function void NewtonCollisionSetScaleLocal (const NewtonCollision* const collision, dFloat scaleX, dFloat scaleY, dFloat scaleZ);
I did not tested but I believe is should work
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound collision and center of mass

Postby PJani » Tue Jul 24, 2012 7:42 am

That would be great if you add local scale function :) I didn't know the position is taken into account too! :roll:

edit: i will checkout repo :D
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Compound collision and center of mass

Postby PJani » Tue Jul 24, 2012 7:47 am

Hmm when i try to build releaseDll i get

Code: Select all
4>..\..\..\source\meshUtil\dgMeshEffect5.cpp(1987) : error C2039: 'Trace' : is not a member of 'dgHugeVector'
4>        p:\cpp\netown_branch\corelibrary_300\source\core\dgGoogol.h(94) : see declaration of 'dgHugeVector'
4>..\..\..\source\meshUtil\dgMeshEffect5.cpp(1988) : error C2039: 'Trace' : is not a member of 'dgHugeVector'
4>        p:\cpp\netown_branch\corelibrary_300\source\core\dgGoogol.h(94) : see declaration of 'dgHugeVector'
4>..\..\..\source\meshUtil\dgMeshEffect5.cpp(1994) : error C2039: 'Trace' : is not a member of 'dgHugeVector'
4>        p:\cpp\netown_branch\corelibrary_300\source\core\dgGoogol.h(94) : see declaration of 'dgHugeVector'
4>..\..\..\source\meshUtil\dgMeshEffect5.cpp(1998) : error C2039: 'Trace' : is not a member of 'dgGoogol'
4>        p:\cpp\netown_branch\corelibrary_300\source\core\dgGoogol.h(37) : see declaration of 'dgGoogol'
4>..\..\..\source\meshUtil\dgMeshEffect5.cpp(1999) : error C2039: 'Trace' : is not a member of 'dgGoogol'
4>        p:\cpp\netown_branch\corelibrary_300\source\core\dgGoogol.h(37) : see declaration of 'dgGoogol'
...
5>------ Build started: Project: newton, Configuration: releaseDll Win32 ------
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Compound collision and center of mass

Postby Julio Jerez » Tue Jul 24, 2012 9:56 am

Trace is debug code for those classes, It is comemted out now, try again.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound collision and center of mass

Postby PJani » Tue Jul 24, 2012 4:38 pm

I dont know why but i get same effect...

my sub collisions are constructed like this...
Code: Select all
        float matrix[16];
        OgreNewt::Converters::QuatPosToMatrix( orient, pos, &matrix[0] );

      
        //make the collision primitive.
        NewtonCollision* sub_col = NewtonCreateConvexHull( m_body->getWorld()->getNewtonWorld(), vertex_count, (float*)&cloud[0].x, sizeof(Ogre::Vector3), 0.0f, collision_id, &matrix[0]);


And the problem here is not just i get shifted sub collision but when i try getting position of sub collision it returns right position! i am a bit confused

If you see the screen you will know what is happening! True positions are reported by NewtonCollisionGetMatrix and same as they where created
Attachments
newton_scaling.png
newton_scaling.png (223.88 KiB) Viewed 4416 times
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Compound collision and center of mass

Postby Julio Jerez » Wed Jul 25, 2012 8:18 am

you are right something is still wrong

I though that the only varuble I need to remove was vector invScale, but I still use the disginal version i some places liek

Code: Select all
inline void dgCollisionInstance::DebugCollision (const dgMatrix& matrix, OnDebugCollisionMeshCallback callback, void* const userData) const
{
   dgMatrix scaleMatrix (dgGetIdentityMatrix());
   scaleMatrix[0][0] = m_scale[0];
   scaleMatrix[1][1] = m_scale[1];
   scaleMatrix[2][2] = m_scale[2];
   m_childShape->DebugCollision  (m_localMatrix * scaleMatrix * matrix, callback, userData);
}



I need to go ove and remove all places where m_scale i sused and replace with m_scaleMatrix
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound collision and center of mass

Postby Julio Jerez » Wed Jul 25, 2012 9:01 am

Oh it turned out that DebugDisplay was the only function that was using the vector form of scale, everything else was using the matrix form.
the engine use debug display for many things so some stuff will be wrong.

I fixed now try again.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Compound collision and center of mass

Postby PJani » Wed Jul 25, 2012 9:38 am

Ok this is getting funny...i made demo in your sandbox and it works...meanwhile in my project it fails the same way as it did before...only explanation there is the OgreNewt converter is failing to convert between your matrix and ogre quaternions

Can you confirm this is right!?
Code: Select all
        //! Take a Newton matrix and create a Quaternion + Position_vector
        void MatrixToQuatPos( const float* matrix, Ogre::Quaternion& quat, Ogre::Vector3 &pos )
        {
            // this takes a matrix returned by Newton, and creates a Quaternion
            // and position Vector3, which is more meaningful for Ogre.
            using namespace Ogre;
            quat = Quaternion( Matrix3( matrix[0], matrix[4], matrix[8],
                              matrix[1], matrix[5], matrix[9],
                              matrix[2], matrix[6], matrix[10] ) );
       
            pos = Vector3( matrix[12], matrix[13], matrix[14] );
        }

        //! Take a Quaternion and Position Matrix and create a Newton-happy float matrix!
        void QuatPosToMatrix( const Ogre::Quaternion& _quat, const Ogre::Vector3 &pos, float* matrix )
        {

            // this takes a Quaternion and a Vector3 and creates a float array
            // which is more meaningful to Newton.

            using namespace Ogre;
            Matrix3 rot;
            Vector3 xcol, ycol, zcol;
           
         Ogre::Quaternion quat (_quat);
         quat.normalise();
            quat.ToRotationMatrix (rot);   // creates a 3x3 rotation matrix from the Quaternion.

            xcol = rot.GetColumn(0);
            ycol = rot.GetColumn(1);
            zcol = rot.GetColumn(2);
       
            // now fill the final matrix with the appropriate data:
            matrix[0] = xcol.x;
            matrix[1] = xcol.y;
            matrix[2] = xcol.z;
            matrix[3] = 0.0f;
       
            matrix[4] = ycol.x;
            matrix[5] = ycol.y;
            matrix[6] = ycol.z;
            matrix[7] = 0.0f;
       
            matrix[8] = zcol.x;
            matrix[9] = zcol.y;
            matrix[10] = zcol.z;
            matrix[11] = 0.0f;
       
            matrix[12] = pos.x;
            matrix[13] = pos.y;
            matrix[14] = pos.z;
            matrix[15] = 1.0;
        }


BTW i am "drawing" debug lines with NewtonCollisionForEachPolygonDo
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Compound collision and center of mass

Postby Julio Jerez » Wed Jul 25, 2012 10:12 am

the matrix spoudl be right, if has being working before, ther is no reason to think it will be wrong now.

I modify the scale demo to spwan a single regular convex of 1 x 1 x 1 scale localyy by 1, 2, 1 and offsetd to position 0, 1, 0
and it seems to work.

Notice that when you read the shape matrix, it does not include the scale
Code: Select all
inline const dgMatrix& dgCollisionInstance::GetLocalMatrix () const
{
   return m_localMatrix;
}


also are you using the newer function: NewtonCollisionSetScaleLocal (collision, scale, scale, scale); not NewtonCollisionSetScale?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

PreviousNext

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 0 guests