- enabled compound collision objects, requires 'clear parent inverse'
authorErwin Coumans <blender@erwincoumans.com>
Fri, 1 Dec 2006 01:04:27 +0000 (01:04 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Fri, 1 Dec 2006 01:04:27 +0000 (01:04 +0000)
- fixed some issues with kinematic objects, introduced during Bullet 2.x upgrade

source/blender/makesdna/DNA_object_types.h
source/blender/python/api2_2x/Object.c
source/blender/src/buttons_logic.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp

index 3ecfafeddaf0315720eccbb12fb4b332c794e717..d01973bce4fe45a807913bc515014bda8a35c157 100644 (file)
@@ -343,6 +343,8 @@ extern Object workob;
 #define OB_BOUND_CONE          3
 #define OB_BOUND_POLYH         4
 #define OB_BOUND_POLYT         5
+#define OB_BOUND_DYN_MESH   6
+
 
 /* **************** BASE ********************* */
 
index bc2f2beb4c099b6e7d4d5f99c3d8262c58830846..10952629e6b51452318410d6f50ee23c5fa823c3 100644 (file)
@@ -3306,7 +3306,7 @@ static int Object_setRBShapeBoundType( BPy_Object * self, PyObject * args )
 {
        self->object->recalc |= OB_RECALC_OB;  
        return EXPP_setIValueRange( args, &self->object->boundtype,
-                       0, OB_BOUND_POLYH, 'h' );
+                       0, OB_BOUND_DYN_MESH, 'h' );
 }
 
 /*  SOFTBODY FUNCTIONS */
index cc9d9fd5999cffa964f90aeb4246ec5fea67aaa8..0292a737d80bdb02c6fdc7e6904aa4c9c4cdb186 100644 (file)
@@ -2444,8 +2444,12 @@ void buttons_ketsji(uiBlock *block, Object *ob)
                                &ob->gameflag, 0, 0,0, 0,
                                "Specify a bounds object for physics");
                if (ob->gameflag & OB_BOUNDS) {
-                       uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Convex Hull Polytope%x5|Static TriangleMesh %x4|",
-                               85, 125, 140, 19, &ob->boundtype, 0, 0, 0, 0, "Selects the collision type");
+                       uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Convex Hull Polytope%x5|Static TriangleMesh %x4",
+                       //almost ready to enable this one:                      uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Convex Hull Polytope%x5|Static TriangleMesh %x4|Dynamic Mesh %x5|",
+                               85, 125, 160, 19, &ob->boundtype, 0, 0, 0, 0, "Selects the collision type");
+                       uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 250,125,100,19, 
+                                         &ob->gameflag, 0, 0, 0, 0, 
+                                         "Add Children");
                }
        }
 }
index 30ff522a26dd0cc0907d5e3ca53684cffe63e021..b8e273f3d195b7eeb12e2664a7635850f4a96da3 100644 (file)
@@ -1206,7 +1206,8 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
                                                 KX_Scene* kxscene,
                                                 int activeLayerBitInfo,
                                                 e_PhysicsEngine        physics_engine,
-                                                KX_BlenderSceneConverter *converter
+                                                KX_BlenderSceneConverter *converter,
+                                                bool processCompoundChildren
                                                 )
                                        
 {
@@ -1214,6 +1215,25 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
        //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
        //bool bRigidBody = (userigidbody == 0);
 
+       // get Root Parent of blenderobject
+       struct Object* parent= blenderobject->parent;
+       while(parent && parent->parent) {
+               parent= parent->parent;
+       }
+
+       bool isCompoundChild = false;
+
+       if (parent && (parent->gameflag & OB_DYNAMIC)) {
+               
+               if ((parent->gameflag & OB_CHILD) != 0)
+               {
+                       isCompoundChild = true;
+               } 
+       }
+       if (processCompoundChildren != isCompoundChild)
+               return;
+
+
        PHY_ShapeProps* shapeprops =
                        CreateShapePropsFromBlenderObject(blenderobject, 
                        kxscene);
@@ -1223,6 +1243,10 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
                CreateMaterialFromBlenderObject(blenderobject, kxscene);
                                        
        KX_ObjectProperties objprop;
+
+       objprop.m_isCompoundChild = isCompoundChild;
+       objprop.m_hasCompoundChildren = (blenderobject->gameflag & OB_CHILD) != 0;
+
        if ((objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0))
        {
                objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
@@ -1242,7 +1266,6 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
        objprop.m_dynamic_parent=NULL;
        objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
        objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
-       
        KX_BoxBounds bb;
        my_get_local_bounds(blenderobject,objprop.m_boundobject.box.m_center,bb.m_extends);
        if (blenderobject->gameflag & OB_BOUNDS)
@@ -1295,19 +1318,17 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
                }
        }
 
-       // get Root Parent of blenderobject
-       struct Object* parent= blenderobject->parent;
-       while(parent && parent->parent) {
-               parent= parent->parent;
-       }
-
+       
        if (parent && (parent->gameflag & OB_DYNAMIC)) {
                
                KX_GameObject *parentgameobject = converter->FindGameObject(parent);
                objprop.m_dynamic_parent = parentgameobject;
-
+               //cannot be dynamic:
+               objprop.m_dyna = false;
+               shapeprops->m_mass = 0.f;
        }
 
+       
        objprop.m_concave = (blenderobject->boundtype & 4) != 0;
        
        switch (physics_engine)
@@ -1873,6 +1894,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                }
        }
        
+       bool processCompoundChildren = false;
+
        // create physics information
        for (i=0;i<sumolist->GetCount();i++)
        {
@@ -1880,16 +1903,28 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                struct Object* blenderobject = converter->FindBlenderObject(gameobj);
                int nummeshes = gameobj->GetMeshCount();
                RAS_MeshObject* meshobj = 0;
-
                if (nummeshes > 0)
                {
                        meshobj = gameobj->GetMesh(0);
                }
+               BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren);
+       }
 
-               BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter);
-
+       processCompoundChildren = true;
+       // create physics information
+       for (i=0;i<sumolist->GetCount();i++)
+       {
+               KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
+               struct Object* blenderobject = converter->FindBlenderObject(gameobj);
+               int nummeshes = gameobj->GetMeshCount();
+               RAS_MeshObject* meshobj = 0;
+               if (nummeshes > 0)
+               {
+                       meshobj = gameobj->GetMesh(0);
+               }
+               BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren);
        }
-       
+
                // create physics joints
        for (i=0;i<sumolist->GetCount();i++)
        {
@@ -1910,20 +1945,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                             PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserData();
                             PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) gotar->GetPhysicsController()->GetUserData();
                             kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ);
-                            /*switch(dat->type){
-                                case CONSTRAINT_RB_BALL:
-                                    KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist);
-                                    PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData();
-                                    PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData();
-                                    kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ);
-                                    break;
-                                case CONSTRAINT_RB_HINGE:
-                                    KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist);
-                                    PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData();
-                                    PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData();
-                                    kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ);
-                                    break;
-                            }*/
                         }
                 }
             }
index d28a8f40d6f4c7a7d06b3ccc9a6c27ec2da34b61..6785cb957bc9f8762dbb459a25eb0269acaf9800 100644 (file)
@@ -195,6 +195,34 @@ SG_Controller*     KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
 
 void   KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly)
 {
+       GetRigidBody()->activate(true);
+
+       if (!m_bDyna)
+       {
+               GetRigidBody()->setCollisionFlags(GetRigidBody()->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+       } else
+       {
+               if (!nondynaonly)
+               {
+                       btTransform worldTrans;
+                       GetRigidBody()->getMotionState()->getWorldTransform(worldTrans);
+                       GetRigidBody()->setCenterOfMassTransform(worldTrans);
+                       
+                       /*
+                       scaling?
+                       if (m_bDyna)
+                       {
+                               m_sumoObj->setScaling(MT_Vector3(1,1,1));
+                       } else
+                       {
+                               MT_Vector3 scale;
+                               GetWorldScaling(scale);
+                               m_sumoObj->setScaling(scale);
+                       }
+                       */
+
+               }
+       }
 }
 
 // todo: remove next line !
index a976a6b13b1b840f3a0d9a367c055e6a9a9b7ce2..684e052323dfd2d94d7d53025542a4971bd7fc12 100644 (file)
@@ -57,7 +57,8 @@ typedef enum {
        KX_BOUNDCYLINDER,
        KX_BOUNDCONE,
        KX_BOUNDMESH,
-       KX_BOUNDPOLYTOPE
+       KX_BOUNDPOLYTOPE,
+       KX_BOUND_DYN_MESH
 } KX_BoundBoxClass;
 
 struct KX_BoxBounds
@@ -86,6 +87,8 @@ struct KX_ObjectProperties
        bool    m_concave;
        bool    m_isdeformable;
        bool    m_disableSleeping;
+       bool    m_hasCompoundChildren;
+       bool    m_isCompoundChild;
        KX_BoundBoxClass        m_boundclass;
        union {
                KX_BoxBounds    box;
index ca75b77dfecdf2bf9432ffb85a3c33dd46891f08..e7a33fafffb0458b07f6eec0b29e8cebbc010062 100644 (file)
@@ -884,29 +884,11 @@ void      KX_ConvertBulletObject( class   KX_GameObject* gameobj,
        CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
        assert(env);
        
-
-       bool isbulletdyna = false;
+       bool isbulletdyna = objprop->m_dyna;
        CcdConstructionInfo ci;
-       class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
-
-       
-
-       if (!objprop->m_dyna)
-       {
-               ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
-       }
-
-       ci.m_MotionState = motionstate;
-       ci.m_gravity = btVector3(0,0,0);
        ci.m_localInertiaTensor =btVector3(0,0,0);
        ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
-       isbulletdyna = objprop->m_dyna;
-       
-       ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
-       
-       btTransform trans;
-       trans.setIdentity();
-       
+
        btCollisionShape* bm = 0;
 
        switch (objprop->m_boundclass)
@@ -1022,6 +1004,59 @@ void     KX_ConvertBulletObject( class   KX_GameObject* gameobj,
 
        bm->setMargin(0.06);
 
+       if (objprop->m_isCompoundChild)
+       {
+               //find parent, compound shape and add to it
+               //take relative transform into account!
+               KX_BulletPhysicsController* parentCtrl = (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController();
+               assert(parentCtrl);
+               btRigidBody* rigidbody = parentCtrl->GetRigidBody();
+               btCollisionShape* colShape = rigidbody->getCollisionShape();
+               assert(colShape->isCompound());
+               btCompoundShape* compoundShape = (btCompoundShape*)colShape;
+               btTransform childTrans;
+               childTrans.setIdentity();
+               NodeList& children = objprop->m_dynamic_parent->GetSGNode()->GetSGChildren();
+
+               MT_Point3 childPos = gameobj->GetSGNode()->GetLocalPosition();
+               MT_Matrix3x3 childRot = gameobj->GetSGNode()->GetLocalOrientation();
+               MT_Vector3 childScale = gameobj->GetSGNode()->GetLocalScale();
+
+               bm->setLocalScaling(btVector3(childScale.x(),childScale.y(),childScale.z()));
+               childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z()));
+               float rotval[12];
+               childRot.getValue(rotval);
+               btMatrix3x3 newRot;
+               newRot.setValue(rotval[0],rotval[1],rotval[2],rotval[4],rotval[5],rotval[6],rotval[8],rotval[9],rotval[10]);
+               newRot = newRot.transpose();
+
+               childTrans.setBasis(newRot);
+                       
+
+               compoundShape->addChildShape(childTrans,bm);
+               //do some recalc?
+               //recalc inertia for rigidbody
+               if (!rigidbody->isStaticOrKinematicObject())
+               {
+                       btVector3 localInertia;
+                       float mass = 1.f/rigidbody->getInvMass();
+                       compoundShape->calculateLocalInertia(mass,localInertia);
+                       rigidbody->setMassProps(mass,localInertia);
+               }
+               return;
+       }
+
+       if (objprop->m_hasCompoundChildren)
+       {
+               //replace shape by compoundShape
+               btCompoundShape* compoundShape = new btCompoundShape();
+               btTransform identTrans;
+               identTrans.setIdentity();
+               compoundShape->addChildShape(identTrans,bm);
+               bm = compoundShape;
+       }
+
+
 #ifdef TEST_SIMD_HULL
        if (bm->IsPolyhedral())
        {
@@ -1052,6 +1087,23 @@ void     KX_ConvertBulletObject( class   KX_GameObject* gameobj,
        ci.m_collisionShape = bm;
        
 
+       class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
+
+       if (!objprop->m_dyna)
+       {
+               ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
+       }
+
+       
+       ci.m_MotionState = motionstate;
+       ci.m_gravity = btVector3(0,0,0);
+       
+       ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
+       
+       btTransform trans;
+       trans.setIdentity();
+       
+
        
        ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
        ci.m_restitution = smmaterial->m_restitution;
index 33b0e986a320c9045bbc7a4051dcddd94459caed..f6a087887f944b6a3786732061cf27e09b6f7735 100644 (file)
@@ -126,7 +126,8 @@ void CcdPhysicsController::CreateRigidbody()
        
        //setMassProps this also sets collisionFlags
        //convert collision flags!
-//     m_body->m_collisionFlags = m_cci.m_collisionFlags;
+
+       m_body->setCollisionFlags(m_body->getCollisionFlags() | m_cci.m_collisionFlags);
        
        m_body->setGravity( m_cci.m_gravity);
        m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
index b951602fe1eb8f86218a7a3075762d127164c62e..37eb0ef76e3320fc06334dd9340571e220114803 100644 (file)
@@ -814,6 +814,8 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
        {
                addCcdPhysicsController(ctrl1);
        }
+       //force collision detection with everything, including static objects (might hurt performance!)
+       ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter;
 
        requestCollisionCallback(ctrl);
        //printf("addSensor\n");
@@ -970,7 +972,7 @@ PHY_IPhysicsController*     CcdPhysicsEnvironment::CreateSphereController(float radi
        cinfo.m_collisionShape = new btSphereShape(radius);
        cinfo.m_MotionState = 0;
        cinfo.m_physicsEnv = this;
-       cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
+       cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_KINEMATIC_OBJECT;
        DefaultMotionState* motionState = new DefaultMotionState();
        cinfo.m_MotionState = motionState;
        motionState->m_worldTransform.setIdentity();
@@ -1153,6 +1155,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float conera
        cinfo.m_collisionShape = new btConeShape(coneradius,coneheight);
        cinfo.m_MotionState = 0;
        cinfo.m_physicsEnv = this;
+       cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
        DefaultMotionState* motionState = new DefaultMotionState();
        cinfo.m_MotionState = motionState;
        motionState->m_worldTransform.setIdentity();