diff -rupN trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp blender-group-cons/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp --- trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp 2012-05-04 17:51:24.846319068 +0200 +++ blender-group-cons/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp 2012-05-15 19:54:09.640267446 +0200 @@ -371,6 +371,139 @@ static std::map gReverseKeyTranslateTable = create_translate_table(); +// deklaration, needed for add_constraint2object +ListBase *get_active_constraints2(Object *ob); + +// adds all constraints to the gameobject, so it can found them after +// replcation +static void add_constraints2object(Object* blenderobject, KX_GameObject* gameobj) +{ + ListBase *conlist; + bConstraint *curcon; + 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; + if (!dat->child && dat->tar) + gameobj->AddConstraint(dat); + } + + } + + } + +} + +void setup_constraint4object(KX_GameObject* obj_src, KX_Scene* scene, bRigidBodyJointConstraint* dat, PHY_IPhysicsController* phy_src, PHY_IPhysicsController* phy_dest) +{ + //we need to pass a full constraint frame, not just axis + MT_Vector3 scale = obj_src->NodeGetWorldScaling(); + + 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); + + // apply not only the pivot and axis values, but also take scale into count + // this is not working well, if only one or two axis are scaled, but works ok on + // homogenus scaling + int constraintId = scene->GetPhysicsEnvironment()->createConstraint(phy_src, phy_dest, + (PHY_ConstraintType)dat->type, + (float)dat->pivX*scale.x(), + (float)dat->pivY*scale.y(), + (float)dat->pivZ*scale.z(), + (float)axis0.x()*scale.x(), + (float)axis0.y()*scale.y(), + (float)axis0.z()*scale.z(), + (float)axis1.x()*scale.x(), + (float)axis1.y()*scale.y(), + (float)axis1.z()*scale.z(), + (float)axis2.x()*scale.x(), + (float)axis2.y()*scale.y(), + (float)axis2.z()*scale.z(), + dat->flag); + // PHY_POINT2POINT_CONSTRAINT=1, + // PHY_LINEHINGE_CONSTRAINT=2, + // PHY_ANGULAR_CONSTRAINT = 3, + // PHY_CONE_TWIST_CONSTRAINT = 4, + // PHY_VEHICLE_CONSTRAINT=11, + // PHY_GENERIC_6DOF_CONSTRAINT=12 + + if (constraintId) { + + switch(dat->type) + { + case PHY_POINT2POINT_CONSTRAINT : + { + } break; + + case PHY_GENERIC_6DOF_CONSTRAINT : + { + int dof; + int dofbit=1; + for (dof=0;dof<6;dof++) + { + if (dat->flag & dofbit) + { + scene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); + } else + { + //minLimit > maxLimit means free(disabled limit) for this degree of freedom + scene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1); + } + dofbit<<=1; + } + + } break; + + case 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) + { + scene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); + } + else + { + //maxLimit < 0 means free(disabled limit) for this degree of freedom + scene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1); + } + dofbit<<=1; + } + + } break; + + case PHY_LINEHINGE_CONSTRAINT : + { + int dof = 3; // dof for angular x + int dofbit = 1<<3; // bitflag use_angular_limit_x + + if (dat->flag & dofbit) + { + scene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof, dat->minLimit[dof],dat->maxLimit[dof]); + } else + { + //minLimit > maxLimit means free(disabled limit) for this degree of freedom + scene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1); + } + + } break; + + case PHY_ANGULAR_CONSTRAINT : + { + + } break; + + } + } +} + + static unsigned int KX_rgbaint2uint_new(unsigned int icol) { union @@ -2351,6 +2484,10 @@ void BL_ConvertBlenderObjects(struct Mai set allblobj; // all objects converted set groupobj; // objects from groups (never in active layer) + // we have to ensure that group definitions are only converted once + // push all converted group members to this set + set convertedlist; + if (alwaysUseExpandFraming) { frame_type = RAS_FrameSettings::e_frame_extend; aspect_width = canvas->GetWidth(); @@ -2487,7 +2624,12 @@ void BL_ConvertBlenderObjects(struct Mai kxscene, rendertools, converter); - + + // insert object to the constraint gameobject 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()); + // this code is copied from above except that // object from groups are never in active layer bool isInActiveLayer = false; @@ -2735,7 +2877,7 @@ void BL_ConvertBlenderObjects(struct Mai } - // create physics joints + // create physics joints for (i=0;iGetCount();i++) { KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); @@ -2744,9 +2886,6 @@ void BL_ConvertBlenderObjects(struct Mai bConstraint *curcon; conlist = get_active_constraints2(blenderobject); - if ((gameobj->GetLayer()&activeLayerBitInfo)==0) - continue; - if (conlist) { for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) { if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) { @@ -2755,6 +2894,22 @@ void BL_ConvertBlenderObjects(struct Mai if (!dat->child && !(curcon->flag & CONSTRAINT_OFF)) { + // experimentell, to get grouped objects and instaces in one active layer + // to work with constraints + add_constraints2object(blenderobject, gameobj); + + set::iterator gobit; + bool skip = false; + for (gobit=convertedlist.begin(); gobit!=convertedlist.end(); gobit++) { + if((*gobit)->GetName() == gameobj->GetName()) + skip = true; + } + + // prevents blender to crash, object was already + // converted or constraint is added to gameobject for later replication + if(skip) + continue; + PHY_IPhysicsController* physctr2 = 0; if (dat->tar) @@ -2767,74 +2922,7 @@ void BL_ConvertBlenderObjects(struct Mai if (gameobj->GetPhysicsController()) { PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserData(); - //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); - } - } - } + setup_constraint4object(gameobj, kxscene, dat, physctrl, physctr2); } } } @@ -2842,6 +2930,12 @@ void BL_ConvertBlenderObjects(struct Mai } } + // cleanup converted set of group objects + set::iterator gobit; + for (gobit=convertedlist.begin(); gobit!=convertedlist.end(); gobit++) + (*gobit)->Release(); + + convertedlist.clear(); sumolist->Release(); // convert world diff -rupN trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.h blender-group-cons/blender/source/gameengine/Converter/BL_BlenderDataConversion.h --- trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.h 2012-05-04 17:51:24.818319068 +0200 +++ blender-group-cons/blender/source/gameengine/Converter/BL_BlenderDataConversion.h 2012-05-15 19:40:12.160226917 +0200 @@ -37,9 +37,14 @@ #include "KX_Python.h" #include "KX_PhysicsEngineEnums.h" #include "SCA_IInputDevice.h" +#include "KX_GameObject.h" + +#include "CcdPhysicsEnvironment.h" class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter); +void setup_constraint4object(KX_GameObject* obj_src, KX_Scene* scene, bRigidBodyJointConstraint* dat, PHY_IPhysicsController* phy_src, PHY_IPhysicsController* phy_dest); + void BL_ConvertBlenderObjects(struct Main* maggie, class KX_Scene* kxscene, class KX_KetsjiEngine* ketsjiEngine, diff -rupN trunk/blender/source/gameengine/GamePlayer/ghost/SConscript blender-group-cons/blender/source/gameengine/GamePlayer/ghost/SConscript --- trunk/blender/source/gameengine/GamePlayer/ghost/SConscript 2012-05-04 17:51:19.862318821 +0200 +++ blender-group-cons/blender/source/gameengine/GamePlayer/ghost/SConscript 2012-05-15 18:56:57.196101325 +0200 @@ -35,10 +35,15 @@ incs = ['.', '#source/gameengine/Physics/common', '#source/gameengine/Network/LoopBackNetwork', '#source/gameengine/GamePlayer/common', + '#source/gameengine/Physics/common', + '#source/gameengine/Physics/Bullet', + '#source/gameengine/Physics/Dummy', '#source/blender/misc', '#source/blender/blenloader', '#source/blender/gpu', - '#extern/glew/include'] + '#extern/glew/include', + '#extern/bullet2/src/', +] incs.append(env['BF_PTHREADS_INC']) diff -rupN trunk/blender/source/gameengine/Ketsji/KX_GameObject.h blender-group-cons/blender/source/gameengine/Ketsji/KX_GameObject.h --- trunk/blender/source/gameengine/Ketsji/KX_GameObject.h 2012-05-04 17:51:31.046319367 +0200 +++ blender-group-cons/blender/source/gameengine/Ketsji/KX_GameObject.h 2012-05-04 21:26:18.960222006 +0200 @@ -50,6 +50,7 @@ #include "KX_Scene.h" #include "KX_KetsjiEngine.h" /* for m_anim_framerate */ #include "KX_IPhysicsController.h" /* for suspend/resume */ +#include "DNA_constraint_types.h" /*constraint replication*/ #include "DNA_object_types.h" #include "SCA_LogicManager.h" /* for ConvertPythonToGameObject to search object names */ #define KX_OB_DYNAMIC 1 @@ -113,6 +114,7 @@ protected: SG_Node* m_pSGNode; MT_CmMatrix4x4 m_OpenGL_4x4Matrix; + std::vector m_constraints; KX_ObstacleSimulation* m_pObstacleSimulation; @@ -185,6 +187,29 @@ 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 + ) { + m_constraints.push_back(cons); + } + + std::vector + GetConstraints( + ) { + return m_constraints; + } + + void + ClearConstraints( + ) { + m_constraints.clear(); + } + /** * Get a pointer to the game object that is the parent of * this object. Or NULL if there is no parent. The returned diff -rupN trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp blender-group-cons/blender/source/gameengine/Ketsji/KX_Scene.cpp --- trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp 2012-05-04 17:51:30.874319360 +0200 +++ blender-group-cons/blender/source/gameengine/Ketsji/KX_Scene.cpp 2012-05-15 19:39:37.416225231 +0200 @@ -85,6 +85,7 @@ #include "BL_ModifierDeformer.h" #include "BL_ShapeDeformer.h" #include "BL_DeformableGameObject.h" +#include "BL_BlenderDataConversion.h" #include "KX_ObstacleSimulation.h" #ifdef USE_BULLET @@ -663,6 +664,55 @@ void KX_Scene::ReplicateLogic(KX_GameObj newobj->ResetState(); } +void KX_Scene::ReplicateConstraints(KX_GameObject* replica) +{ + if(replica->GetConstraints().size() > 0) + { + PHY_IPhysicsController* physctr_repl; + if(replica->GetPhysicsController()) + { + physctr_repl = (PHY_IPhysicsController*) replica->GetPhysicsController()->GetUserData(); + } + else + { + // make sure to return, because createConstraint() would crash + return; + } + + std::vector constraints = replica->GetConstraints(); + std::vector::iterator consit; + int number = 0; // just for debugging + + // object could have some constraints, iterate over all of theme to ensure + // that every constraint is recreated + for(consit = constraints.begin(); consit != constraints.end(); ++consit) + { + + // try to finde the constraint targes in the list of group objects + bRigidBodyJointConstraint* dat = (*consit); + vector::iterator memit; + for (memit = m_logicHierarchicalGameObjects.begin();!(memit==m_logicHierarchicalGameObjects.end());++memit) + { + // if the group member is the actual target to + // the constraint + KX_GameObject* member = (*memit); + if(dat->tar->id.name+2 == member->GetName()) + { + PHY_IPhysicsController* physctr_memb = NULL; + if(member->GetPhysicsController()) + physctr_memb = (PHY_IPhysicsController*) member->GetPhysicsController()->GetUserData(); + + setup_constraint4object(member, this, dat, physctr_repl, physctr_memb); + } + + } + + } + + } + +} + void KX_Scene::DupliGroupRecurse(CValue* obj, int level) { KX_GameObject* groupobj = (KX_GameObject*) obj; @@ -810,6 +860,13 @@ void KX_Scene::DupliGroupRecurse(CValue* duplilist.push_back((*git)); } + // now replicate all constraints + for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git) + { + ReplicateConstraints((*git)); + (*git)->ClearConstraints(); + } + for (git = duplilist.begin(); !(git == duplilist.end()); ++git) { DupliGroupRecurse((*git), level+1); diff -rupN trunk/blender/source/gameengine/Ketsji/KX_Scene.h blender-group-cons/blender/source/gameengine/Ketsji/KX_Scene.h --- trunk/blender/source/gameengine/Ketsji/KX_Scene.h 2012-05-04 17:51:31.042319367 +0200 +++ blender-group-cons/blender/source/gameengine/Ketsji/KX_Scene.h 2012-05-04 21:41:04.820264900 +0200 @@ -536,6 +536,7 @@ public: */ void ReplicateLogic(class KX_GameObject* newobj); + void ReplicateConstraints(class KX_GameObject* gameobj); static SG_Callbacks m_callbacks; const STR_String& GetName();