From 22a50402efc1fd9b725d7760c90b343e63191ee4 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 20 Sep 2008 21:33:54 +0000 Subject: BGE patch: allow Bullet mesh shape sharing for objects copied with ALT-D. --- .../Physics/Bullet/CcdPhysicsController.cpp | 58 ++++++++++++++++------ .../Physics/Bullet/CcdPhysicsController.h | 37 +++++++------- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 2 +- 3 files changed, 62 insertions(+), 35 deletions(-) (limited to 'source/gameengine/Physics/Bullet') diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index b1b97b5370f..1ec555f653d 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -902,9 +902,25 @@ void DefaultMotionState::calculateWorldTransformations() } // Shape constructor +std::map CcdShapeConstructionInfo::m_meshShapeMap; + +CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, bool polytope) +{ + if (polytope) + // not yet supported + return NULL; + + std::map::const_iterator mit = m_meshShapeMap.find(mesh); + if (mit != m_meshShapeMap.end()) + return mit->second; + return NULL; +} + bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope) { // assume no shape information + // no support for dynamic change of shape yet + assert(m_meshObject == NULL); m_shapeType = PHY_SHAPE_NONE; m_vertexArray.clear(); m_polygonIndexArray.clear(); @@ -1006,6 +1022,11 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope) return false; } m_meshObject = meshobj; + if (!polytope) + { + // triangle shape can be shared, store the mesh object in the map + m_meshShapeMap.insert(std::pair(meshobj,this)); + } return true; } @@ -1066,16 +1087,18 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() break; case PHY_SHAPE_COMPOUND: - if (m_nextShape) + if (m_shapeArray.size() > 0) { compoundShape = new btCompoundShape(); - for (nextShapeInfo=m_nextShape; nextShapeInfo; nextShapeInfo = nextShapeInfo->m_nextShape) + for (std::vector::iterator sit = m_shapeArray.begin(); + sit != m_shapeArray.end(); + sit++) { - collisionShape = nextShapeInfo->CreateBulletShape(); + collisionShape = (*sit)->CreateBulletShape(); if (collisionShape) { - collisionShape->setLocalScaling(nextShapeInfo->m_childScale); - compoundShape->addChildShape(nextShapeInfo->m_childTrans, collisionShape); + collisionShape->setLocalScaling((*sit)->m_childScale); + compoundShape->addChildShape((*sit)->m_childTrans, collisionShape); } } collisionShape = compoundShape; @@ -1086,28 +1109,31 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo) { - CcdShapeConstructionInfo* nextShape = this; - while (nextShape->m_nextShape != NULL) - nextShape = nextShape->m_nextShape; - nextShape->m_nextShape = shapeInfo; + m_shapeArray.push_back(shapeInfo); } CcdShapeConstructionInfo::~CcdShapeConstructionInfo() { - CcdShapeConstructionInfo* childShape = m_nextShape; - - while (childShape) + for (std::vector::iterator sit = m_shapeArray.begin(); + sit != m_shapeArray.end(); + sit++) { - CcdShapeConstructionInfo* nextShape = childShape->m_nextShape; - childShape->m_nextShape = NULL; - childShape->Release(); - childShape = nextShape; + (*sit)->Release(); } + m_shapeArray.clear(); if (m_unscaledShape) { DeleteBulletShape(m_unscaledShape); } m_vertexArray.clear(); + if (m_shapeType == PHY_SHAPE_MESH && m_meshObject != NULL) + { + std::map::iterator mit = m_meshShapeMap.find(m_meshObject); + if (mit != m_meshShapeMap.end() && mit->second == this) + { + m_meshShapeMap.erase(mit); + } + } } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 355c1d608b1..af146413c91 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -18,6 +18,7 @@ subject to the following restrictions: #define BULLET2_PHYSICSCONTROLLER_H #include +#include #include "PHY_IPhysicsController.h" @@ -42,15 +43,17 @@ class btCollisionShape; class CcdShapeConstructionInfo { public: + static CcdShapeConstructionInfo* FindMesh(RAS_MeshObject* mesh, bool polytope); + CcdShapeConstructionInfo() : m_shapeType(PHY_SHAPE_NONE), m_radius(1.0), m_height(1.0), m_halfExtend(0.f,0.f,0.f), m_childScale(1.0f,1.0f,1.0f), - m_nextShape(NULL), - m_unscaledShape(NULL), - m_refCount(1) + m_refCount(1), + m_meshObject(NULL), + m_unscaledShape(NULL) { m_childTrans.setIdentity(); } @@ -77,22 +80,19 @@ public: { return m_unscaledShape; } - CcdShapeConstructionInfo* GetNextShape() - { - return m_nextShape; - } CcdShapeConstructionInfo* GetChildShape(int i) { - CcdShapeConstructionInfo* shape = m_nextShape; - while (i > 0 && shape != NULL) - { - shape = shape->m_nextShape; - i--; - } - return shape; + if (i < 0 || i >= m_shapeArray.size()) + return NULL; + + return m_shapeArray.at(i); } bool SetMesh(RAS_MeshObject* mesh, bool polytope); + RAS_MeshObject* GetMesh(void) + { + return m_meshObject; + } btCollisionShape* CreateBulletShape(); @@ -109,14 +109,15 @@ public: std::vector m_polygonIndexArray; // Contains the array of polygon index in the // original mesh that correspond to shape triangles. // only set for concave mesh shape. - const RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh protected: - CcdShapeConstructionInfo* m_nextShape; // for compound shape - btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape, - // the actual shape is of type btScaledBvhTriangleMeshShape + static std::map m_meshShapeMap; int m_refCount; // this class is shared between replicas // keep track of users so that we can release it + RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh + btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape, + // the actual shape is of type btScaledBvhTriangleMeshShape + std::vector m_shapeArray; // for compound shapes }; struct CcdConstructionInfo diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 96caf885e7c..68b3df1695c 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -865,7 +865,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac if (shape == rayCallback.m_hitTriangleShape && rayCallback.m_hitTriangleIndex < shapeInfo->m_polygonIndexArray.size()) { - result.m_meshObject = shapeInfo->m_meshObject; + result.m_meshObject = shapeInfo->GetMesh(); result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex); // Bullet returns the normal from "outside". -- cgit v1.2.3