BGE: ray casting works on soft body, the hit polygon is also returned. The modifications to Bullet have been reported to Bullet forum. Note: welding is completely disabled on soft body as it breaks the relationship between the soft body collision shape and the graphics mesh without bringing any additional stability (the reverse actually).

This commit is contained in:
Benoit Bolsee
2009-11-28 17:30:34 +00:00
parent 38ba32a423
commit 1c4150f211
5 changed files with 46 additions and 2 deletions

View 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);
}
}
;

View 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);
}
}
}
}
}

View 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

View 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

View 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];