diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index db1595db36f..1b2ceae6560 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -279,13 +279,15 @@ void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* chil // 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 + // add to parent compound shapeinfo (increments ref count) GetShapeInfo()->AddShape(proxyShapeInfo); // create new bullet collision shape from the object shapeinfo and set scaling - btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin()); + btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin(), childCtrl->getConstructionInfo().m_bGimpact, true); newChildShape->setLocalScaling(relativeScale); // add bullet collision shape to parent compound collision shape compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape); + // proxyShapeInfo is not needed anymore, release it + proxyShapeInfo->Release(); // remember we created this shape childCtrl->m_bulletChildShape = newChildShape; // recompute inertia of parent diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index bae32c74d1a..c693913a3a1 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -97,6 +97,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, bool isbulletdyna = false; bool isbulletsensor = false; + bool useGimpact = false; CcdConstructionInfo ci; class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo(); @@ -121,7 +122,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->m_radius = objprop->m_radius; isbulletdyna = objprop->m_dyna; isbulletsensor = objprop->m_sensor; - + useGimpact = ((isbulletdyna || isbulletsensor) && !objprop->m_softbody); + ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f); btCollisionShape* bm = 0; @@ -178,24 +180,22 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, } case KX_BOUNDPOLYTOPE: { - shapeInfo->SetMesh(meshobj, dm,true,false); + shapeInfo->SetMesh(meshobj, dm,true); bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDMESH: { - bool useGimpact = ((ci.m_mass || isbulletsensor) && !objprop->m_softbody); - // mesh shapes can be shared, check first if we already have a shape on that mesh - class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false,useGimpact); + class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false); if (sharedShapeInfo != NULL) { - delete shapeInfo; + shapeInfo->Release(); shapeInfo = sharedShapeInfo; shapeInfo->AddRef(); } else { - shapeInfo->SetMesh(meshobj, dm, false,useGimpact); + shapeInfo->SetMesh(meshobj, dm, false); } // Soft bodies require welding. Only avoid remove doubles for non-soft bodies! @@ -204,7 +204,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI } - bm = shapeInfo->CreateBulletShape(ci.m_margin); + bm = shapeInfo->CreateBulletShape(ci.m_margin, useGimpact, !objprop->m_softbody); //should we compute inertia for dynamic shape? //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor); @@ -218,7 +218,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, if (!bm) { delete motionstate; - delete shapeInfo; + shapeInfo->Release(); return; } @@ -268,6 +268,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, compoundShape->calculateLocalInertia(mass,localInertia); rigidbody->setMassProps(mass,localInertia); } + shapeInfo->Release(); // delete motionstate as it's not used delete motionstate; return; @@ -284,6 +285,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, compoundShape->addChildShape(shapeInfo->m_childTrans,bm); // now replace the shape bm = compoundShape; + shapeInfo->Release(); shapeInfo = compoundShapeInfo; } @@ -395,6 +397,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so ci.m_bSoft = objprop->m_softbody; ci.m_bSensor = isbulletsensor; + ci.m_bGimpact = useGimpact; MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,objprop->m_hasCompoundChildren); @@ -544,7 +547,8 @@ bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *fro shapeInfo->UpdateMesh(from_gameobj, from_meshobj); /* create the new bullet mesh */ - btCollisionShape* bm= shapeInfo->CreateBulletShape(spc->getConstructionInfo().m_margin); + CcdConstructionInfo& cci = spc->getConstructionInfo(); + btCollisionShape* bm= shapeInfo->CreateBulletShape(cci.m_margin, cci.m_bGimpact, !cci.m_bSoft); spc->ReplaceControllerShape(bm); return true; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index e0164b24769..fe429200dd4 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -236,7 +236,7 @@ bool CcdPhysicsController::CreateSoftbody() } } else { - btBvhTriangleMeshShape* trimeshshape = (btBvhTriangleMeshShape*) m_cci.m_collisionShape; + btTriangleMeshShape* trimeshshape = (btTriangleMeshShape*) m_cci.m_collisionShape; ///only deal with meshes that have 1 sub part/component, for now if (trimeshshape->getMeshInterface()->getNumSubParts()==1) { @@ -682,7 +682,7 @@ void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta if (m_shapeInfo) { m_shapeInfo->AddRef(); - m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin); + m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft); if (m_collisionShape) { @@ -1276,7 +1276,7 @@ PHY_IPhysicsController* CcdPhysicsController::GetReplica() if (m_shapeInfo) { // This situation does not normally happen - cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin); + cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft); } else if (m_collisionShape) { @@ -1379,9 +1379,9 @@ void DefaultMotionState::calculateWorldTransformations() // Shape constructor std::map CcdShapeConstructionInfo::m_meshShapeMap; -CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope, bool gimpact) +CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope) { - if (polytope || dm || gimpact) + if (polytope || dm) // not yet supported return NULL; @@ -1391,12 +1391,10 @@ CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mes return NULL; } -bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, bool polytope,bool useGimpact) +bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, bool polytope) { int numpolys, numverts; - m_useGimpact = useGimpact; - // assume no shape information // no support for dynamic change of shape yet assert(IsUnused()); @@ -1656,7 +1654,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, } // sharing only on static mesh at present, if you change that, you must also change in FindMesh - if (!polytope && !dm && !useGimpact) + if (!polytope && !dm) { // triangle shape can be shared, store the mesh object in the map m_meshShapeMap.insert(std::pair(meshobj,this)); @@ -1991,13 +1989,13 @@ bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo) return true; } -btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) +btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, bool useGimpact, bool useBvh) { btCollisionShape* collisionShape = 0; btCompoundShape* compoundShape = 0; if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL) - return m_shapeProxy->CreateBulletShape(margin); + return m_shapeProxy->CreateBulletShape(margin, useGimpact, useBvh); switch (m_shapeType) { @@ -2037,7 +2035,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) // 9 multiplications/additions and one function call for each triangle that passes the mid phase filtering // One possible optimization is to use directly the btBvhTriangleMeshShape when the scale is 1,1,1 // and btScaledBvhTriangleMeshShape otherwise. - if (m_useGimpact) + if (useGimpact) { btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray( m_polygonIndexArray.size(), @@ -2095,14 +2093,14 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) if(m_unscaledShape) { DeleteBulletShape(m_unscaledShape, false); m_unscaledShape->~btBvhTriangleMeshShape(); - - m_unscaledShape = new(m_unscaledShape) btBvhTriangleMeshShape( indexVertexArrays, true ); + m_unscaledShape = new(m_unscaledShape) btBvhTriangleMeshShape( indexVertexArrays, true, useBvh ); } else { - m_unscaledShape = new btBvhTriangleMeshShape( indexVertexArrays, true ); + m_unscaledShape = new btBvhTriangleMeshShape( indexVertexArrays, true, useBvh ); } - m_forceReInstance= false; - m_unscaledShape->recalcLocalAabb(); + } else if (useBvh && m_unscaledShape->getOptimizedBvh() == NULL) { + // the existing unscaledShape was not build with Bvh, do it now + m_unscaledShape->buildOptimizedBvh(); } collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f)); collisionShape->setMargin(margin); @@ -2117,7 +2115,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) sit != m_shapeArray.end(); sit++) { - collisionShape = (*sit)->CreateBulletShape(margin); + collisionShape = (*sit)->CreateBulletShape(margin, useGimpact, useBvh); if (collisionShape) { collisionShape->setLocalScaling((*sit)->m_childScale); @@ -2133,6 +2131,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin) void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo) { m_shapeArray.push_back(shapeInfo); + shapeInfo->AddRef(); } CcdShapeConstructionInfo::~CcdShapeConstructionInfo() diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 637007e2857..607602a4d0d 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -62,7 +62,7 @@ public: float uv[2]; }; - static CcdShapeConstructionInfo* FindMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope, bool gimpact); + static CcdShapeConstructionInfo* FindMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope); CcdShapeConstructionInfo() : m_shapeType(PHY_SHAPE_NONE), @@ -74,7 +74,6 @@ public: m_refCount(1), m_meshObject(NULL), m_unscaledShape(NULL), - m_useGimpact(false), m_forceReInstance(false), m_weldingThreshold1(0.f), m_shapeProxy(NULL) @@ -143,7 +142,7 @@ public: return true; } - bool SetMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope,bool useGimpact); + bool SetMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope); RAS_MeshObject* GetMesh(void) { return m_meshObject; @@ -158,7 +157,7 @@ public: return m_shapeProxy; } - btCollisionShape* CreateBulletShape(btScalar margin); + btCollisionShape* CreateBulletShape(btScalar margin, bool useGimpact=false, bool useBvh=true); // member variables PHY_ShapeType m_shapeType; @@ -193,7 +192,6 @@ protected: btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape, // the actual shape is of type btScaledBvhTriangleMeshShape std::vector m_shapeArray; // for compound shapes - bool m_useGimpact; //use gimpact for concave dynamic/moving collision detection bool m_forceReInstance; //use gimpact for concave dynamic/moving collision detection float m_weldingThreshold1; //welding closeby vertices together can improve softbody stability etc. CcdShapeConstructionInfo* m_shapeProxy; // only used for PHY_SHAPE_PROXY, pointer to actual shape info @@ -240,6 +238,7 @@ struct CcdConstructionInfo m_bRigid(false), m_bSoft(false), m_bSensor(false), + m_bGimpact(false), m_collisionFilterGroup(DefaultFilter), m_collisionFilterMask(AllFilter), m_collisionShape(0), @@ -308,6 +307,7 @@ struct CcdConstructionInfo bool m_bRigid; bool m_bSoft; bool m_bSensor; + bool m_bGimpact; // use Gimpact for mesh body ///optional use of collision group/mask: ///only collision with object goups that match the collision mask.