BGE bug fix (for 2.47): setParent() fix, third part: set mass to 0 when parenting. Allow loc/scale/orientation change on child object with physic controller.

This commit is contained in:
Benoit Bolsee 2008-07-20 15:40:03 +00:00
parent 89f2a63ecd
commit d725e5f78e
6 changed files with 51 additions and 16 deletions

@ -170,10 +170,12 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost)
{ {
btBroadphaseProxy* handle = body->getBroadphaseHandle(); btBroadphaseProxy* handle = body->getBroadphaseHandle();
m_savedCollisionFlags = body->getCollisionFlags(); m_savedCollisionFlags = body->getCollisionFlags();
m_savedMass = GetMass();
m_savedCollisionFilterGroup = handle->m_collisionFilterGroup; m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
m_savedCollisionFilterMask = handle->m_collisionFilterMask; m_savedCollisionFilterMask = handle->m_collisionFilterMask;
body->setActivationState(DISABLE_SIMULATION); body->setActivationState(DISABLE_SIMULATION);
GetPhysicsEnvironment()->updateCcdPhysicsController(this, GetPhysicsEnvironment()->updateCcdPhysicsController(this,
0.0,
btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)), btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
btBroadphaseProxy::StaticFilter, btBroadphaseProxy::StaticFilter,
btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
@ -185,11 +187,12 @@ void KX_BulletPhysicsController::RestoreDynamics()
btRigidBody *body = GetRigidBody(); btRigidBody *body = GetRigidBody();
if (body->getActivationState() == DISABLE_SIMULATION) if (body->getActivationState() == DISABLE_SIMULATION)
{ {
GetRigidBody()->forceActivationState(ACTIVE_TAG);
GetPhysicsEnvironment()->updateCcdPhysicsController(this, GetPhysicsEnvironment()->updateCcdPhysicsController(this,
m_savedMass,
m_savedCollisionFlags, m_savedCollisionFlags,
m_savedCollisionFilterGroup, m_savedCollisionFilterGroup,
m_savedCollisionFilterMask); m_savedCollisionFilterMask);
GetRigidBody()->forceActivationState(ACTIVE_TAG);
} }
} }

@ -11,6 +11,8 @@ private:
int m_savedCollisionFlags; int m_savedCollisionFlags;
short int m_savedCollisionFilterGroup; short int m_savedCollisionFilterGroup;
short int m_savedCollisionFilterMask; short int m_savedCollisionFilterMask;
MT_Scalar m_savedMass;
public: public:
KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna); KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna);

@ -224,6 +224,10 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
RemoveParent(scene); RemoveParent(scene);
obj->GetSGNode()->AddChild(GetSGNode()); obj->GetSGNode()->AddChild(GetSGNode());
if (m_pPhysicsController1)
{
m_pPhysicsController1->SuspendDynamics(true);
}
// Set us to our new scale, position, and orientation // Set us to our new scale, position, and orientation
scale1[0] = scale1[0]/scale2[0]; scale1[0] = scale1[0]/scale2[0];
scale1[1] = scale1[1]/scale2[1]; scale1[1] = scale1[1]/scale2[1];
@ -240,10 +244,6 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
if (rootlist->RemoveValue(this)) if (rootlist->RemoveValue(this))
// the object was in parent list, decrement ref count as it's now removed // the object was in parent list, decrement ref count as it's now removed
Release(); Release();
if (m_pPhysicsController1)
{
m_pPhysicsController1->SuspendDynamics(true);
}
} }
} }
@ -724,8 +724,12 @@ MT_Vector3 KX_GameObject::GetAngularVelocity(bool local)
void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans) void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
{ {
if (m_pPhysicsController1) if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{ {
// don't update physic controller if the object is a child:
// 1) the transformation will not be right
// 2) in this case, the physic controller is necessarily a static object
// that is updated from the normal kinematic synchronization
m_pPhysicsController1->setPosition(trans); m_pPhysicsController1->setPosition(trans);
} }
@ -737,25 +741,22 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot) void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot)
{ {
if (m_pPhysicsController1) if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{ {
// see note above
m_pPhysicsController1->setOrientation(rot.getRotation()); m_pPhysicsController1->setOrientation(rot.getRotation());
} }
if (GetSGNode()) if (GetSGNode())
GetSGNode()->SetLocalOrientation(rot); GetSGNode()->SetLocalOrientation(rot);
else
{
int i;
i=0;
}
} }
void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale) void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale)
{ {
if (m_pPhysicsController1) if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{ {
// see note above
m_pPhysicsController1->setScaling(scale); m_pPhysicsController1->setScaling(scale);
} }

@ -106,6 +106,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
btRigidBody* m_body; btRigidBody* m_body;
class PHY_IMotionState* m_MotionState; class PHY_IMotionState* m_MotionState;
btMotionState* m_bulletMotionState; btMotionState* m_bulletMotionState;
friend class CcdPhysicsEnvironment; // needed when updating the controller
void* m_newClientInfo; void* m_newClientInfo;
@ -194,7 +195,6 @@ class CcdPhysicsController : public PHY_IPhysicsController
return m_cci.m_collisionFilterMask; return m_cci.m_collisionFilterMask;
} }
virtual void calcXform() {} ; virtual void calcXform() {} ;
virtual void SetMargin(float margin) {}; virtual void SetMargin(float margin) {};
virtual float GetMargin() const {return 0.f;}; virtual float GetMargin() const {return 0.f;};

@ -466,17 +466,39 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
} }
void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask) void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
{ {
// this function is used when the collisionning group of a controller is changed // this function is used when the collisionning group of a controller is changed
// remove and add the collistioning object // remove and add the collistioning object
btRigidBody* body = ctrl->GetRigidBody(); btRigidBody* body = ctrl->GetRigidBody();
btVector3 inertia;
m_dynamicsWorld->removeCollisionObject(body); m_dynamicsWorld->removeCollisionObject(body);
body->setCollisionFlags(newCollisionFlags); body->setCollisionFlags(newCollisionFlags);
body->getCollisionShape()->calculateLocalInertia(newMass, inertia);
body->setMassProps(newMass, inertia);
m_dynamicsWorld->addCollisionObject(body, newCollisionGroup, newCollisionMask); m_dynamicsWorld->addCollisionObject(body, newCollisionGroup, newCollisionMask);
// to avoid nasty interaction, we must update the property of the controller as well
ctrl->m_cci.m_mass = newMass;
ctrl->m_cci.m_collisionFilterGroup = newCollisionGroup;
ctrl->m_cci.m_collisionFilterMask = newCollisionMask;
ctrl->m_cci.m_collisionFlags = newCollisionFlags;
} }
void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctrl)
{
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_controllers.begin(), m_controllers.end(), ctrl);
if (i == m_controllers.end())
{
btRigidBody* body = ctrl->GetRigidBody();
m_dynamicsWorld->addCollisionObject(body,
ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
}
}
void CcdPhysicsEnvironment::beginFrame() void CcdPhysicsEnvironment::beginFrame()
{ {

@ -183,7 +183,14 @@ protected:
void removeCcdPhysicsController(CcdPhysicsController* ctrl); void removeCcdPhysicsController(CcdPhysicsController* ctrl);
void updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask); void updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
void disableCcdPhysicsController(CcdPhysicsController* ctrl)
{
removeCcdPhysicsController(ctrl);
}
void enableCcdPhysicsController(CcdPhysicsController* ctrl);
btBroadphaseInterface* getBroadphase(); btBroadphaseInterface* getBroadphase();