add support for generic concave shapes for convex cast.

minor improvement in ray cast demo.
Thanks John McCutchan (JMC)
This commit is contained in:
ejcoumans
2007-12-07 19:21:16 +00:00
parent 9447dfdcfb
commit a4bc26544c
3 changed files with 75 additions and 9 deletions

View File

@@ -325,8 +325,8 @@ void ConcaveRaycastDemo::initPhysics()
staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
//raycastBar = btRaycastBar (4000.0, 0.0); raycastBar = btRaycastBar (4000.0, 0.0);
raycastBar = btRaycastBar (true, 40.0, -50.0, 50.0); //raycastBar = btRaycastBar (true, 40.0, -50.0, 50.0);
} }
void ConcaveRaycastDemo::clientMoveAndDisplay() void ConcaveRaycastDemo::clientMoveAndDisplay()

View File

@@ -476,9 +476,68 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal); triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
} else } else
{ {
//currently there is no convex cast support for concave shapes other then btBvhTriangleMeshShape btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
//not yet btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btAssert(0); btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
btTransform rotationXform;
rotationXform.setIdentity (); // FIXME!!!
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
if (hitFraction <= m_resultCallback->m_closestHitFraction)
{
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(convexResult,normalInWorldSpace);
}
return hitFraction;
}
};
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
btVector3 rayAabbMinLocal = convexFromLocal;
rayAabbMinLocal.setMin(convexToLocal);
btVector3 rayAabbMaxLocal = convexFromLocal;
rayAabbMaxLocal.setMax(convexToLocal);
rayAabbMinLocal += boxMinLocal;
rayAabbMaxLocal += boxMaxLocal;
triangleMesh->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
} }
} else { } else {
//todo: use AABB tree or other BVH acceleration structure! //todo: use AABB tree or other BVH acceleration structure!

View File

@@ -967,13 +967,20 @@ void btOptimizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallb
void btOptimizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const void btOptimizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
{ {
bool supported = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS; bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS;
if (supported) if (fast_path)
{ {
walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex); walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
} else { } else {
//not yet, please implement different paths /* Slow path:
btAssert("Box cast on this type of Bvh Tree is not supported yet" && 0); Construct the bounding box for the entire box cast and send that down the tree */
btVector3 qaabbMin = raySource;
btVector3 qaabbMax = raySource;
qaabbMin.setMin(rayTarget);
qaabbMax.setMax(rayTarget);
qaabbMin += aabbMin;
qaabbMax += aabbMax;
reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
} }
} }