Commit: 0b4a71b07245d5370a02fae4dbde9195c9c58881
Author: Thomas Szepe
Date:   Sun Mar 22 17:55:43 2015 +0100
Branches: master
https://developer.blender.org/rB0b4a71b07245d5370a02fae4dbde9195c9c58881

BGE: Add physics constraints replication

This patch will add a physics constraints replication for group instances
(dupli group).
It also fix crashing when when a group instance is made from a linked
group instance and both are on the active layer.

Initial patch T31443 from moerdn (Martin Sell).

Reviewers: lordloki, sergof, moguri, sybren

Reviewed By: moguri, sybren

Differential Revision: https://developer.blender.org/D658

===================================================================

M       source/gameengine/Converter/BL_BlenderDataConversion.cpp
M       source/gameengine/Ketsji/KX_GameObject.cpp
M       source/gameengine/Ketsji/KX_GameObject.h
M       source/gameengine/Ketsji/KX_Scene.cpp
M       source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
M       source/gameengine/Physics/Bullet/CcdPhysicsController.h
M       source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
M       source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
M       source/gameengine/Physics/common/PHY_IPhysicsController.h
M       source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h

===================================================================

diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp 
b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 7e0588f..cd2e215 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1741,6 +1741,16 @@ static KX_GameObject* getGameOb(STR_String 
busc,CListValue* sumolist)
 
 }
 
+static bool bl_isConstraintInList(KX_GameObject *gameobj, set<KX_GameObject*> 
convertedlist)
+{
+       set<KX_GameObject*>::iterator gobit;
+       for (gobit = convertedlist.begin(); gobit != convertedlist.end(); 
gobit++) {
+               if ((*gobit)->GetName() == gameobj->GetName())
+                       return true;
+       }
+       return false;
+}
+
 /* helper for BL_ConvertBlenderObjects, avoids code duplication
  * note: all var names match args are passed from the caller */
 static void bl_ConvertBlenderObject_Single(
@@ -1900,6 +1910,12 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        // is not in a separate thread.
        BL_Texture::GetMaxUnits();
 
+       /* We have to ensure that group definitions are only converted once
+        * push all converted group members to this set.
+        * This will happen when a group instance is made from a linked group 
instance
+        * and both are on the active layer. */
+       set<KX_GameObject*> convertedlist;
+
        if (alwaysUseExpandFraming) {
                frame_type = RAS_FrameSettings::e_frame_extend;
                aspect_width = canvas->GetWidth();
@@ -2031,6 +2047,11 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                                                                                
                                converter,
                                                                                
                                libloading);
 
+                                               /* Insert object to the 
constraint game object list
+                                                * so we can check later if 
there is a instance in the scene or
+                                                * an instance and its actual 
group definition. */
+                                               
convertedlist.insert((KX_GameObject*)gameobj->AddRef());
+
                                                bool isInActiveLayer = false;
                                                if (gameobj)
                                                {
@@ -2270,93 +2291,50 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        // create physics joints
        for (i=0;i<sumolist->GetCount();i++)
        {
-               KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
-               struct Object* blenderobject = gameobj->GetBlenderObject();
-               ListBase *conlist;
+               PHY_IPhysicsEnvironment *physEnv = 
kxscene->GetPhysicsEnvironment();
+               KX_GameObject *gameobj = (KX_GameObject *)sumolist->GetValue(i);
+               struct Object *blenderobject = gameobj->GetBlenderObject();
+               ListBase *conlist = get_active_constraints2(blenderobject);
                bConstraint *curcon;
 
-               if ((gameobj->GetLayer()&activeLayerBitInfo)==0)
+               if (!conlist)
                        continue;
 
-               conlist = get_active_constraints2(blenderobject);
-               if (conlist) {
-                       for (curcon = (bConstraint *)conlist->first; curcon; 
curcon = (bConstraint *)curcon->next) {
-                               if 
(curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) {
-
-                                       bRigidBodyJointConstraint 
*dat=(bRigidBodyJointConstraint *)curcon->data;
+               for (curcon = (bConstraint *)conlist->first; curcon; curcon = 
(bConstraint *)curcon->next) {
+                       if (curcon->type != CONSTRAINT_TYPE_RIGIDBODYJOINT)
+                               continue;
 
-                                       if (!dat->child && !(curcon->flag & 
CONSTRAINT_OFF)) {
+                       bRigidBodyJointConstraint *dat = 
(bRigidBodyJointConstraint *)curcon->data;
+                                       
+                       /* Skip if no target or a child object is selected or 
constraints are deactivated */
+                       if (!dat->tar || dat->child || (curcon->flag & 
CONSTRAINT_OFF))
+                               continue;
 
-                                               PHY_IPhysicsController* 
physctr2 = 0;
+                       /* Store constraints of grouped and instanced objects 
for all layers */
+                       gameobj->AddConstraint(dat);
+                                               
+                       /* Skipped already converted constraints. 
+                        * This will happen when a group instance is made from 
a linked group instance
+                        * and both are on the active layer. */
+                       if (bl_isConstraintInList(gameobj, convertedlist))
+                               continue;
 
-                                               if (dat->tar) {
-                                                       KX_GameObject 
*gotar=getGameOb(dat->tar->id.name+2,sumolist);
-                                                       if (gotar && 
((gotar->GetLayer()&activeLayerBitInfo)!=0) && gotar->GetPhysicsController())
-                                                               physctr2 = 
gotar->GetPhysicsController();
-                                               }
+                       KX_GameObject *gotar = getGameOb(dat->tar->id.name + 2, 
sumolist);
 
-                                               if 
(gameobj->GetPhysicsController()) {
-                                                       PHY_IPhysicsController* 
physctrl = gameobj->GetPhysicsController();
-                                                       //we need to pass a 
full constraint frame, not just axis
-
-                                                       
//localConstraintFrameBasis
-                                                       MT_Matrix3x3 
localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ));
-                                                       MT_Vector3 axis0 = 
localCFrame.getColumn(0);
-                                                       MT_Vector3 axis1 = 
localCFrame.getColumn(1);
-                                                       MT_Vector3 axis2 = 
localCFrame.getColumn(2);
-
-                                                       int constraintId = 
kxscene->GetPhysicsEnvironment()->CreateConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,
-                                                               
(float)dat->pivY,(float)dat->pivZ,
-                                                               
(float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
-                                                               
(float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
-                                                               
(float)axis2.x(),(float)axis2.y(),(float)axis2.z(),dat->flag);
-                                                       if (constraintId) {
-                                                               //if it is a 
generic 6DOF constraint, set all the limits accordingly
-                                                               if (dat->type 
== PHY_GENERIC_6DOF_CONSTRAINT) {
-                                                                       int dof;
-                                                                       int 
dofbit=1;
-                                                                       for 
(dof=0;dof<6;dof++) {
-                                                                               
if (dat->flag & dofbit) {
-                                                                               
        
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
-                                                                               
} else {
-                                                                               
        //minLimit > maxLimit means free(disabled limit) for this degree of 
freedom
-                                                                               
        
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
-                                                                               
}
-                                                                               
dofbit<<=1;
-                                                                       }
-                                                               } else if 
(dat->type == PHY_CONE_TWIST_CONSTRAINT) {
-                                                                       int dof;
-                                                                       int 
dofbit = 1<<3; // bitflag use_angular_limit_x
-
-                                                                       for 
(dof=3;dof<6;dof++) {
-                                                                               
if (dat->flag & dofbit) {
-                                                                               
        
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
-                                                                               
} else {
-                                                                               
        //maxLimit < 0 means free(disabled limit) for this degree of freedom
-                                                                               
        
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
-                                                                               
}
-                                                                               
dofbit<<=1;
-                                                                       }
-                                                               } else if 
(dat->type == PHY_LINEHINGE_CONSTRAINT) {
-                                                                       int dof 
= 3; // dof for angular x
-                                                                       int 
dofbit = 1<<3; // bitflag use_angular_limit_x
-
-                                                                       if 
(dat->flag & dofbit) {
-                                                                               
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,
-                                                                               
                dat->minLimit[dof],dat->maxLimit[dof]);
-                                                                       } else {
-                                                                               
//minLimit > maxLimit means free(disabled limit) for this degree of freedom
-                                                                               
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
+                       if (gotar && (gotar->GetLayer()&activeLayerBitInfo) && 
gotar->GetPhysicsController() &&
+                               (gameobj->GetLayer()&activeLayerBitInfo) && 
gameobj->GetPhysicsController())
+                       {
+                               physEnv->SetupObjectConstraints(gameobj, gotar, 
dat);
                        }
                }
        }
 
+       /* cleanup converted set of group objects */
+       set<KX_GameObject*>::iterator gobit;
+       for (gobit = convertedlist.begin(); gobit != convertedlist.end(); 
gobit++)
+               (*gobit)->Release();
+               
+       convertedlist.clear();
        sumolist->Release();
 
        // convert world
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp 
b/source/gameengine/Ketsji/KX_GameObject.cpp
index 71af263..c8fc64f 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -292,6 +292,21 @@ void KX_GameObject::SetDupliGroupObject(KX_GameObject* obj)
        m_pDupliGroupObject = obj;
 }
 
+void KX_GameObject::AddConstraint(bRigidBodyJointConstraint *cons)
+{
+       m_constraints.push_back(cons);
+}
+
+std::vector<bRigidBodyJointConstraint*> KX_GameObject::GetConstraints()
+{
+       return m_constraints;
+}
+
+void KX_GameObject::ClearConstraints()
+{
+       m_constraints.clear();
+}
+
 KX_GameObject* KX_GameObject::GetParent()
 {
        KX_GameObject* result = NULL;
diff --git a/source/gameengine/Ketsji/KX_GameObject.h 
b/source/gameengine/Ketsji/KX_GameObject.h
index 7d1a934..132e72c 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -49,6 +49,7 @@
 #include "CTR_HashedPtr.h"
 #include "KX_Scene.h"
 #include "KX_KetsjiEngine.h" /* for m_anim_framerate */
+#include "DNA_constraint_types.h" /* for constraint replication */
 #include "DNA_object_types.h"
 #include "SCA_LogicManager.h" /* for ConvertPythonToGameObject to search 
object names */
 
@@ -117,6 +118,7 @@ protected:
        SG_Node*                                                        
m_pSGNode;
 
        MT_CmMatrix4x4                                          
m_OpenGL_4x4Matrix;
+       std::vector<bRigidBodyJointConstraint*> m_constraints;
 
        KX_ObstacleSimulation*                          m_pObstacleSimulation;
 
@@ -193,6 +195,14 @@ public:
                void
        UpdateBlenderObjectMatrix(Object* blendobj=NULL);
 
+       /**
+        * Used for constraint replication for group instances.
+        * The list of constraints is filled during data conversion.
+        */
+       void AddConstraint(bRigidBodyJointConstraint *cons);
+       std::vector<bRigidBodyJointConstraint*> GetConstraints();
+       void ClearConstraints();
+
        /** 
         * Get a pointer to the game object that is the parent of 
         * this object. Or NULL if there is no parent. The returned
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp 
b/source/gameengine/Ketsji/KX_Scene.cpp
index d1b1009..47510ba 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -848,6 +848,12 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
        // now look if object in the hierarchy have dupli group and recurse
        for (git = 
m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
        {
+               /* Replicate all constraints. */
+               if ((*git)->GetPhysicsController()) {
+                       
(*git)->GetPhysicsController()->ReplicateConstraints((*git), 
m_logicHierarchicalGameObjects);
+                       (*git)->ClearConstraints();
+               }
+
                if ((*git) != groupobj && (*git)->IsDupliGroup())
                        // can't instantiate group immediately as it destroys 
m_logicHierarchicalGameObjects
                        duplilist.push_back((*git));
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp 
b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 44c4e28..5adff8f 100644
--- a/source/gameengine/Physic

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to