Ok let us deal with the first problem first, in thsi function
- Code: Select all
// updateBodyProperties
bool NewtonScene::updateBodyProperties (const BodyID & bodyID)
{ TRACE("NewtonScene::updateBodyProperties")
PhysicsBodies::iterator it = bodies_.find(bodyID);
if ( it != bodies_.end() )
{
PhysicsBody::Ptr pBody = it->second;
if( pBody && pBody->component )
{
const NewtonBody * const newtonBody = (NewtonBody*)pBody->component->userData;
if( !newtonBody ) return false;
NewtonCollision * const collision = NewtonBodyGetCollision(newtonBody);
if( !collision ) return false;
if( pBody->bodyDesc.bodyState & BodyState::ScaleChanged )
{
NewtonCollisionSetScale(collision, pBody->bodyDesc.scale[0], pBody->bodyDesc.scale[1], pBody->bodyDesc.scale[2] );
pBody->bodyDesc.bodyState ^= BodyState::ScaleChanged;
}
dVector origin;
dVector inertia;
dFloat mass = pBody->bodyDesc.mass;
NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]);
dFloat Ixx = mass * inertia[0];
dFloat Iyy = mass * inertia[1];
dFloat Izz = mass * inertia[2];
NewtonBodySetMassMatrix (newtonBody, mass, Ixx, Iyy, Izz);
}
}
return true;
}
In newton therd are two scale functions.
void NewtonCollisionSetScale (const NewtonCollision* const collision, dFloat scaleX, dFloat scaleY, dFloat scaleZ);
void NewtonBodySetCollision (const NewtonBody* const body, const NewtonCollision* const collision);
NewtonCollisionSetScale scale only the colllion shape. but does no notify anyone of what was done.
NewtonBodySetCollision scale the collision shape and after that notify the world that the body owning the shape needs to opdate its AABB,
and that the world also need to update it Node braphse AABB which is different.
you are calling the first.
It has to be like that for real time because scalling a shape happens all the time at run time for effect likes vehicles,
player controllers, triggers, raycats and so on. you do not want these local effects generate global effects over the world.
in you case you need to use teh secund version. your function will be better if it was write like this
- Code: Select all
bool NewtonScene::updateBodyProperties (const BodyID & bodyID)
{ TRACE("NewtonScene::updateBodyProperties")
PhysicsBodies::iterator it = bodies_.find(bodyID);
if ( it != bodies_.end() )
{
PhysicsBody::Ptr pBody = it->second;
if( pBody && pBody->component )
{
const NewtonBody * const newtonBody = (NewtonBody*)pBody->component->userData;
if( pBody->bodyDesc.bodyState & BodyState::ScaleChanged )
{
//NewtonCollisionSetScale(collision, pBody->bodyDesc.scale[0], pBody->bodyDesc.scale[1], pBody->bodyDesc.scale[2] );
NewtonBodySetCollisionScale (pBody, pBody->bodyDesc.scale[0], pBody->bodyDesc.scale[1], pBody->bodyDesc.scale[2]);
pBody->bodyDesc.bodyState ^= BodyState::ScaleChanged;
}
// I do no thonk you nee to do this, the scale above does that more effeceintly
// bu I am not sure, needs to be tested.
dVector origin;
dVector inertia;
dFloat mass = pBody->bodyDesc.mass;
NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]);
dFloat Ixx = mass * inertia[0];
dFloat Iyy = mass * inertia[1];
dFloat Izz = mass * inertia[2];
NewtonBodySetMassMatrix (newtonBody, mass, Ixx, Iyy, Izz);
}
}
return true;
}
Now the function that is checked in has a bug that I just fixed, you need to update so that that change take effect.
please try that and let us see where we are.