some work on compound collision shapes (not finished yet)
This commit is contained in:
@@ -21,6 +21,7 @@ subject to the following restrictions:
|
||||
#include "CollisionDispatch/ConvexConvexAlgorithm.h"
|
||||
#include "CollisionDispatch/EmptyCollisionAlgorithm.h"
|
||||
#include "CollisionDispatch/ConvexConcaveCollisionAlgorithm.h"
|
||||
#include "CollisionDispatch/CompoundCollisionAlgorithm.h"
|
||||
#include "CollisionShapes/CollisionShape.h"
|
||||
#include "CollisionDispatch/CollisionObject.h"
|
||||
#include <algorithm>
|
||||
@@ -122,6 +123,17 @@ CollisionAlgorithm* CollisionDispatcher::InternalFindAlgorithm(BroadphaseProxy&
|
||||
return new ConvexConcaveCollisionAlgorithm(ci,&proxy1,&proxy0);
|
||||
}
|
||||
|
||||
if (body0->m_collisionShape->IsCompound())
|
||||
{
|
||||
return new CompoundCollisionAlgorithm(ci,&proxy0,&proxy1);
|
||||
} else
|
||||
{
|
||||
if (body1->m_collisionShape->IsCompound())
|
||||
{
|
||||
return new CompoundCollisionAlgorithm(ci,&proxy1,&proxy0);
|
||||
}
|
||||
}
|
||||
|
||||
//failed to find an algorithm
|
||||
return new EmptyAlgorithm(ci);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ subject to the following restrictions:
|
||||
#include "CollisionShapes/SphereShape.h" //for raycasting
|
||||
#include "CollisionShapes/TriangleMeshShape.h" //for raycasting
|
||||
#include "NarrowPhaseCollision/RaycastCallback.h"
|
||||
#include "CollisionShapes/CompoundShape.h"
|
||||
|
||||
#include "NarrowPhaseCollision/SubSimplexConvexCast.h"
|
||||
#include "BroadphaseCollision/BroadphaseInterface.h"
|
||||
@@ -139,58 +140,27 @@ void CollisionWorld::RemoveCollisionObject(CollisionObject* collisionObject)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CollisionWorld::RayTest(const SimdVector3& rayFromWorld, const SimdVector3& rayToWorld, RayResultCallback& resultCallback)
|
||||
void RayTestSingle(const SimdTransform& rayFromTrans,const SimdTransform& rayToTrans,
|
||||
CollisionObject* collisionObject,
|
||||
const CollisionShape* collisionShape,
|
||||
const SimdTransform& colObjWorldTransform,
|
||||
CollisionWorld::RayResultCallback& resultCallback)
|
||||
{
|
||||
|
||||
|
||||
SimdTransform rayFromTrans,rayToTrans;
|
||||
rayFromTrans.setIdentity();
|
||||
rayFromTrans.setOrigin(rayFromWorld);
|
||||
rayToTrans.setIdentity();
|
||||
|
||||
rayToTrans.setOrigin(rayToWorld);
|
||||
|
||||
//do culling based on aabb (rayFrom/rayTo)
|
||||
SimdVector3 rayAabbMin = rayFromWorld;
|
||||
SimdVector3 rayAabbMax = rayFromWorld;
|
||||
rayAabbMin.setMin(rayToWorld);
|
||||
rayAabbMax.setMax(rayToWorld);
|
||||
|
||||
SphereShape pointShape(0.0f);
|
||||
|
||||
/// brute force go over all objects. Once there is a broadphase, use that, or
|
||||
/// add a raycast against aabb first.
|
||||
|
||||
std::vector<CollisionObject*>::iterator iter;
|
||||
|
||||
for (iter=m_collisionObjects.begin();
|
||||
!(iter==m_collisionObjects.end()); iter++)
|
||||
{
|
||||
|
||||
CollisionObject* collisionObject= (*iter);
|
||||
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
SimdVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
collisionObject->m_collisionShape->GetAabb(collisionObject->m_worldTransform,collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
|
||||
//check aabb overlap
|
||||
|
||||
if (TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,collisionObjectAabbMin,collisionObjectAabbMax))
|
||||
{
|
||||
if (collisionObject->m_collisionShape->IsConvex())
|
||||
if (collisionShape->IsConvex())
|
||||
{
|
||||
ConvexCast::CastResult castResult;
|
||||
castResult.m_fraction = 1.f;//??
|
||||
|
||||
ConvexShape* convexShape = (ConvexShape*) collisionObject->m_collisionShape;
|
||||
ConvexShape* convexShape = (ConvexShape*) collisionShape;
|
||||
VoronoiSimplexSolver simplexSolver;
|
||||
SubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
|
||||
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
|
||||
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
|
||||
|
||||
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,collisionObject->m_worldTransform,collisionObject->m_worldTransform,castResult))
|
||||
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
|
||||
{
|
||||
//add hit
|
||||
if (castResult.m_normal.length2() > 0.0001f)
|
||||
@@ -217,12 +187,12 @@ void CollisionWorld::RayTest(const SimdVector3& rayFromWorld, const SimdVector3&
|
||||
else
|
||||
{
|
||||
|
||||
if (collisionObject->m_collisionShape->IsConcave())
|
||||
if (collisionShape->IsConcave())
|
||||
{
|
||||
|
||||
TriangleMeshShape* triangleMesh = (TriangleMeshShape*)collisionObject->m_collisionShape;
|
||||
TriangleMeshShape* triangleMesh = (TriangleMeshShape*)collisionShape;
|
||||
|
||||
SimdTransform worldTocollisionObject = collisionObject->m_worldTransform.inverse();
|
||||
SimdTransform worldTocollisionObject = colObjWorldTransform.inverse();
|
||||
|
||||
SimdVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
|
||||
SimdVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
|
||||
@@ -231,12 +201,12 @@ void CollisionWorld::RayTest(const SimdVector3& rayFromWorld, const SimdVector3&
|
||||
|
||||
struct BridgeTriangleRaycastCallback : public TriangleRaycastCallback
|
||||
{
|
||||
RayResultCallback* m_resultCallback;
|
||||
CollisionWorld::RayResultCallback* m_resultCallback;
|
||||
CollisionObject* m_collisionObject;
|
||||
TriangleMeshShape* m_triangleMesh;
|
||||
|
||||
BridgeTriangleRaycastCallback( const SimdVector3& from,const SimdVector3& to,
|
||||
RayResultCallback* resultCallback, CollisionObject* collisionObject,TriangleMeshShape* triangleMesh):
|
||||
CollisionWorld::RayResultCallback* resultCallback, CollisionObject* collisionObject,TriangleMeshShape* triangleMesh):
|
||||
TriangleRaycastCallback(from,to),
|
||||
m_resultCallback(resultCallback),
|
||||
m_collisionObject(collisionObject),
|
||||
@@ -275,10 +245,75 @@ void CollisionWorld::RayTest(const SimdVector3& rayFromWorld, const SimdVector3&
|
||||
|
||||
triangleMesh->ProcessAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
|
||||
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
//todo: use AABB tree or other BVH acceleration structure!
|
||||
if (collisionShape->IsCompound())
|
||||
{
|
||||
const CompoundShape* compoundShape = static_cast<const CompoundShape*>(collisionShape);
|
||||
int i=0;
|
||||
for (i=0;i<compoundShape->GetNumChildShapes();i++)
|
||||
{
|
||||
SimdTransform childTrans = compoundShape->GetChildTransform(i);
|
||||
const CollisionShape* childCollisionShape = compoundShape->GetChildShape(i);
|
||||
SimdTransform childWorldTrans = colObjWorldTransform * childTrans;
|
||||
RayTestSingle(rayFromTrans,rayToTrans,
|
||||
collisionObject,
|
||||
childCollisionShape,
|
||||
childWorldTrans,
|
||||
resultCallback);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionWorld::RayTest(const SimdVector3& rayFromWorld, const SimdVector3& rayToWorld, RayResultCallback& resultCallback)
|
||||
{
|
||||
|
||||
|
||||
SimdTransform rayFromTrans,rayToTrans;
|
||||
rayFromTrans.setIdentity();
|
||||
rayFromTrans.setOrigin(rayFromWorld);
|
||||
rayToTrans.setIdentity();
|
||||
|
||||
rayToTrans.setOrigin(rayToWorld);
|
||||
|
||||
//do culling based on aabb (rayFrom/rayTo)
|
||||
SimdVector3 rayAabbMin = rayFromWorld;
|
||||
SimdVector3 rayAabbMax = rayFromWorld;
|
||||
rayAabbMin.setMin(rayToWorld);
|
||||
rayAabbMax.setMax(rayToWorld);
|
||||
|
||||
|
||||
/// brute force go over all objects. Once there is a broadphase, use that, or
|
||||
/// add a raycast against aabb first.
|
||||
|
||||
std::vector<CollisionObject*>::iterator iter;
|
||||
|
||||
for (iter=m_collisionObjects.begin();
|
||||
!(iter==m_collisionObjects.end()); iter++)
|
||||
{
|
||||
|
||||
CollisionObject* collisionObject= (*iter);
|
||||
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
SimdVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
collisionObject->m_collisionShape->GetAabb(collisionObject->m_worldTransform,collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
|
||||
//check aabb overlap
|
||||
|
||||
if (TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,collisionObjectAabbMin,collisionObjectAabbMax))
|
||||
{
|
||||
RayTestSingle(rayFromTrans,rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->m_collisionShape,
|
||||
collisionObject->m_worldTransform,
|
||||
resultCallback);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,19 +14,70 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
#include "CollisionDispatch/CompoundCollisionAlgorithm.h"
|
||||
#include "CollisionDispatch/CollisionObject.h"
|
||||
#include "CollisionShapes/CompoundShape.h"
|
||||
|
||||
|
||||
CompoundCollisionAlgorithm::CompoundCollisionAlgorithm( const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
|
||||
:m_dispatcher(ci.m_dispatcher),
|
||||
m_compoundProxy(*proxy0),
|
||||
m_otherProxy(*proxy1)
|
||||
{
|
||||
CollisionObject* colObj = static_cast<CollisionObject*>(m_compoundProxy.m_clientObject);
|
||||
assert (colObj->m_collisionShape->IsCompound());
|
||||
|
||||
CompoundShape* compoundShape = static_cast<CompoundShape*>(colObj->m_collisionShape);
|
||||
int numChildren = compoundShape->GetNumChildShapes();
|
||||
m_childProxies.resize( numChildren );
|
||||
int i;
|
||||
for (i=0;i<numChildren;i++)
|
||||
{
|
||||
m_childProxies[i] = BroadphaseProxy(*proxy0);
|
||||
}
|
||||
|
||||
m_childCollisionAlgorithms.resize(numChildren);
|
||||
for (i=0;i<numChildren;i++)
|
||||
{
|
||||
CollisionShape* childShape = compoundShape->GetChildShape(i);
|
||||
CollisionObject* colObj = static_cast<CollisionObject*>(m_childProxies[i].m_clientObject);
|
||||
CollisionShape* orgShape = colObj->m_collisionShape;
|
||||
colObj->m_collisionShape = childShape;
|
||||
m_childCollisionAlgorithms[i] = m_dispatcher->FindAlgorithm(m_childProxies[i],m_otherProxy);
|
||||
colObj->m_collisionShape =orgShape;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CompoundCollisionAlgorithm::~CompoundCollisionAlgorithm()
|
||||
{
|
||||
int numChildren = m_childCollisionAlgorithms.size();
|
||||
int i;
|
||||
for (i=0;i<numChildren;i++)
|
||||
{
|
||||
delete m_childCollisionAlgorithms[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CompoundCollisionAlgorithm::ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,const DispatcherInfo& dispatchInfo)
|
||||
void CompoundCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy* ,const DispatcherInfo& dispatchInfo)
|
||||
{
|
||||
CollisionObject* colObj = static_cast<CollisionObject*>(m_compoundProxy.m_clientObject);
|
||||
assert (colObj->m_collisionShape->IsCompound());
|
||||
|
||||
CompoundShape* compoundShape = static_cast<CompoundShape*>(colObj->m_collisionShape);
|
||||
|
||||
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);
|
||||
CollisionShape* orgShape = colObj->m_collisionShape;
|
||||
colObj->m_collisionShape = childShape;
|
||||
m_childCollisionAlgorithms[i]->ProcessCollision(&m_childProxies[i],&m_otherProxy,dispatchInfo);
|
||||
//revert back
|
||||
colObj->m_collisionShape =orgShape;
|
||||
}
|
||||
}
|
||||
|
||||
float CompoundCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,const DispatcherInfo& dispatchInfo)
|
||||
|
||||
@@ -23,14 +23,19 @@ subject to the following restrictions:
|
||||
#include "NarrowPhaseCollision/PersistentManifold.h"
|
||||
class Dispatcher;
|
||||
#include "BroadphaseCollision/BroadphaseProxy.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
/// CompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
|
||||
/// Place holder, not fully implemented yet
|
||||
class CompoundCollisionAlgorithm : public CollisionAlgorithm
|
||||
{
|
||||
BroadphaseProxy m_compoundProxy;
|
||||
BroadphaseProxy m_otherProxy;
|
||||
std::vector<BroadphaseProxy> m_childProxies;
|
||||
std::vector<CollisionAlgorithm*> m_childCollisionAlgorithms;
|
||||
|
||||
Dispatcher* m_dispatcher;
|
||||
BroadphaseProxy m_compound;
|
||||
|
||||
BroadphaseProxy m_other;
|
||||
|
||||
Reference in New Issue
Block a user