Просмотр исходного кода

Applied Bullet internal edge patch from amadeus_osa.

Lasse Öörni 12 лет назад
Родитель
Сommit
855fefe74c

+ 7 - 0
Engine/Physics/CollisionShape.cpp

@@ -37,6 +37,7 @@
 #include "Scene.h"
 #include "Terrain.h"
 
+#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
 #include <BulletCollision/CollisionShapes/btBoxShape.h>
 #include <BulletCollision/CollisionShapes/btCapsuleShape.h>
 #include <BulletCollision/CollisionShapes/btCompoundShape.h>
@@ -139,6 +140,9 @@ TriangleMeshData::TriangleMeshData(Model* model, unsigned lodLevel) :
     }
     
     shape_ = new btBvhTriangleMeshShape(meshData_, true, true);
+    
+    infoMap_ = new btTriangleInfoMap();
+    btGenerateInternalEdgeInfo(shape_, infoMap_);
 }
 
 TriangleMeshData::~TriangleMeshData()
@@ -148,6 +152,9 @@ TriangleMeshData::~TriangleMeshData()
     
     delete meshData_;
     meshData_ = 0;
+    
+    delete infoMap_;
+    infoMap_ = 0;
 }
 
 ConvexData::ConvexData(Model* model, unsigned lodLevel)

+ 3 - 0
Engine/Physics/CollisionShape.h

@@ -30,6 +30,7 @@
 class btBvhTriangleMeshShape;
 class btCollisionShape;
 class btCompoundShape;
+class btTriangleInfoMap;
 class btTriangleMesh;
 
 namespace Urho3D
@@ -75,6 +76,8 @@ struct TriangleMeshData : public CollisionGeometryData
     btTriangleMesh* meshData_;
     /// Bullet triangle mesh collision shape.
     btBvhTriangleMeshShape* shape_;
+    /// Bullet triangle info map.
+    btTriangleInfoMap* infoMap_;
 };
 
 /// Convex hull geometry data.

+ 15 - 0
Engine/Physics/PhysicsWorld.cpp

@@ -39,11 +39,14 @@
 
 #include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
 #include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h>
+#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
 #include <BulletCollision/CollisionShapes/btBoxShape.h>
 #include <BulletCollision/CollisionShapes/btSphereShape.h>
 #include <BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h>
 #include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
 
+extern ContactAddedCallback gContactAddedCallback;
+
 namespace Urho3D
 {
 
@@ -69,6 +72,16 @@ void InternalTickCallback(btDynamicsWorld *world, btScalar timeStep)
     static_cast<PhysicsWorld*>(world->getWorldUserInfo())->PostStep(timeStep);
 }
 
+static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1)
+{
+	btAdjustInternalEdgeContacts(cp, colObj1Wrap, colObj0Wrap, partId1, index1);
+	
+	cp.m_combinedFriction = colObj0Wrap->getCollisionObject()->getFriction() * colObj1Wrap->getCollisionObject()->getFriction();
+	cp.m_combinedRestitution = colObj0Wrap->getCollisionObject()->getRestitution() * colObj1Wrap->getCollisionObject()->getRestitution();
+	
+	return true;
+}
+
 /// Callback for physics world queries.
 struct PhysicsQueryCallback : public btCollisionWorld::ContactResultCallback
 {
@@ -110,6 +123,8 @@ PhysicsWorld::PhysicsWorld(Context* context) :
     debugRenderer_(0),
     debugMode_(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)
 {
+	gContactAddedCallback = CustomMaterialCombinerCallback;
+	
     collisionConfiguration_ = new btDefaultCollisionConfiguration();
     collisionDispatcher_ = new btCollisionDispatcher(collisionConfiguration_);
     broadphase_ = new btDbvtBroadphase();

+ 4 - 0
Engine/Physics/RigidBody.cpp

@@ -775,6 +775,10 @@ void RigidBody::UpdateMass()
         }
         body_->setCollisionShape(useCompound ? shiftedCompoundShape_ : shiftedCompoundShape_->getChildShape(0));
         
+        // If we have one shape and this is a triangle mesh, we use a custom material callback in order to adjust internal edges
+        if (!useCompound && body_->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
+			body_->setCollisionFlags(body_->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+        
         // Reapply rigid body position with new center of mass shift
         Vector3 oldPosition = GetPosition();
         centerOfMass_ = ToVector3(principal.getOrigin());