Moderators: Sascha Willems, walaber
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
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);
}
}
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 ------
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]);
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);
}
//! 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;
}
inline const dgMatrix& dgCollisionInstance::GetLocalMatrix () const
{
return m_localMatrix;
}
Users browsing this forum: No registered users and 2 guests