BGE: ray casting works on soft body, the hit polygon is also returned. The modificati...
authorBenoit Bolsee <benoit.bolsee@online.be>
Sat, 28 Nov 2009 17:30:34 +0000 (17:30 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Sat, 28 Nov 2009 17:30:34 +0000 (17:30 +0000)
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp

index be261ec408013cf4abcd4010c083182466958ef3..a9f3223798b7c880ac63600b2a0be35545d93877 100644 (file)
@@ -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);
+       }
        
 }
 ;
index 10e880e2523ac9d6f7596c8d3d0b8d59c0255aea..7159f5528295128b1470fe5ae3409841e254cfb2 100644 (file)
@@ -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);
+                                       }
+                               }
                        }
                }
        }
index 1f4b9bec647dec5bbc5bc9e4bb4686b34321b605..b6374e64153c397edb78b6ed418689f3991684c9 100644 (file)
@@ -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
index d837b2c4466d5b8143d37d0968c98aab3d2539b9..31616fdec15766d5944e7a9237cad54004b8b65e 100644 (file)
@@ -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
index 5cd20a3ec12b2c4fe39599031d48bad783baac86..3d1fa6fc1801c62501a778cfb52453d04d43532a 100644 (file)
@@ -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];