diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2006-12-01 04:04:27 +0300 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2006-12-01 04:04:27 +0300 |
commit | 4941107f927c3717a113b82463193caae0022d8c (patch) | |
tree | 2f4de94b1bb53233e54f49a732a0f4d90df14bf8 /source/gameengine | |
parent | 51ce503cb24de6fa928555359acce77beed8995e (diff) |
- enabled compound collision objects, requires 'clear parent inverse'
- fixed some issues with kinematic objects, introduced during Bullet 2.x upgrade
Diffstat (limited to 'source/gameengine')
6 files changed, 158 insertions, 50 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 30ff522a26d..b8e273f3d19 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -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; - }*/ } } } diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index d28a8f40d6f..6785cb957bc 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -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 ! diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index a976a6b13b1..684e052323d 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -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; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index ca75b77dfec..e7a33fafffb 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -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; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 33b0e986a32..f6a087887f9 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -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); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index b951602fe1e..37eb0ef76e3 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -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(); |