Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp135
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h5
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp23
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h10
-rw-r--r--source/gameengine/Ketsji/KX_OdePhysicsController.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_OdePhysicsController.h2
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.h5
9 files changed, 178 insertions, 9 deletions
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 3a20bbfbb11..a67f4a54b3f 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -17,10 +17,11 @@
#include "BulletSoftBody/btSoftBody.h"
-KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna)
-: KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
+KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound)
+: KX_IPhysicsController(dyna,compound,(PHY_IPhysicsController*)this),
CcdPhysicsController(ci),
-m_savedCollisionFlags(0)
+m_savedCollisionFlags(0),
+m_bulletChildShape(NULL)
{
}
@@ -175,6 +176,133 @@ void KX_BulletPhysicsController::setRigidBody(bool rigid)
{
}
+/* This function dynamically adds the collision shape of another controller to
+ the current controller shape provided it is a compound shape.
+ The idea is that dynamic parenting on a compound object will dynamically extend the shape
+*/
+void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* child)
+{
+ if (child == NULL || !IsCompound())
+ return;
+ // other controller must be a bullet controller too
+ // verify that body and shape exist and match
+ KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child);
+ btRigidBody* rootBody = GetRigidBody();
+ btRigidBody* childBody = childCtrl->GetRigidBody();
+ if (!rootBody || !childBody)
+ return;
+ const btCollisionShape* rootShape = rootBody->getCollisionShape();
+ const btCollisionShape* childShape = childBody->getCollisionShape();
+ if (!rootShape ||
+ !childShape ||
+ rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE ||
+ childShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
+ return;
+ btCompoundShape* compoundShape = (btCompoundShape*)rootShape;
+ // compute relative transformation between parent and child
+ btTransform rootTrans;
+ btTransform childTrans;
+ rootBody->getMotionState()->getWorldTransform(rootTrans);
+ childBody->getMotionState()->getWorldTransform(childTrans);
+ btVector3 rootScale = rootShape->getLocalScaling();
+ rootScale[0] = 1.0/rootScale[0];
+ rootScale[1] = 1.0/rootScale[1];
+ rootScale[2] = 1.0/rootScale[2];
+ // relative scale = child_scale/parent_scale
+ btVector3 relativeScale = childShape->getLocalScaling()*rootScale;
+ btMatrix3x3 rootRotInverse = rootTrans.getBasis().transpose();
+ // relative pos = parent_rot^-1 * ((parent_pos-child_pos)/parent_scale)
+ btVector3 relativePos = rootRotInverse*((childTrans.getOrigin()-rootTrans.getOrigin())*rootScale);
+ // relative rot = parent_rot^-1 * child_rot
+ btMatrix3x3 relativeRot = rootRotInverse*childTrans.getBasis();
+ // create a proxy shape info to store the transformation
+ CcdShapeConstructionInfo* proxyShapeInfo = new CcdShapeConstructionInfo();
+ // store the transformation to this object shapeinfo
+ proxyShapeInfo->m_childTrans.setOrigin(relativePos);
+ proxyShapeInfo->m_childTrans.setBasis(relativeRot);
+ proxyShapeInfo->m_childScale.setValue(relativeScale[0], relativeScale[1], relativeScale[2]);
+ // we will need this to make sure that we remove the right proxy later when unparenting
+ proxyShapeInfo->m_userData = childCtrl;
+ proxyShapeInfo->SetProxy(childCtrl->GetShapeInfo()->AddRef());
+ // add to parent compound shapeinfo
+ GetShapeInfo()->AddShape(proxyShapeInfo);
+ // create new bullet collision shape from the object shapeinfo and set scaling
+ btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape();
+ newChildShape->setLocalScaling(relativeScale);
+ // add bullet collision shape to parent compound collision shape
+ compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape);
+ // remember we created this shape
+ childCtrl->m_bulletChildShape = newChildShape;
+ // recompute inertia of parent
+ if (!rootBody->isStaticOrKinematicObject())
+ {
+ btVector3 localInertia;
+ float mass = 1.f/rootBody->getInvMass();
+ compoundShape->calculateLocalInertia(mass,localInertia);
+ rootBody->setMassProps(mass,localInertia);
+ }
+ // must update the broadphase cache,
+ GetPhysicsEnvironment()->refreshCcdPhysicsController(this);
+ // remove the children
+ GetPhysicsEnvironment()->disableCcdPhysicsController(childCtrl);
+}
+
+/* Reverse function of the above, it will remove a shape from a compound shape
+ provided that the former was added to the later using AddCompoundChild()
+*/
+void KX_BulletPhysicsController::RemoveCompoundChild(KX_IPhysicsController* child)
+{
+ if (child == NULL || !IsCompound())
+ return;
+ // other controller must be a bullet controller too
+ // verify that body and shape exist and match
+ KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child);
+ btRigidBody* rootBody = GetRigidBody();
+ btRigidBody* childBody = childCtrl->GetRigidBody();
+ if (!rootBody || !childBody)
+ return;
+ const btCollisionShape* rootShape = rootBody->getCollisionShape();
+ if (!rootShape ||
+ rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE)
+ return;
+ btCompoundShape* compoundShape = (btCompoundShape*)rootShape;
+ // retrieve the shapeInfo
+ CcdShapeConstructionInfo* childShapeInfo = childCtrl->GetShapeInfo();
+ CcdShapeConstructionInfo* rootShapeInfo = GetShapeInfo();
+ // and verify that the child is part of the parent
+ int i = rootShapeInfo->FindChildShape(childShapeInfo, childCtrl);
+ if (i < 0)
+ return;
+ rootShapeInfo->RemoveChildShape(i);
+ if (childCtrl->m_bulletChildShape)
+ {
+ int numChildren = compoundShape->getNumChildShapes();
+ for (i=0; i<numChildren; i++)
+ {
+ if (compoundShape->getChildShape(i) == childCtrl->m_bulletChildShape)
+ {
+ compoundShape->removeChildShapeByIndex(i);
+ compoundShape->recalculateLocalAabb();
+ break;
+ }
+ }
+ delete childCtrl->m_bulletChildShape;
+ childCtrl->m_bulletChildShape = NULL;
+ }
+ // recompute inertia of parent
+ if (!rootBody->isStaticOrKinematicObject())
+ {
+ btVector3 localInertia;
+ float mass = 1.f/rootBody->getInvMass();
+ compoundShape->calculateLocalInertia(mass,localInertia);
+ rootBody->setMassProps(mass,localInertia);
+ }
+ // must update the broadphase cache,
+ GetPhysicsEnvironment()->refreshCcdPhysicsController(this);
+ // reactivate the children
+ GetPhysicsEnvironment()->enableCcdPhysicsController(childCtrl);
+}
+
void KX_BulletPhysicsController::SuspendDynamics(bool ghost)
{
btRigidBody *body = GetRigidBody();
@@ -251,6 +379,7 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
physicsreplica->setParentCtrl(ccdParent);
physicsreplica->PostProcessReplica(motionstate,parentctrl);
physicsreplica->m_userdata = (PHY_IPhysicsController*)physicsreplica;
+ physicsreplica->m_bulletChildShape = NULL;
return physicsreplica;
}
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
index d5fca4ec6d3..a50af2699bf 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
@@ -13,10 +13,11 @@ private:
short int m_savedCollisionFilterGroup;
short int m_savedCollisionFilterMask;
MT_Scalar m_savedMass;
+ btCollisionShape* m_bulletChildShape;
public:
- KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna);
+ KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound);
virtual ~KX_BulletPhysicsController ();
///////////////////////////////////
@@ -42,6 +43,8 @@ public:
virtual MT_Scalar GetMass();
virtual MT_Vector3 getReactionForce();
virtual void setRigidBody(bool rigid);
+ virtual void AddCompoundChild(KX_IPhysicsController* child);
+ virtual void RemoveCompoundChild(KX_IPhysicsController* child);
virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 0e7a6d92ec1..46e46b014b5 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -1084,7 +1084,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_bSoft = objprop->m_softbody;
MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
- KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
+ KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,objprop->m_hasCompoundChildren);
// shapeInfo is reference counted, decrement now as we don't use it anymore
if (shapeInfo)
shapeInfo->Release();
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index f2a554c6b2a..706b80a1fab 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -252,6 +252,20 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
if (rootlist->RemoveValue(this))
// the object was in parent list, decrement ref count as it's now removed
Release();
+ // if the new parent is a compound object, add this object shape to the compound shape.
+ // step 0: verify this object has physical controller
+ if (m_pPhysicsController1)
+ {
+ // step 1: find the top parent (not necessarily obj)
+ KX_GameObject* rootobj = (KX_GameObject*)obj->GetSGNode()->GetRootSGParent()->GetSGClientObject();
+ // step 2: verify it has a physical controller and compound shape
+ if (rootobj != NULL &&
+ rootobj->m_pPhysicsController1 != NULL &&
+ rootobj->m_pPhysicsController1->IsCompound())
+ {
+ rootobj->m_pPhysicsController1->AddCompoundChild(m_pPhysicsController1);
+ }
+ }
}
}
@@ -260,6 +274,8 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
// check on valid node in case a python controller holds a reference to a deleted object
if (GetSGNode() && GetSGNode()->GetSGParent())
{
+ // get the root object to remove us from compound object if needed
+ KX_GameObject* rootobj = (KX_GameObject*)GetSGNode()->GetRootSGParent()->GetSGClientObject();
// Set us to the right spot
GetSGNode()->SetLocalScale(GetSGNode()->GetWorldScaling());
GetSGNode()->SetLocalOrientation(GetSGNode()->GetWorldOrientation());
@@ -275,6 +291,13 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
rootlist->Add(AddRef());
if (m_pPhysicsController1)
{
+ // in case this controller was added as a child shape to the parent
+ if (rootobj != NULL &&
+ rootobj->m_pPhysicsController1 != NULL &&
+ rootobj->m_pPhysicsController1->IsCompound())
+ {
+ rootobj->m_pPhysicsController1->RemoveCompoundChild(m_pPhysicsController1);
+ }
m_pPhysicsController1->RestoreDynamics();
}
}
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp
index 5cd66efd965..a38222c5f7e 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp
@@ -35,9 +35,10 @@
#include "PHY_DynamicTypes.h"
-KX_IPhysicsController::KX_IPhysicsController(bool dyna,void* userdata)
+KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool compound, void* userdata)
: m_bDyna(dyna),
+ m_bCompound(compound),
m_suspendDynamics(false),
m_userdata(userdata)
{
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h
index 4ea283e9f98..fed71735bec 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.h
@@ -32,6 +32,7 @@
#include "SG_Controller.h"
#include "MT_Vector3.h"
#include "MT_Point3.h"
+#include "MT_Transform.h"
#include "MT_Matrix3x3.h"
struct KX_ClientObjectInfo;
@@ -48,10 +49,11 @@ class KX_IPhysicsController : public SG_Controller
{
protected:
bool m_bDyna;
+ bool m_bCompound;
bool m_suspendDynamics;
void* m_userdata;
public:
- KX_IPhysicsController(bool dyna,void* userdata);
+ KX_IPhysicsController(bool dyna,bool compound, void* userdata);
virtual ~KX_IPhysicsController();
@@ -78,6 +80,8 @@ public:
virtual MT_Scalar GetMass()=0;
virtual MT_Vector3 getReactionForce()=0;
virtual void setRigidBody(bool rigid)=0;
+ virtual void AddCompoundChild(KX_IPhysicsController* child) = 0;
+ virtual void RemoveCompoundChild(KX_IPhysicsController* child) = 0;
virtual void SuspendDynamics(bool ghost=false)=0;
virtual void RestoreDynamics()=0;
@@ -92,6 +96,10 @@ public:
return m_bDyna;
}
+ bool IsCompound(void) {
+ return m_bCompound;
+ }
+
virtual MT_Scalar GetRadius()=0;
virtual void SetSumoTransform(bool nondynaonly)=0;
// todo: remove next line !
diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp
index 6a701a5f25b..dc6990267d4 100644
--- a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp
@@ -50,7 +50,7 @@ KX_OdePhysicsController::KX_OdePhysicsController(
float extends[3],
float radius
)
-: KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
+: KX_IPhysicsController(dyna,false,(PHY_IPhysicsController*)this),
ODEPhysicsController(
dyna,fullRigidBody,phantom,motionstate,
space,world,mass,friction,restitution,
diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h
index 53050f6ce3e..e3b5336c0b5 100644
--- a/source/gameengine/Ketsji/KX_OdePhysicsController.h
+++ b/source/gameengine/Ketsji/KX_OdePhysicsController.h
@@ -73,6 +73,8 @@ public:
virtual MT_Scalar GetMass();
virtual MT_Vector3 getReactionForce();
virtual void setRigidBody(bool rigid);
+ virtual void AddCompoundChild(KX_IPhysicsController* child) { }
+ virtual void RemoveCompoundChild(KX_IPhysicsController* child) { }
virtual void SuspendDynamics(bool);
virtual void RestoreDynamics();
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
index abe48d99043..a684b637894 100644
--- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
@@ -53,7 +53,7 @@ public:
class SM_Object* sumoObj,
class PHY_IMotionState* motionstate
,bool dyna)
- : KX_IPhysicsController(dyna,NULL) ,
+ : KX_IPhysicsController(dyna,false,NULL) ,
SumoPhysicsController(sumoScene,/*solidscene,*/sumoObj,motionstate,dyna)
{
};
@@ -78,6 +78,9 @@ public:
void SuspendDynamics(bool);
void RestoreDynamics();
+ virtual void AddCompoundChild(KX_IPhysicsController* child) { }
+ virtual void RemoveCompoundChild(KX_IPhysicsController* child) { }
+
virtual void getOrientation(MT_Quaternion& orn);
virtual void setOrientation(const MT_Matrix3x3& orn);