added basic CCD calculations for Compounds and non-convex (convex-versus-concave).
This commit is contained in:
@@ -99,5 +99,46 @@ void CompoundCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,BroadphaseP
|
||||
|
||||
float CompoundCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,const DispatcherInfo& dispatchInfo)
|
||||
{
|
||||
return 1.f;
|
||||
CollisionObject* colObj = static_cast<CollisionObject*>(m_compoundProxy.m_clientObject);
|
||||
assert (colObj->m_collisionShape->IsCompound());
|
||||
|
||||
CompoundShape* compoundShape = static_cast<CompoundShape*>(colObj->m_collisionShape);
|
||||
|
||||
//We will use the OptimizedBVH, AABB tree to cull potential child-overlaps
|
||||
//If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals
|
||||
//given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means:
|
||||
//determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1
|
||||
//then use each overlapping node AABB against Tree0
|
||||
//and vise versa.
|
||||
|
||||
float hitFraction = 1.f;
|
||||
|
||||
int numChildren = m_childCollisionAlgorithms.size();
|
||||
int i;
|
||||
for (i=0;i<numChildren;i++)
|
||||
{
|
||||
//temporarily exchange parent CollisionShape with childShape, and recurse
|
||||
CollisionShape* childShape = compoundShape->GetChildShape(i);
|
||||
CollisionObject* colObj = static_cast<CollisionObject*>(m_childProxies[i].m_clientObject);
|
||||
|
||||
//backup
|
||||
SimdTransform orgTrans = colObj->m_worldTransform;
|
||||
CollisionShape* orgShape = colObj->m_collisionShape;
|
||||
|
||||
SimdTransform childTrans = compoundShape->GetChildTransform(i);
|
||||
SimdTransform newChildWorldTrans = orgTrans*childTrans ;
|
||||
colObj->m_worldTransform = newChildWorldTrans;
|
||||
|
||||
colObj->m_collisionShape = childShape;
|
||||
float frac = m_childCollisionAlgorithms[i]->CalculateTimeOfImpact(&m_childProxies[i],&m_otherProxy,dispatchInfo);
|
||||
if (frac<hitFraction)
|
||||
{
|
||||
hitFraction = frac;
|
||||
}
|
||||
//revert back
|
||||
colObj->m_collisionShape =orgShape;
|
||||
colObj->m_worldTransform = orgTrans;
|
||||
}
|
||||
return hitFraction;
|
||||
|
||||
}
|
||||
@@ -23,7 +23,9 @@ subject to the following restrictions:
|
||||
#include "CollisionDispatch/ManifoldResult.h"
|
||||
#include "NarrowPhaseCollision/RaycastCallback.h"
|
||||
#include "CollisionShapes/TriangleShape.h"
|
||||
#include "CollisionShapes/SphereShape.h"
|
||||
#include "IDebugDraw.h"
|
||||
#include "NarrowPhaseCollision/SubSimplexConvexCast.h"
|
||||
|
||||
ConvexConcaveCollisionAlgorithm::ConvexConcaveCollisionAlgorithm( const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
|
||||
: CollisionAlgorithm(ci),m_convex(*proxy0),m_concave(*proxy1),
|
||||
@@ -202,36 +204,84 @@ float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,B
|
||||
CollisionObject* convexbody = (CollisionObject* )m_convex.m_clientObject;
|
||||
CollisionObject* triBody = static_cast<CollisionObject* >(m_concave.m_clientObject);
|
||||
|
||||
const SimdVector3& from = convexbody->m_worldTransform.getOrigin();
|
||||
|
||||
SimdVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
|
||||
//only perform CCD above a certain treshold, this prevents blocking on the long run
|
||||
//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
|
||||
float squareMot0 = (convexbody->m_interpolationWorldTransform.getOrigin() - convexbody->m_worldTransform.getOrigin()).length2();
|
||||
if (squareMot0 < convexbody->m_ccdSquareMotionTreshold)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
//const SimdVector3& from = convexbody->m_worldTransform.getOrigin();
|
||||
//SimdVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
|
||||
//todo: only do if the motion exceeds the 'radius'
|
||||
|
||||
struct LocalTriangleRaycastCallback : public TriangleRaycastCallback
|
||||
SimdTransform convexFromLocal = triBody->m_cachedInvertedWorldTransform * convexbody->m_worldTransform;
|
||||
SimdTransform convexToLocal = triBody->m_cachedInvertedWorldTransform * convexbody->m_interpolationWorldTransform;
|
||||
|
||||
struct LocalTriangleSphereCastCallback : public TriangleCallback
|
||||
{
|
||||
LocalTriangleRaycastCallback(const SimdVector3& from,const SimdVector3& to)
|
||||
:TriangleRaycastCallback(from,to)
|
||||
{
|
||||
SimdTransform m_ccdSphereFromTrans;
|
||||
SimdTransform m_ccdSphereToTrans;
|
||||
SimdTransform m_meshTransform;
|
||||
|
||||
float m_ccdSphereRadius;
|
||||
float m_hitFraction;
|
||||
|
||||
|
||||
LocalTriangleSphereCastCallback(const SimdTransform& from,const SimdTransform& to,float ccdSphereRadius,float hitFraction)
|
||||
:m_ccdSphereFromTrans(from),
|
||||
m_ccdSphereToTrans(to),
|
||||
m_ccdSphereRadius(ccdSphereRadius),
|
||||
m_hitFraction(hitFraction)
|
||||
{
|
||||
}
|
||||
|
||||
virtual float ReportHit(const SimdVector3& hitNormalLocal, float hitFraction, int partId, int triangleIndex )
|
||||
|
||||
virtual void ProcessTriangle(SimdVector3* triangle, int partId, int triangleIndex)
|
||||
{
|
||||
//todo: handle ccd here
|
||||
return 0.f;
|
||||
//do a swept sphere for now
|
||||
SimdTransform ident;
|
||||
ident.setIdentity();
|
||||
ConvexCast::CastResult castResult;
|
||||
castResult.m_fraction = m_hitFraction;
|
||||
SphereShape pointShape(m_ccdSphereRadius);
|
||||
TriangleShape triShape(triangle[0],triangle[1],triangle[2]);
|
||||
VoronoiSimplexSolver simplexSolver;
|
||||
SubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver);
|
||||
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
|
||||
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
|
||||
//local space?
|
||||
|
||||
if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans,
|
||||
ident,ident,castResult))
|
||||
{
|
||||
if (m_hitFraction > castResult.m_fraction)
|
||||
m_hitFraction = castResult.m_fraction;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
LocalTriangleRaycastCallback raycastCallback(from,to);
|
||||
|
||||
raycastCallback.m_hitFraction = convexbody->m_hitFraction;
|
||||
|
||||
SimdVector3 aabbMin (-1e30f,-1e30f,-1e30f);
|
||||
SimdVector3 aabbMax (SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
|
||||
|
||||
|
||||
|
||||
if (triBody->m_collisionShape->IsConcave())
|
||||
{
|
||||
SimdVector3 rayAabbMin = convexFromLocal.getOrigin();
|
||||
rayAabbMin.setMin(convexToLocal.getOrigin());
|
||||
SimdVector3 rayAabbMax = convexFromLocal.getOrigin();
|
||||
rayAabbMax.setMax(convexToLocal.getOrigin());
|
||||
rayAabbMin -= SimdVector3(convexbody->m_ccdSweptShereRadius,convexbody->m_ccdSweptShereRadius,convexbody->m_ccdSweptShereRadius);
|
||||
rayAabbMax += SimdVector3(convexbody->m_ccdSweptShereRadius,convexbody->m_ccdSweptShereRadius,convexbody->m_ccdSweptShereRadius);
|
||||
|
||||
float curHitFraction = 1.f; //is this available?
|
||||
LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal,
|
||||
convexbody->m_ccdSweptShereRadius,curHitFraction);
|
||||
|
||||
raycastCallback.m_hitFraction = convexbody->m_hitFraction;
|
||||
|
||||
CollisionObject* concavebody = (CollisionObject* )m_concave.m_clientObject;
|
||||
|
||||
@@ -239,15 +289,16 @@ float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,B
|
||||
|
||||
if (triangleMesh)
|
||||
{
|
||||
triangleMesh->ProcessAllTriangles(&raycastCallback,aabbMin,aabbMax);
|
||||
triangleMesh->ProcessAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (raycastCallback.m_hitFraction < convexbody->m_hitFraction)
|
||||
{
|
||||
convexbody->m_hitFraction = raycastCallback.m_hitFraction;
|
||||
return raycastCallback.m_hitFraction;
|
||||
if (raycastCallback.m_hitFraction < convexbody->m_hitFraction)
|
||||
{
|
||||
convexbody->m_hitFraction = raycastCallback.m_hitFraction;
|
||||
return raycastCallback.m_hitFraction;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
|
||||
@@ -22,7 +22,9 @@ subject to the following restrictions:
|
||||
CompoundShape::CompoundShape()
|
||||
:m_localAabbMin(1e30f,1e30f,1e30f),
|
||||
m_localAabbMax(-1e30f,-1e30f,-1e30f),
|
||||
m_aabbTree(0)
|
||||
m_aabbTree(0),
|
||||
m_collisionMargin(0.f),
|
||||
m_localScaling(1.f,1.f,1.f)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user