diff options
5 files changed, 46 insertions, 2 deletions
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h index be261ec4080..a9f3223798b 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -152,6 +152,10 @@ BT_DECLARE_ALIGNED_ALLOCATOR(); { return (proxyType == STATIC_PLANE_PROXYTYPE); } + static SIMD_FORCE_INLINE bool isSoftBody(int proxyType) + { + return (proxyType == SOFTBODY_SHAPE_PROXYTYPE); + } } ; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index 10e880e2523..7159f552829 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -31,6 +31,7 @@ subject to the following restrictions: #include "LinearMath/btAabbUtil2.h" #include "LinearMath/btQuickprof.h" #include "LinearMath/btStackAlloc.h" +#include "BulletSoftBody/btSoftBody.h" //#define USE_BRUTEFORCE_RAYBROADPHASE 1 //RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest @@ -411,6 +412,31 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra // restore collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape); } + } else { + if (collisionShape->isSoftBody()) { + btSoftBody* softBody = static_cast<btSoftBody*>(collisionObject); + btSoftBody::sRayCast softResult; + if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = 0; + shapeInfo.m_triangleIndex = softResult.index; + // get the normal + btVector3 normal = softBody->m_faces[softResult.index].m_normal; + btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin(); + if (normal.dot(rayDir) > 0) { + // normal always point toward origin of the ray + normal = -normal; + } + btCollisionWorld::LocalRayResult rayResult + (collisionObject, + &shapeInfo, + normal, + softResult.fraction); + bool normalInWorldSpace = true; + resultCallback.addSingleResult(rayResult,normalInWorldSpace); + } + } } } } diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h index 1f4b9bec647..b6374e64153 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h @@ -72,6 +72,10 @@ public: { return btBroadphaseProxy::isCompound(getShapeType()); } + SIMD_FORCE_INLINE bool isSoftBody() const + { + return btBroadphaseProxy::isSoftBody(getShapeType()); + } ///isInfinite is used to catch simulation error (aabb check) SIMD_FORCE_INLINE bool isInfinite() const diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d837b2c4466..31616fdec15 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1458,7 +1458,9 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */ objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/ - objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */ + //objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */ + /* disable welding: it doesn't bring any additional stability and it breaks the relation between soft body collision shape and graphic mesh */ + objprop.m_soft_welding = 0.f; objprop.m_margin = blenderobject->bsoft->margin; objprop.m_contactProcessingThreshold = 0.f; } else diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 5cd20a3ec12..3d1fa6fc180 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -1070,6 +1070,8 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac rayCallback.m_hitTriangleIndex < shapeInfo->m_polygonIndexArray.size()) { result.m_meshObject = shapeInfo->GetMesh(); + // note for softbody: this assumes that the softbody shape uses the same triangle numbering + // than the triangle mesh shape that was used to build it result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex); // Bullet returns the normal from "outside". @@ -1078,7 +1080,13 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac { // mesh shapes are shared and stored in the shapeInfo btTriangleMeshShape* triangleShape = shapeInfo->GetMeshShape(); - if (triangleShape) + + if (shape->isSoftBody()) + { + // we can get the real normal directly from the body + btSoftBody* softBody = static_cast<btSoftBody*>(rayCallback.m_collisionObject); + rayCallback.m_hitNormalWorld = softBody->m_faces[rayCallback.m_hitTriangleIndex].m_normal; + } else if (triangleShape) { // this code is copied from Bullet btVector3 triangle[3]; |