- fix issue with convex cast: results further away (larger hitfraction) could overwrite closer results

- minor naming convention thing (variables start with lower case)
- renamed MotorDemo
- added ConcaveConvexcastDemo, Thanks John McCutchan (JMC)
This commit is contained in:
ejcoumans
2007-12-06 02:54:29 +00:00
parent 35d2ae870c
commit 6f80b98a67
10 changed files with 855 additions and 101 deletions

View File

@@ -238,49 +238,110 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
} else {
if (collisionShape->isConcave())
{
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
///optimized version for btBvhTriangleMeshShape
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
btTriangleRaycastCallback(from,to),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
btTriangleRaycastCallback(from,to),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
}
};
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
} else
{
btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
//ConvexCast::CastResult
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
}
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
};
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
btTriangleRaycastCallback(from,to),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
{
}
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
shapeInfo.m_triangleIndex = triangleIndex;
btCollisionWorld::LocalRayResult rayResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
}
};
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 rayAabbMinLocal = rayFromLocal;
rayAabbMinLocal.setMin(rayToLocal);
btVector3 rayAabbMaxLocal = rayFromLocal;
rayAabbMaxLocal.setMax(rayToLocal);
triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
}
} else {
//todo: use AABB tree or other BVH acceleration structure!
if (collisionShape->isCompound())
@@ -356,55 +417,69 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
} else {
if (collisionShape->isConcave())
{
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
btTransform rotationXform;
rotationXform.setIdentity (); // FIXME!!!
//ConvexCast::CastResult
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
btTransform rotationXform;
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)
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;
}
};
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;
btCollisionWorld::LocalConvexResult convexResult
(m_collisionObject,
&shapeInfo,
hitNormalLocal,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = false;
return m_resultCallback->AddSingleResult(convexResult,normalInWorldSpace);
}
};
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
} else
{
//currently there is no convex cast support for concave shapes other then btBvhTriangleMeshShape
//not yet
btAssert(0);
}
} else {
//todo: use AABB tree or other BVH acceleration structure!
if (collisionShape->isCompound())

View File

@@ -265,8 +265,8 @@ public:
virtual btScalar AddSingleResult(LocalConvexResult& rayResult,bool normalInWorldSpace)
{
//caller already does the filter on the m_closestHitFraction
assert(rayResult.m_hitFraction <= m_closestHitFraction);
btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
m_closestHitFraction = rayResult.m_hitFraction;
m_hitCollisionObject = rayResult.m_hitCollisionObject;
if (normalInWorldSpace)

View File

@@ -754,8 +754,8 @@ void btOptimizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
bool isLeafNode;
//PCK: unsigned instead of bool
unsigned BoxBoxOverlap = 0;
unsigned RayBoxOverlap = 0;
unsigned boxBoxOverlap = 0;
unsigned rayBoxOverlap = 0;
btScalar lambda_max = 1.0;
#define RAYAABB2
@@ -811,10 +811,10 @@ void btOptimizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
//PCK: unsigned instead of bool
// only interested if this is closer than any previous hit
btScalar param = 1.0;
RayBoxOverlap = 0;
BoxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
rayBoxOverlap = 0;
boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
isLeafNode = rootNode->isLeafNode();
if (BoxBoxOverlap)
if (boxBoxOverlap)
{
btVector3 bounds[2];
bounds[0] = unQuantize(rootNode->m_quantizedAabbMin);
@@ -832,20 +832,19 @@ void btOptimizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
}
#endif
#ifdef RAYAABB2
RayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
#else
RayBoxOverlap = btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
rayBoxOverlap = btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
#endif
}
RayBoxOverlap = true;
if (isLeafNode && RayBoxOverlap)
if (isLeafNode && rayBoxOverlap)
{
nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
}
//PCK: unsigned instead of bool
if ((RayBoxOverlap != 0) || isLeafNode)
if ((rayBoxOverlap != 0) || isLeafNode)
{
rootNode++;
curIndex++;