Working on middle-phase collision detection
This commit is contained in:
parent
7dcc86d746
commit
d894a40d2e
|
@ -98,6 +98,9 @@ void RigidBody::setType(BodyType type) {
|
|||
// Awake the body
|
||||
setIsSleeping(false);
|
||||
|
||||
// Update the active status of currently overlapping pairs
|
||||
updateOverlappingPairs();
|
||||
|
||||
// Ask the broad-phase to test again the collision shapes of the body for collision
|
||||
// detection (as if the body has moved)
|
||||
askForBroadPhaseCollisionCheck();
|
||||
|
@ -683,6 +686,9 @@ void RigidBody::setIsSleeping(bool isSleeping) {
|
|||
// Notify all the components
|
||||
mWorld.setBodyDisabled(mEntity, isSleeping);
|
||||
|
||||
// Update the currently overlapping pairs
|
||||
updateOverlappingPairs();
|
||||
|
||||
if (isSleeping) {
|
||||
|
||||
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, Vector3::zero());
|
||||
|
@ -696,6 +702,23 @@ void RigidBody::setIsSleeping(bool isSleeping) {
|
|||
(isSleeping ? "true" : "false"));
|
||||
}
|
||||
|
||||
// Update whether the current overlapping pairs where this body is involed are active or not
|
||||
void RigidBody::updateOverlappingPairs() {
|
||||
|
||||
// For each proxy-shape of the body
|
||||
const List<Entity>& proxyShapesEntities = mWorld.mCollisionBodyComponents.getProxyShapes(mEntity);
|
||||
for (uint i=0; i < proxyShapesEntities.size(); i++) {
|
||||
|
||||
// Get the currently overlapping pairs for this proxy-shape
|
||||
List<uint64> overlappingPairs = mWorld.mProxyShapesComponents.getOverlappingPairs(proxyShapesEntities[i]);
|
||||
|
||||
for (uint j=0; j < overlappingPairs.size(); j++) {
|
||||
|
||||
mWorld.mCollisionDetection.mOverlappingPairs.updateOverlappingPairIsActive(overlappingPairs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the inverse of the inertia tensor in world coordinates.
|
||||
const Matrix3x3 RigidBody::getInertiaTensorInverseWorld(CollisionWorld& world, Entity bodyEntity) {
|
||||
|
||||
|
|
|
@ -73,6 +73,9 @@ class RigidBody : public CollisionBody {
|
|||
/// Set the variable to know whether or not the body is sleeping
|
||||
void setIsSleeping(bool isSleeping);
|
||||
|
||||
/// Update whether the current overlapping pairs where this body is involed are active or not
|
||||
void updateOverlappingPairs();
|
||||
|
||||
/// Return the inverse of the inertia tensor in world coordinates.
|
||||
static const Matrix3x3 getInertiaTensorInverseWorld(CollisionWorld& world, Entity bodyEntity);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ CapsuleVsCapsuleNarrowPhaseInfoBatch::CapsuleVsCapsuleNarrowPhaseInfoBatch(Memor
|
|||
}
|
||||
|
||||
// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
void CapsuleVsCapsuleNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
void CapsuleVsCapsuleNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
const Transform& shape1Transform, const Transform& shape2Transform) {
|
||||
|
||||
assert(shape1->getType() == CollisionShapeType::CAPSULE);
|
||||
|
@ -60,7 +60,7 @@ void CapsuleVsCapsuleNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Ent
|
|||
isColliding.add(false);
|
||||
|
||||
// Add a collision info for the two collision shapes into the overlapping pair (if not present yet)
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairId, shape1->getId(), shape2->getId());
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairIndex, shape1->getId(), shape2->getId());
|
||||
lastFrameCollisionInfos.add(lastFrameInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ struct CapsuleVsCapsuleNarrowPhaseInfoBatch : public NarrowPhaseInfoBatch {
|
|||
virtual ~CapsuleVsCapsuleNarrowPhaseInfoBatch() = default;
|
||||
|
||||
/// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
virtual void addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
virtual void addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
CollisionShape* shape2, const Transform& shape1Transform,
|
||||
const Transform& shape2Transform);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ NarrowPhaseInfoBatch::~NarrowPhaseInfoBatch() {
|
|||
}
|
||||
|
||||
// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
void NarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
void NarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
const Transform& shape1Transform, const Transform& shape2Transform,
|
||||
MemoryAllocator& shapeAllocator) {
|
||||
|
||||
|
@ -64,7 +64,7 @@ void NarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1,
|
|||
isColliding.add(false);
|
||||
|
||||
// Add a collision info for the two collision shapes into the overlapping pair (if not present yet)
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairId, shape1->getId(), shape2->getId());
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairIndex, shape1->getId(), shape2->getId());
|
||||
lastFrameCollisionInfos.add(lastFrameInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ struct NarrowPhaseInfoBatch {
|
|||
uint getNbObjects() const;
|
||||
|
||||
/// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
void addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
void addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
CollisionShape* shape2, const Transform& shape1Transform,
|
||||
const Transform& shape2Transform, MemoryAllocator& shapeAllocator);
|
||||
|
||||
|
|
|
@ -39,28 +39,28 @@ NarrowPhaseInput::NarrowPhaseInput(MemoryAllocator& allocator, OverlappingPairs&
|
|||
}
|
||||
|
||||
// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
void NarrowPhaseInput::addNarrowPhaseTest(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
void NarrowPhaseInput::addNarrowPhaseTest(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
const Transform& shape1Transform, const Transform& shape2Transform,
|
||||
NarrowPhaseAlgorithmType narrowPhaseAlgorithmType, MemoryAllocator& shapeAllocator) {
|
||||
|
||||
switch (narrowPhaseAlgorithmType) {
|
||||
case NarrowPhaseAlgorithmType::SphereVsSphere:
|
||||
mSphereVsSphereBatch.addNarrowPhaseInfo(pairId, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform);
|
||||
mSphereVsSphereBatch.addNarrowPhaseInfo(pairId, pairIndex, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform);
|
||||
break;
|
||||
case NarrowPhaseAlgorithmType::SphereVsCapsule:
|
||||
mSphereVsCapsuleBatch.addNarrowPhaseInfo(pairId, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform);
|
||||
mSphereVsCapsuleBatch.addNarrowPhaseInfo(pairId, pairIndex, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform);
|
||||
break;
|
||||
case NarrowPhaseAlgorithmType::CapsuleVsCapsule:
|
||||
mCapsuleVsCapsuleBatch.addNarrowPhaseInfo(pairId, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform);
|
||||
mCapsuleVsCapsuleBatch.addNarrowPhaseInfo(pairId, pairIndex, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform);
|
||||
break;
|
||||
case NarrowPhaseAlgorithmType::SphereVsConvexPolyhedron:
|
||||
mSphereVsConvexPolyhedronBatch.addNarrowPhaseInfo(pairId, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform, shapeAllocator);
|
||||
mSphereVsConvexPolyhedronBatch.addNarrowPhaseInfo(pairId, pairIndex, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform, shapeAllocator);
|
||||
break;
|
||||
case NarrowPhaseAlgorithmType::CapsuleVsConvexPolyhedron:
|
||||
mCapsuleVsConvexPolyhedronBatch.addNarrowPhaseInfo(pairId, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform, shapeAllocator);
|
||||
mCapsuleVsConvexPolyhedronBatch.addNarrowPhaseInfo(pairId, pairIndex, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform, shapeAllocator);
|
||||
break;
|
||||
case NarrowPhaseAlgorithmType::ConvexPolyhedronVsConvexPolyhedron:
|
||||
mConvexPolyhedronVsConvexPolyhedronBatch.addNarrowPhaseInfo(pairId, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform, shapeAllocator);
|
||||
mConvexPolyhedronVsConvexPolyhedronBatch.addNarrowPhaseInfo(pairId, pairIndex, proxyShape1, proxyShape2, shape1, shape2, shape1Transform, shape2Transform, shapeAllocator);
|
||||
break;
|
||||
case NarrowPhaseAlgorithmType::None:
|
||||
// Must never happen
|
||||
|
|
|
@ -67,7 +67,7 @@ class NarrowPhaseInput {
|
|||
NarrowPhaseInput(MemoryAllocator& allocator, OverlappingPairs& overlappingPairs);
|
||||
|
||||
/// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
void addNarrowPhaseTest(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
void addNarrowPhaseTest(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
CollisionShape* shape2, const Transform& shape1Transform,
|
||||
const Transform& shape2Transform, NarrowPhaseAlgorithmType narrowPhaseAlgorithmType,
|
||||
MemoryAllocator& shapeAllocator);
|
||||
|
|
|
@ -39,7 +39,7 @@ SphereVsCapsuleNarrowPhaseInfoBatch::SphereVsCapsuleNarrowPhaseInfoBatch(MemoryA
|
|||
}
|
||||
|
||||
// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
void SphereVsCapsuleNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
void SphereVsCapsuleNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
const Transform& shape1Transform, const Transform& shape2Transform) {
|
||||
|
||||
bool isSphereShape1 = shape1->getType() == CollisionShapeType::SPHERE;
|
||||
|
@ -63,7 +63,7 @@ void SphereVsCapsuleNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Enti
|
|||
isColliding.add(false);
|
||||
|
||||
// Add a collision info for the two collision shapes into the overlapping pair (if not present yet)
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairId, shape1->getId(), shape2->getId());
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairIndex, shape1->getId(), shape2->getId());
|
||||
lastFrameCollisionInfos.add(lastFrameInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ struct SphereVsCapsuleNarrowPhaseInfoBatch : public NarrowPhaseInfoBatch {
|
|||
virtual ~SphereVsCapsuleNarrowPhaseInfoBatch() = default;
|
||||
|
||||
/// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
virtual void addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
virtual void addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
CollisionShape* shape2, const Transform& shape1Transform,
|
||||
const Transform& shape2Transform);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ SphereVsSphereNarrowPhaseInfoBatch::SphereVsSphereNarrowPhaseInfoBatch(MemoryAll
|
|||
}
|
||||
|
||||
// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
void SphereVsSphereNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
void SphereVsSphereNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1, CollisionShape* shape2,
|
||||
const Transform& shape1Transform, const Transform& shape2Transform) {
|
||||
|
||||
assert(shape1->getType() == CollisionShapeType::SPHERE);
|
||||
|
@ -56,7 +56,7 @@ void SphereVsSphereNarrowPhaseInfoBatch::addNarrowPhaseInfo(uint64 pairId, Entit
|
|||
isColliding.add(false);
|
||||
|
||||
// Add a collision info for the two collision shapes into the overlapping pair (if not present yet)
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairId, shape1->getId(), shape2->getId());
|
||||
LastFrameCollisionInfo* lastFrameInfo = mOverlappingPairs.addLastFrameInfoIfNecessary(pairIndex, shape1->getId(), shape2->getId());
|
||||
lastFrameCollisionInfos.add(lastFrameInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ struct SphereVsSphereNarrowPhaseInfoBatch : public NarrowPhaseInfoBatch {
|
|||
virtual ~SphereVsSphereNarrowPhaseInfoBatch() override = default;
|
||||
|
||||
/// Add shapes to be tested during narrow-phase collision detection into the batch
|
||||
virtual void addNarrowPhaseInfo(uint64 pairId, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
virtual void addNarrowPhaseInfo(uint64 pairId, uint64 pairIndex, Entity proxyShape1, Entity proxyShape2, CollisionShape* shape1,
|
||||
CollisionShape* shape2, const Transform& shape1Transform,
|
||||
const Transform& shape2Transform);
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ class CollisionShape {
|
|||
CollisionShapeName mName;
|
||||
|
||||
/// Unique identifier of the shape inside an overlapping pair
|
||||
uint mId;
|
||||
uint32 mId;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -125,7 +125,7 @@ class CollisionShape {
|
|||
virtual void getLocalBounds(Vector3& min, Vector3& max) const=0;
|
||||
|
||||
/// Return the id of the shape
|
||||
uint getId() const;
|
||||
uint32 getId() const;
|
||||
|
||||
/// Return the local inertia tensor of the collision shapes
|
||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const=0;
|
||||
|
@ -166,7 +166,7 @@ inline CollisionShapeType CollisionShape::getType() const {
|
|||
}
|
||||
|
||||
// Return the id of the shape
|
||||
inline uint CollisionShape::getId() const {
|
||||
inline uint32 CollisionShape::getId() const {
|
||||
return mId;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,9 @@ OverlappingPairs::OverlappingPairs(MemoryAllocator& persistentMemoryAllocator, M
|
|||
CollisionBodyComponents& collisionBodyComponents, RigidBodyComponents& rigidBodyComponents, Set<bodypair> &noCollisionPairs, CollisionDispatch &collisionDispatch)
|
||||
: mPersistentAllocator(persistentMemoryAllocator), mTempMemoryAllocator(temporaryMemoryAllocator),
|
||||
mNbPairs(0), mConcavePairsStartIndex(0), mPairDataSize(sizeof(uint64) + sizeof(int32) + sizeof(int32) + sizeof(Entity) +
|
||||
sizeof(Entity) + sizeof(Map<ShapeIdPair, LastFrameCollisionInfo*>) +
|
||||
sizeof(bool) + sizeof(bool) + sizeof(NarrowPhaseAlgorithmType)),
|
||||
sizeof(Entity) + sizeof(Map<uint64, LastFrameCollisionInfo*>) +
|
||||
sizeof(bool) + sizeof(bool) + sizeof(NarrowPhaseAlgorithmType) +
|
||||
sizeof(bool)),
|
||||
mNbAllocatedPairs(0), mBuffer(nullptr),
|
||||
mMapPairIdToPairIndex(persistentMemoryAllocator),
|
||||
mProxyShapeComponents(proxyShapeComponents), mCollisionBodyComponents(collisionBodyComponents),
|
||||
|
@ -205,10 +206,11 @@ void OverlappingPairs::allocate(uint64 nbPairsToAllocate) {
|
|||
int32* newPairBroadPhaseId2 = reinterpret_cast<int32*>(newPairBroadPhaseId1 + nbPairsToAllocate);
|
||||
Entity* newProxyShapes1 = reinterpret_cast<Entity*>(newPairBroadPhaseId2 + nbPairsToAllocate);
|
||||
Entity* newProxyShapes2 = reinterpret_cast<Entity*>(newProxyShapes1 + nbPairsToAllocate);
|
||||
Map<ShapeIdPair, LastFrameCollisionInfo*>* newLastFrameCollisionInfos = reinterpret_cast<Map<ShapeIdPair, LastFrameCollisionInfo*>*>(newProxyShapes2 + nbPairsToAllocate);
|
||||
Map<uint64, LastFrameCollisionInfo*>* newLastFrameCollisionInfos = reinterpret_cast<Map<uint64, LastFrameCollisionInfo*>*>(newProxyShapes2 + nbPairsToAllocate);
|
||||
bool* newNeedToTestOverlap = reinterpret_cast<bool*>(newLastFrameCollisionInfos + nbPairsToAllocate);
|
||||
bool* newIsActive = reinterpret_cast<bool*>(newNeedToTestOverlap + nbPairsToAllocate);
|
||||
NarrowPhaseAlgorithmType* newNarrowPhaseAlgorithmType = reinterpret_cast<NarrowPhaseAlgorithmType*>(newIsActive + nbPairsToAllocate);
|
||||
bool* newIsShape1Convex = reinterpret_cast<bool*>(newNarrowPhaseAlgorithmType + nbPairsToAllocate);
|
||||
|
||||
// If there was already pairs before
|
||||
if (mNbPairs > 0) {
|
||||
|
@ -219,10 +221,11 @@ void OverlappingPairs::allocate(uint64 nbPairsToAllocate) {
|
|||
memcpy(newPairBroadPhaseId2, mPairBroadPhaseId2, mNbPairs * sizeof(int32));
|
||||
memcpy(newProxyShapes1, mProxyShapes1, mNbPairs * sizeof(Entity));
|
||||
memcpy(newProxyShapes2, mProxyShapes2, mNbPairs * sizeof(Entity));
|
||||
memcpy(newLastFrameCollisionInfos, mLastFrameCollisionInfos, mNbPairs * sizeof(Map<ShapeIdPair, LastFrameCollisionInfo*>));
|
||||
memcpy(newLastFrameCollisionInfos, mLastFrameCollisionInfos, mNbPairs * sizeof(Map<uint64, LastFrameCollisionInfo*>));
|
||||
memcpy(newNeedToTestOverlap, mNeedToTestOverlap, mNbPairs * sizeof(bool));
|
||||
memcpy(newIsActive, mIsActive, mNbPairs * sizeof(bool));
|
||||
memcpy(newNarrowPhaseAlgorithmType, mNarrowPhaseAlgorithmType, mNbPairs * sizeof(NarrowPhaseAlgorithmType));
|
||||
memcpy(newIsShape1Convex, mIsShape1Convex, mNbPairs * sizeof(bool));
|
||||
|
||||
// Deallocate previous memory
|
||||
mPersistentAllocator.release(mBuffer, mNbAllocatedPairs * mPairDataSize);
|
||||
|
@ -238,43 +241,57 @@ void OverlappingPairs::allocate(uint64 nbPairsToAllocate) {
|
|||
mNeedToTestOverlap = newNeedToTestOverlap;
|
||||
mIsActive = newIsActive;
|
||||
mNarrowPhaseAlgorithmType = newNarrowPhaseAlgorithmType;
|
||||
mIsShape1Convex = newIsShape1Convex;
|
||||
|
||||
mNbAllocatedPairs = nbPairsToAllocate;
|
||||
}
|
||||
|
||||
// Add an overlapping pair
|
||||
uint64 OverlappingPairs::addPair(ProxyShape* shape1, ProxyShape* shape2, bool isActive) {
|
||||
uint64 OverlappingPairs::addPair(ProxyShape* shape1, ProxyShape* shape2) {
|
||||
|
||||
RP3D_PROFILE("OverlappingPairs::addPair()", mProfiler);
|
||||
|
||||
const CollisionShape* collisionShape1 = mProxyShapeComponents.getCollisionShape(shape1->getEntity());
|
||||
const CollisionShape* collisionShape2 = mProxyShapeComponents.getCollisionShape(shape2->getEntity());
|
||||
|
||||
// Prepare to add new pair (allocate memory if necessary and compute insertion index)
|
||||
uint64 index = prepareAddPair(collisionShape1->isConvex() && collisionShape2->isConvex());
|
||||
const bool isShape1Convex = collisionShape1->isConvex();
|
||||
const bool isShape2Convex = collisionShape2->isConvex();
|
||||
const bool isConvexVsConvex = isShape1Convex && isShape2Convex;
|
||||
|
||||
const uint32 shape1Id = static_cast<uint32>(shape1->getBroadPhaseId());
|
||||
const uint32 shape2Id = static_cast<uint32>(shape2->getBroadPhaseId());
|
||||
// Prepare to add new pair (allocate memory if necessary and compute insertion index)
|
||||
uint64 index = prepareAddPair(isConvexVsConvex);
|
||||
|
||||
const uint32 broadPhase1Id = static_cast<uint32>(shape1->getBroadPhaseId());
|
||||
const uint32 broadPhase2Id = static_cast<uint32>(shape2->getBroadPhaseId());
|
||||
|
||||
// Compute a unique id for the overlapping pair
|
||||
const uint64 pairId = pairNumbers(std::max(shape1Id, shape2Id), std::min(shape1Id, shape2Id));
|
||||
const uint64 pairId = pairNumbers(std::max(broadPhase1Id, broadPhase2Id), std::min(broadPhase1Id, broadPhase2Id));
|
||||
|
||||
assert(!mMapPairIdToPairIndex.containsKey(pairId));
|
||||
|
||||
// Select the narrow phase algorithm to use according to the two collision shapes
|
||||
NarrowPhaseAlgorithmType algorithmType = mCollisionDispatch.selectNarrowPhaseAlgorithm(collisionShape1->getType(),
|
||||
collisionShape2->getType());
|
||||
NarrowPhaseAlgorithmType algorithmType;
|
||||
if (isConvexVsConvex) {
|
||||
|
||||
algorithmType = mCollisionDispatch.selectNarrowPhaseAlgorithm(collisionShape1->getType(), collisionShape2->getType());
|
||||
}
|
||||
else {
|
||||
|
||||
algorithmType = mCollisionDispatch.selectNarrowPhaseAlgorithm(isShape1Convex ? collisionShape1->getType() : collisionShape2->getType(),
|
||||
CollisionShapeType::CONVEX_POLYHEDRON);
|
||||
}
|
||||
|
||||
// Insert the new component data
|
||||
new (mPairIds + index) uint64(pairId);
|
||||
new (mPairBroadPhaseId1 + index) int32(shape1->getBroadPhaseId());
|
||||
new (mPairBroadPhaseId2 + index) int32(shape2->getBroadPhaseId());
|
||||
new (mProxyShapes1 + index) Entity(shape1->getEntity());
|
||||
new (mProxyShapes2 + index) Entity(shape2->getEntity());
|
||||
new (mLastFrameCollisionInfos + index) Map<ShapeIdPair, LastFrameCollisionInfo*>(mPersistentAllocator);
|
||||
new (mLastFrameCollisionInfos + index) Map<uint64, LastFrameCollisionInfo*>(mPersistentAllocator);
|
||||
new (mNeedToTestOverlap + index) bool(false);
|
||||
new (mIsActive + index) bool(isActive);
|
||||
new (mIsActive + index) bool(true);
|
||||
new (mNarrowPhaseAlgorithmType + index) NarrowPhaseAlgorithmType(algorithmType);
|
||||
|
||||
new (mIsShape1Convex + index) bool(isShape1Convex);
|
||||
|
||||
// Map the entity with the new component lookup index
|
||||
mMapPairIdToPairIndex.add(Pair<uint64, uint64>(pairId, index));
|
||||
|
@ -290,6 +307,8 @@ uint64 OverlappingPairs::addPair(ProxyShape* shape1, ProxyShape* shape2, bool is
|
|||
assert(mConcavePairsStartIndex <= mNbPairs);
|
||||
assert(mNbPairs == static_cast<uint64>(mMapPairIdToPairIndex.size()));
|
||||
|
||||
updateOverlappingPairIsActive(pairId);
|
||||
|
||||
return pairId;
|
||||
}
|
||||
|
||||
|
@ -305,10 +324,11 @@ void OverlappingPairs::movePairToIndex(uint64 srcIndex, uint64 destIndex) {
|
|||
mPairBroadPhaseId2[destIndex] = mPairBroadPhaseId2[srcIndex];
|
||||
new (mProxyShapes1 + destIndex) Entity(mProxyShapes1[srcIndex]);
|
||||
new (mProxyShapes2 + destIndex) Entity(mProxyShapes2[srcIndex]);
|
||||
new (mLastFrameCollisionInfos + destIndex) Map<ShapeIdPair, LastFrameCollisionInfo*>(mLastFrameCollisionInfos[srcIndex]);
|
||||
new (mLastFrameCollisionInfos + destIndex) Map<uint64, LastFrameCollisionInfo*>(mLastFrameCollisionInfos[srcIndex]);
|
||||
mNeedToTestOverlap[destIndex] = mNeedToTestOverlap[srcIndex];
|
||||
mIsActive[destIndex] = mIsActive[srcIndex];
|
||||
new (mNarrowPhaseAlgorithmType + destIndex) NarrowPhaseAlgorithmType(mNarrowPhaseAlgorithmType[srcIndex]);
|
||||
mIsShape1Convex[destIndex] = mIsShape1Convex[srcIndex];
|
||||
|
||||
// Destroy the source pair
|
||||
destroyPair(srcIndex);
|
||||
|
@ -330,10 +350,11 @@ void OverlappingPairs::swapPairs(uint64 index1, uint64 index2) {
|
|||
int32 pairBroadPhaseId2 = mPairBroadPhaseId2[index1];
|
||||
Entity proxyShape1 = mProxyShapes1[index1];
|
||||
Entity proxyShape2 = mProxyShapes2[index1];
|
||||
Map<ShapeIdPair, LastFrameCollisionInfo*> lastFrameCollisionInfo(mLastFrameCollisionInfos[index1]);
|
||||
Map<uint64, LastFrameCollisionInfo*> lastFrameCollisionInfo(mLastFrameCollisionInfos[index1]);
|
||||
bool needTestOverlap = mNeedToTestOverlap[index1];
|
||||
bool isActive = mIsActive[index1];
|
||||
NarrowPhaseAlgorithmType narrowPhaseAlgorithmType = mNarrowPhaseAlgorithmType[index1];
|
||||
bool isShape1Convex = mIsShape1Convex[index1];
|
||||
|
||||
// Destroy pair 1
|
||||
destroyPair(index1);
|
||||
|
@ -346,10 +367,11 @@ void OverlappingPairs::swapPairs(uint64 index1, uint64 index2) {
|
|||
mPairBroadPhaseId2[index2] = pairBroadPhaseId2;
|
||||
new (mProxyShapes1 + index2) Entity(proxyShape1);
|
||||
new (mProxyShapes2 + index2) Entity(proxyShape2);
|
||||
new (mLastFrameCollisionInfos + index2) Map<ShapeIdPair, LastFrameCollisionInfo*>(lastFrameCollisionInfo);
|
||||
new (mLastFrameCollisionInfos + index2) Map<uint64, LastFrameCollisionInfo*>(lastFrameCollisionInfo);
|
||||
mNeedToTestOverlap[index2] = needTestOverlap;
|
||||
mIsActive[index2] = isActive;
|
||||
new (mNarrowPhaseAlgorithmType + index2) NarrowPhaseAlgorithmType(narrowPhaseAlgorithmType);
|
||||
mIsShape1Convex[index2] = isShape1Convex;
|
||||
|
||||
// Update the pairID to pair index mapping
|
||||
mMapPairIdToPairIndex.add(Pair<uint64, uint64>(pairId, index2));
|
||||
|
@ -370,33 +392,60 @@ void OverlappingPairs::destroyPair(uint64 index) {
|
|||
|
||||
mProxyShapes1[index].~Entity();
|
||||
mProxyShapes2[index].~Entity();
|
||||
mLastFrameCollisionInfos[index].~Map<ShapeIdPair, LastFrameCollisionInfo*>();
|
||||
mLastFrameCollisionInfos[index].~Map<uint64, LastFrameCollisionInfo*>();
|
||||
mNarrowPhaseAlgorithmType[index].~NarrowPhaseAlgorithmType();
|
||||
}
|
||||
|
||||
// Add a new last frame collision info if it does not exist for the given shapes already
|
||||
LastFrameCollisionInfo* OverlappingPairs::addLastFrameInfoIfNecessary(uint64 pairId, uint shapeId1, uint shapeId2) {
|
||||
|
||||
RP3D_PROFILE("OverlappingPairs::addLastFrameInfoIfNecessary()", mProfiler);
|
||||
// Update whether a given overlapping pair is active or not
|
||||
void OverlappingPairs::updateOverlappingPairIsActive(uint64 pairId) {
|
||||
|
||||
assert(mMapPairIdToPairIndex.containsKey(pairId));
|
||||
|
||||
const uint64 index = mMapPairIdToPairIndex[pairId];
|
||||
assert(index < mNbPairs);
|
||||
const uint64 pairIndex = mMapPairIdToPairIndex[pairId];
|
||||
|
||||
const Entity proxyShape1 = mProxyShapes1[pairIndex];
|
||||
const Entity proxyShape2 = mProxyShapes2[pairIndex];
|
||||
|
||||
const Entity body1 = mProxyShapeComponents.getBody(proxyShape1);
|
||||
const Entity body2 = mProxyShapeComponents.getBody(proxyShape2);
|
||||
|
||||
const bool isBody1Enabled = !mCollisionBodyComponents.getIsEntityDisabled(body1);
|
||||
const bool isBody2Enabled = !mCollisionBodyComponents.getIsEntityDisabled(body2);
|
||||
const bool isBody1Static = mRigidBodyComponents.hasComponent(body1) &&
|
||||
mRigidBodyComponents.getBodyType(body1) == BodyType::STATIC;
|
||||
const bool isBody2Static = mRigidBodyComponents.hasComponent(body2) &&
|
||||
mRigidBodyComponents.getBodyType(body2) == BodyType::STATIC;
|
||||
|
||||
const bool isBody1Active = isBody1Enabled && !isBody1Static;
|
||||
const bool isBody2Active = isBody2Enabled && !isBody2Static;
|
||||
|
||||
// Check if the bodies are in the set of bodies that cannot collide between each other
|
||||
bodypair bodiesIndex = OverlappingPairs::computeBodiesIndexPair(body1, body2);
|
||||
bool bodiesCanCollide = !mNoCollisionPairs.contains(bodiesIndex);
|
||||
|
||||
mIsActive[pairIndex] = bodiesCanCollide && (isBody1Active || isBody2Active);
|
||||
}
|
||||
|
||||
// Add a new last frame collision info if it does not exist for the given shapes already
|
||||
LastFrameCollisionInfo* OverlappingPairs::addLastFrameInfoIfNecessary(uint64 pairIndex, uint32 shapeId1, uint32 shapeId2) {
|
||||
|
||||
RP3D_PROFILE("OverlappingPairs::addLastFrameInfoIfNecessary()", mProfiler);
|
||||
|
||||
assert(pairIndex < mNbPairs);
|
||||
|
||||
// Try to get the corresponding last frame collision info
|
||||
const ShapeIdPair shapeIdPair(shapeId1, shapeId2);
|
||||
const uint64 shapesId = pairNumbers(std::max(shapeId1, shapeId2), std::min(shapeId1, shapeId2));
|
||||
|
||||
// If there is no collision info for those two shapes already
|
||||
auto it = mLastFrameCollisionInfos[index].find(shapeIdPair);
|
||||
if (it == mLastFrameCollisionInfos[index].end()) {
|
||||
auto it = mLastFrameCollisionInfos[pairIndex].find(shapesId);
|
||||
if (it == mLastFrameCollisionInfos[pairIndex].end()) {
|
||||
|
||||
// Create a new collision info
|
||||
LastFrameCollisionInfo* collisionInfo = new (mPersistentAllocator.allocate(sizeof(LastFrameCollisionInfo)))
|
||||
LastFrameCollisionInfo();
|
||||
|
||||
// Add it into the map of collision infos
|
||||
mLastFrameCollisionInfos[index].add(Pair<ShapeIdPair, LastFrameCollisionInfo*>(shapeIdPair, collisionInfo));
|
||||
mLastFrameCollisionInfos[pairIndex].add(Pair<uint64, LastFrameCollisionInfo*>(shapesId, collisionInfo));
|
||||
|
||||
return collisionInfo;
|
||||
}
|
||||
|
@ -439,28 +488,3 @@ void OverlappingPairs::clearObsoleteLastFrameCollisionInfos() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if the overlapping pair between two shapes is active
|
||||
bool OverlappingPairs::computeIsPairActive(ProxyShape* shape1, ProxyShape* shape2) {
|
||||
|
||||
const Entity body1Entity = mProxyShapeComponents.getBody(shape1->getEntity());
|
||||
const Entity body2Entity = mProxyShapeComponents.getBody(shape2->getEntity());
|
||||
|
||||
const bool isStaticRigidBody1 = mRigidBodyComponents.hasComponent(body1Entity) &&
|
||||
mRigidBodyComponents.getBodyType(body1Entity) == BodyType::STATIC;
|
||||
const bool isStaticRigidBody2 = mRigidBodyComponents.hasComponent(body2Entity) &&
|
||||
mRigidBodyComponents.getBodyType(body2Entity) == BodyType::STATIC;
|
||||
|
||||
// Check that at least one body is enabled (active and awake) and not static
|
||||
// TODO : Do not test this every frame
|
||||
bool isBody1Active = !mCollisionBodyComponents.getIsEntityDisabled(body1Entity) && !isStaticRigidBody1;
|
||||
bool isBody2Active = !mCollisionBodyComponents.getIsEntityDisabled(body2Entity) && !isStaticRigidBody2;
|
||||
if (!isBody1Active && !isBody2Active) return false;
|
||||
|
||||
// Check if the bodies are in the set of bodies that cannot collide between each other
|
||||
// TODO : Do not check this every frame but remove and do not create overlapping pairs of bodies in this situation
|
||||
bodypair bodiesIndex = OverlappingPairs::computeBodiesIndexPair(body1Entity, body2Entity);
|
||||
if (mNoCollisionPairs.contains(bodiesIndex) > 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -104,11 +104,6 @@ struct LastFrameCollisionInfo {
|
|||
*/
|
||||
class OverlappingPairs {
|
||||
|
||||
public:
|
||||
|
||||
// TODO : Try to use a pairing function like pairNumbers() here
|
||||
using ShapeIdPair = Pair<uint, uint>;
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Constants -------------------- //
|
||||
|
@ -165,7 +160,7 @@ class OverlappingPairs {
|
|||
/// If two convex shapes overlap, we have a single collision data but if one shape is concave,
|
||||
/// we might have collision data for several overlapping triangles. The key in the map is the
|
||||
/// shape Ids of the two collision shapes.
|
||||
Map<ShapeIdPair, LastFrameCollisionInfo*>* mLastFrameCollisionInfos;
|
||||
Map<uint64, LastFrameCollisionInfo*>* mLastFrameCollisionInfos;
|
||||
|
||||
/// True if we need to test if the convex vs convex overlapping pairs of shapes still overlap
|
||||
bool* mNeedToTestOverlap;
|
||||
|
@ -176,6 +171,9 @@ class OverlappingPairs {
|
|||
/// Array with the pointer to the narrow-phase algorithm for each overlapping pair
|
||||
NarrowPhaseAlgorithmType* mNarrowPhaseAlgorithmType;
|
||||
|
||||
/// True if the first shape of the pair is convex
|
||||
bool* mIsShape1Convex;
|
||||
|
||||
/// Reference to the proxy-shapes components
|
||||
ProxyShapeComponents& mProxyShapeComponents;
|
||||
|
||||
|
@ -235,7 +233,7 @@ class OverlappingPairs {
|
|||
OverlappingPairs& operator=(const OverlappingPairs& pair) = delete;
|
||||
|
||||
/// Add an overlapping pair
|
||||
uint64 addPair(ProxyShape* shape1, ProxyShape* shape2, bool isActive);
|
||||
uint64 addPair(ProxyShape* shape1, ProxyShape* shape2);
|
||||
|
||||
/// Remove a component at a given index
|
||||
void removePair(uint64 pairId);
|
||||
|
@ -261,14 +259,20 @@ class OverlappingPairs {
|
|||
/// Notify if a given pair is active or not
|
||||
void setIsPairActive(uint64 pairId, bool isActive);
|
||||
|
||||
/// Return the index of a given overlapping pair in the internal array
|
||||
uint64 getPairIndex(uint64 pairId) const;
|
||||
|
||||
/// Return the last frame collision info
|
||||
LastFrameCollisionInfo* getLastFrameCollisionInfo(uint64, ShapeIdPair& shapeIds);
|
||||
LastFrameCollisionInfo* getLastFrameCollisionInfo(uint64, uint64 shapesId);
|
||||
|
||||
/// Return a reference to the temporary memory allocator
|
||||
MemoryAllocator& getTemporaryAllocator();
|
||||
|
||||
/// Add a new last frame collision info if it does not exist for the given shapes already
|
||||
LastFrameCollisionInfo* addLastFrameInfoIfNecessary(uint64 pairId, uint shapeId1, uint shapeId2);
|
||||
LastFrameCollisionInfo* addLastFrameInfoIfNecessary(uint64 pairIndex, uint32 shapeId1, uint32 shapeId2);
|
||||
|
||||
/// Update whether a given overlapping pair is active or not
|
||||
void updateOverlappingPairIsActive(uint64 pairId);
|
||||
|
||||
/// Delete all the obsolete last frame collision info
|
||||
void clearObsoleteLastFrameCollisionInfos();
|
||||
|
@ -276,9 +280,6 @@ class OverlappingPairs {
|
|||
/// Return the pair of bodies index of the pair
|
||||
static bodypair computeBodiesIndexPair(Entity body1Entity, Entity body2Entity);
|
||||
|
||||
/// Return true if the overlapping pair between two shapes is active
|
||||
bool computeIsPairActive(ProxyShape* shape1, ProxyShape* shape2);
|
||||
|
||||
/// Set if we need to test a given pair for overlap
|
||||
void setNeedToTestOverlap(uint64 pairId, bool needToTestOverlap);
|
||||
|
||||
|
@ -317,14 +318,20 @@ inline void OverlappingPairs::setIsPairActive(uint64 pairId, bool isActive) {
|
|||
mIsActive[mMapPairIdToPairIndex[pairId]] = isActive;
|
||||
}
|
||||
|
||||
// Return the index of a given overlapping pair in the internal array
|
||||
inline uint64 OverlappingPairs::getPairIndex(uint64 pairId) const {
|
||||
assert(mMapPairIdToPairIndex.containsKey(pairId));
|
||||
return mMapPairIdToPairIndex[pairId];
|
||||
}
|
||||
|
||||
// Return the last frame collision info for a given shape id or nullptr if none is found
|
||||
inline LastFrameCollisionInfo* OverlappingPairs::getLastFrameCollisionInfo(uint64 pairId, ShapeIdPair& shapeIds) {
|
||||
inline LastFrameCollisionInfo* OverlappingPairs::getLastFrameCollisionInfo(uint64 pairId, uint64 shapesId) {
|
||||
|
||||
assert(mMapPairIdToPairIndex.containsKey(pairId));
|
||||
const uint64 index = mMapPairIdToPairIndex[pairId];
|
||||
assert(index < mNbPairs);
|
||||
|
||||
Map<ShapeIdPair, LastFrameCollisionInfo*>::Iterator it = mLastFrameCollisionInfos[index].find(shapeIds);
|
||||
Map<uint64, LastFrameCollisionInfo*>::Iterator it = mLastFrameCollisionInfos[index].find(shapesId);
|
||||
if (it != mLastFrameCollisionInfos[index].end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ void CollisionDetectionSystem::updateOverlappingPairs(const List<Pair<int32, int
|
|||
if (shape1->getCollisionShape()->isConvex() || shape2->getCollisionShape()->isConvex()) {
|
||||
|
||||
// Add the new overlapping pair
|
||||
mOverlappingPairs.addPair(shape1, shape2, mOverlappingPairs.computeIsPairActive(shape1, shape2));
|
||||
mOverlappingPairs.addPair(shape1, shape2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,84 +217,47 @@ void CollisionDetectionSystem::computeMiddlePhase(OverlappingPairs& overlappingP
|
|||
// For each possible convex vs convex pair of bodies
|
||||
for (uint64 i=0; i < overlappingPairs.getNbConvexVsConvexPairs(); i++) {
|
||||
|
||||
const Entity proxyShape1Entity = overlappingPairs.mProxyShapes1[i];
|
||||
const Entity proxyShape2Entity = overlappingPairs.mProxyShapes2[i];
|
||||
|
||||
const uint proxyShape1Index = mProxyShapesComponents.getEntityIndex(proxyShape1Entity);
|
||||
const uint proxyShape2Index = mProxyShapesComponents.getEntityIndex(proxyShape2Entity);
|
||||
|
||||
assert(mProxyShapesComponents.mBroadPhaseId[proxyShape1Index] != -1);
|
||||
assert(mProxyShapesComponents.mBroadPhaseId[proxyShape2Index] != -1);
|
||||
assert(mProxyShapesComponents.mBroadPhaseId[proxyShape1Index] != mProxyShapesComponents.mBroadPhaseId[proxyShape2Index]);
|
||||
|
||||
const Entity body1Entity = mProxyShapesComponents.mBodiesEntities[proxyShape1Index];
|
||||
const Entity body2Entity = mProxyShapesComponents.mBodiesEntities[proxyShape2Index];
|
||||
|
||||
const bool isStaticRigidBody1 = mWorld->mRigidBodyComponents.hasComponent(body1Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body1Entity) == BodyType::STATIC;
|
||||
const bool isStaticRigidBody2 = mWorld->mRigidBodyComponents.hasComponent(body2Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body2Entity) == BodyType::STATIC;
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes1[i]) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes2[i]) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes1[i]) != mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes2[i]));
|
||||
|
||||
// Check that at least one body is enabled (active and awake) and not static
|
||||
// TODO : Do not test this every frame
|
||||
bool isBody1Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body1Entity) && !isStaticRigidBody1;
|
||||
bool isBody2Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body2Entity) && !isStaticRigidBody2;
|
||||
if (!isBody1Active && !isBody2Active) continue;
|
||||
if (mOverlappingPairs.mIsActive[i]) {
|
||||
|
||||
// Check if the bodies are in the set of bodies that cannot collide between each other
|
||||
// TODO : Do not check this every frame but remove and do not create overlapping pairs of bodies in this situation
|
||||
bodypair bodiesIndex = OverlappingPairs::computeBodiesIndexPair(body1Entity, body2Entity);
|
||||
if (mNoCollisionPairs.contains(bodiesIndex) > 0) continue;
|
||||
const Entity proxyShape1Entity = overlappingPairs.mProxyShapes1[i];
|
||||
const Entity proxyShape2Entity = overlappingPairs.mProxyShapes2[i];
|
||||
|
||||
CollisionShape* collisionShape1 = mProxyShapesComponents.mCollisionShapes[proxyShape1Index];
|
||||
CollisionShape* collisionShape2 = mProxyShapesComponents.mCollisionShapes[proxyShape2Index];
|
||||
const uint proxyShape1Index = mProxyShapesComponents.getEntityIndex(proxyShape1Entity);
|
||||
const uint proxyShape2Index = mProxyShapesComponents.getEntityIndex(proxyShape2Entity);
|
||||
|
||||
NarrowPhaseAlgorithmType algorithmType = overlappingPairs.mNarrowPhaseAlgorithmType[i];
|
||||
CollisionShape* collisionShape1 = mProxyShapesComponents.mCollisionShapes[proxyShape1Index];
|
||||
CollisionShape* collisionShape2 = mProxyShapesComponents.mCollisionShapes[proxyShape2Index];
|
||||
|
||||
// No middle-phase is necessary, simply create a narrow phase info
|
||||
// for the narrow-phase collision detection
|
||||
narrowPhaseInput.addNarrowPhaseTest(overlappingPairs.mPairIds[i], proxyShape1Entity, proxyShape2Entity, collisionShape1, collisionShape2,
|
||||
mProxyShapesComponents.mLocalToWorldTransforms[proxyShape1Index],
|
||||
mProxyShapesComponents.mLocalToWorldTransforms[proxyShape2Index],
|
||||
algorithmType, mMemoryManager.getSingleFrameAllocator());
|
||||
NarrowPhaseAlgorithmType algorithmType = overlappingPairs.mNarrowPhaseAlgorithmType[i];
|
||||
|
||||
// No middle-phase is necessary, simply create a narrow phase info
|
||||
// for the narrow-phase collision detection
|
||||
narrowPhaseInput.addNarrowPhaseTest(overlappingPairs.mPairIds[i], i, proxyShape1Entity, proxyShape2Entity, collisionShape1, collisionShape2,
|
||||
mProxyShapesComponents.mLocalToWorldTransforms[proxyShape1Index],
|
||||
mProxyShapesComponents.mLocalToWorldTransforms[proxyShape2Index],
|
||||
algorithmType, mMemoryManager.getSingleFrameAllocator());
|
||||
}
|
||||
}
|
||||
|
||||
// For each possible convex vs concave pair of bodies
|
||||
uint64 convexVsConcaveStartIndex = overlappingPairs.getConvexVsConcavePairsStartIndex();
|
||||
const uint64 convexVsConcaveStartIndex = overlappingPairs.getConvexVsConcavePairsStartIndex();
|
||||
for (uint64 i=convexVsConcaveStartIndex; i < convexVsConcaveStartIndex + overlappingPairs.getNbConvexVsConcavePairs(); i++) {
|
||||
|
||||
const Entity proxyShape1Entity = overlappingPairs.mProxyShapes1[i];
|
||||
const Entity proxyShape2Entity = overlappingPairs.mProxyShapes2[i];
|
||||
|
||||
const uint proxyShape1Index = mProxyShapesComponents.getEntityIndex(proxyShape1Entity);
|
||||
const uint proxyShape2Index = mProxyShapesComponents.getEntityIndex(proxyShape2Entity);
|
||||
|
||||
assert(mProxyShapesComponents.mBroadPhaseId[proxyShape1Index] != -1);
|
||||
assert(mProxyShapesComponents.mBroadPhaseId[proxyShape2Index] != -1);
|
||||
assert(mProxyShapesComponents.mBroadPhaseId[proxyShape1Index] != mProxyShapesComponents.mBroadPhaseId[proxyShape2Index]);
|
||||
|
||||
const Entity body1Entity = mProxyShapesComponents.mBodiesEntities[proxyShape1Index];
|
||||
const Entity body2Entity = mProxyShapesComponents.mBodiesEntities[proxyShape2Index];
|
||||
|
||||
const bool isStaticRigidBody1 = mWorld->mRigidBodyComponents.hasComponent(body1Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body1Entity) == BodyType::STATIC;
|
||||
const bool isStaticRigidBody2 = mWorld->mRigidBodyComponents.hasComponent(body2Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body2Entity) == BodyType::STATIC;
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes1[i]) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes2[i]) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes1[i]) != mProxyShapesComponents.getBroadPhaseId(overlappingPairs.mProxyShapes2[i]));
|
||||
|
||||
// Check that at least one body is enabled (active and awake) and not static
|
||||
// TODO : Do not test this every frame
|
||||
bool isBody1Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body1Entity) && !isStaticRigidBody1;
|
||||
bool isBody2Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body2Entity) && !isStaticRigidBody2;
|
||||
if (!isBody1Active && !isBody2Active) continue;
|
||||
if (mOverlappingPairs.mIsActive[i]) {
|
||||
|
||||
// Check if the bodies are in the set of bodies that cannot collide between each other
|
||||
// TODO : Do not check this every frame but remove and do not create overlapping pairs of bodies in this situation
|
||||
bodypair bodiesIndex = OverlappingPairs::computeBodiesIndexPair(body1Entity, body2Entity);
|
||||
if (mNoCollisionPairs.contains(bodiesIndex) > 0) continue;
|
||||
|
||||
computeConvexVsConcaveMiddlePhase(overlappingPairs.mPairIds[i], proxyShape1Entity, proxyShape2Entity,
|
||||
mMemoryManager.getSingleFrameAllocator(), narrowPhaseInput);
|
||||
computeConvexVsConcaveMiddlePhase(i, mMemoryManager.getSingleFrameAllocator(), narrowPhaseInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,25 +287,6 @@ void CollisionDetectionSystem::computeMiddlePhaseCollisionSnapshot(List<uint64>&
|
|||
assert(mProxyShapesComponents.getBroadPhaseId(proxyShape2Entity) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(proxyShape1Entity) != mProxyShapesComponents.getBroadPhaseId(proxyShape2Entity));
|
||||
|
||||
const Entity body1Entity = mProxyShapesComponents.getBody(proxyShape1Entity);
|
||||
const Entity body2Entity = mProxyShapesComponents.getBody(proxyShape2Entity);
|
||||
|
||||
const bool isStaticRigidBody1 = mWorld->mRigidBodyComponents.hasComponent(body1Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body1Entity) == BodyType::STATIC;
|
||||
const bool isStaticRigidBody2 = mWorld->mRigidBodyComponents.hasComponent(body2Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body2Entity) == BodyType::STATIC;
|
||||
|
||||
// Check that at least one body is enabled (active and awake) and not static
|
||||
// TODO : Do not test this every frame
|
||||
bool isBody1Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body1Entity) && !isStaticRigidBody1;
|
||||
bool isBody2Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body2Entity) && !isStaticRigidBody2;
|
||||
if (!isBody1Active && !isBody2Active) continue;
|
||||
|
||||
// Check if the bodies are in the set of bodies that cannot collide between each other
|
||||
// TODO : Do not check this every frame but remove and do not create overlapping pairs of bodies in this situation
|
||||
bodypair bodiesIndex = OverlappingPairs::computeBodiesIndexPair(body1Entity, body2Entity);
|
||||
if (mNoCollisionPairs.contains(bodiesIndex) > 0) continue;
|
||||
|
||||
CollisionShape* collisionShape1 = mProxyShapesComponents.getCollisionShape(proxyShape1Entity);
|
||||
CollisionShape* collisionShape2 = mProxyShapesComponents.getCollisionShape(proxyShape2Entity);
|
||||
|
||||
|
@ -350,7 +294,7 @@ void CollisionDetectionSystem::computeMiddlePhaseCollisionSnapshot(List<uint64>&
|
|||
|
||||
// No middle-phase is necessary, simply create a narrow phase info
|
||||
// for the narrow-phase collision detection
|
||||
narrowPhaseInput.addNarrowPhaseTest(pairId, proxyShape1Entity, proxyShape2Entity, collisionShape1, collisionShape2,
|
||||
narrowPhaseInput.addNarrowPhaseTest(pairId, pairIndex, proxyShape1Entity, proxyShape2Entity, collisionShape1, collisionShape2,
|
||||
mProxyShapesComponents.getLocalToWorldTransform(proxyShape1Entity),
|
||||
mProxyShapesComponents.getLocalToWorldTransform(proxyShape2Entity),
|
||||
algorithmType, mMemoryManager.getSingleFrameAllocator());
|
||||
|
@ -361,78 +305,52 @@ void CollisionDetectionSystem::computeMiddlePhaseCollisionSnapshot(List<uint64>&
|
|||
for (uint p=0; p < concavePairs.size(); p++) {
|
||||
|
||||
const uint64 pairId = concavePairs[p];
|
||||
const uint64 pairIndex = mOverlappingPairs.mMapPairIdToPairIndex[pairId];
|
||||
|
||||
const uint pairIndex = mOverlappingPairs.mMapPairIdToPairIndex[pairId];
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(mOverlappingPairs.mProxyShapes1[pairIndex]) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(mOverlappingPairs.mProxyShapes2[pairIndex]) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(mOverlappingPairs.mProxyShapes1[pairIndex]) != mProxyShapesComponents.getBroadPhaseId(mOverlappingPairs.mProxyShapes2[pairIndex]));
|
||||
|
||||
const Entity proxyShape1Entity = mOverlappingPairs.mProxyShapes1[pairIndex];
|
||||
const Entity proxyShape2Entity = mOverlappingPairs.mProxyShapes2[pairIndex];
|
||||
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(proxyShape1Entity) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(proxyShape2Entity) != -1);
|
||||
assert(mProxyShapesComponents.getBroadPhaseId(proxyShape1Entity) != mProxyShapesComponents.getBroadPhaseId(proxyShape2Entity));
|
||||
|
||||
const Entity body1Entity = mProxyShapesComponents.getBody(proxyShape1Entity);
|
||||
const Entity body2Entity = mProxyShapesComponents.getBody(proxyShape2Entity);
|
||||
|
||||
const bool isStaticRigidBody1 = mWorld->mRigidBodyComponents.hasComponent(body1Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body1Entity) == BodyType::STATIC;
|
||||
const bool isStaticRigidBody2 = mWorld->mRigidBodyComponents.hasComponent(body2Entity) &&
|
||||
mWorld->mRigidBodyComponents.getBodyType(body2Entity) == BodyType::STATIC;
|
||||
|
||||
// Check that at least one body is enabled (active and awake) and not static
|
||||
// TODO : Do not test this every frame
|
||||
bool isBody1Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body1Entity) && !isStaticRigidBody1;
|
||||
bool isBody2Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body2Entity) && !isStaticRigidBody2;
|
||||
if (!isBody1Active && !isBody2Active) continue;
|
||||
|
||||
// Check if the bodies are in the set of bodies that cannot collide between each other
|
||||
// TODO : Do not check this every frame but remove and do not create overlapping pairs of bodies in this situation
|
||||
bodypair bodiesIndex = OverlappingPairs::computeBodiesIndexPair(body1Entity, body2Entity);
|
||||
if (mNoCollisionPairs.contains(bodiesIndex) > 0) continue;
|
||||
|
||||
computeConvexVsConcaveMiddlePhase(pairId, proxyShape1Entity, proxyShape2Entity,
|
||||
mMemoryManager.getSingleFrameAllocator(), narrowPhaseInput);
|
||||
computeConvexVsConcaveMiddlePhase(pairIndex, mMemoryManager.getSingleFrameAllocator(), narrowPhaseInput);
|
||||
}
|
||||
}
|
||||
// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
|
||||
void CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase(uint64 pairId, Entity proxyShape1, Entity proxyShape2,
|
||||
MemoryAllocator& allocator, NarrowPhaseInput& narrowPhaseInput) {
|
||||
void CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase(uint64 pairIndex, MemoryAllocator& allocator, NarrowPhaseInput& narrowPhaseInput) {
|
||||
|
||||
RP3D_PROFILE("CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase()", mProfiler);
|
||||
|
||||
ProxyShape* shape1 = mProxyShapesComponents.getProxyShape(proxyShape1);
|
||||
ProxyShape* shape2 = mProxyShapesComponents.getProxyShape(proxyShape2);
|
||||
const Entity proxyShape1 = mOverlappingPairs.mProxyShapes1[pairIndex];
|
||||
const Entity proxyShape2 = mOverlappingPairs.mProxyShapes2[pairIndex];
|
||||
|
||||
const uint proxyShape1Index = mProxyShapesComponents.getEntityIndex(proxyShape1);
|
||||
const uint proxyShape2Index = mProxyShapesComponents.getEntityIndex(proxyShape2);
|
||||
|
||||
ProxyShape* shape1 = mProxyShapesComponents.mProxyShapes[proxyShape1Index];
|
||||
ProxyShape* shape2 = mProxyShapesComponents.mProxyShapes[proxyShape2Index];
|
||||
|
||||
ProxyShape* convexProxyShape;
|
||||
ProxyShape* concaveProxyShape;
|
||||
ConvexShape* convexShape;
|
||||
ConcaveShape* concaveShape;
|
||||
|
||||
const bool isShape1Convex = shape1->getCollisionShape()->isConvex();
|
||||
const bool isShape1Convex = mOverlappingPairs.mIsShape1Convex[pairIndex];
|
||||
|
||||
// Collision shape 1 is convex, collision shape 2 is concave
|
||||
if (isShape1Convex) {
|
||||
convexProxyShape = shape1;
|
||||
convexShape = static_cast<ConvexShape*>(shape1->getCollisionShape());
|
||||
concaveProxyShape = shape2;
|
||||
concaveShape = static_cast<ConcaveShape*>(shape2->getCollisionShape());
|
||||
}
|
||||
else { // Collision shape 2 is convex, collision shape 1 is concave
|
||||
convexProxyShape = shape2;
|
||||
convexShape = static_cast<ConvexShape*>(shape2->getCollisionShape());
|
||||
concaveProxyShape = shape1;
|
||||
concaveShape = static_cast<ConcaveShape*>(shape1->getCollisionShape());
|
||||
}
|
||||
|
||||
// Select the narrow phase algorithm to use according to the two collision shapes
|
||||
NarrowPhaseAlgorithmType algorithmType = mCollisionDispatch.selectNarrowPhaseAlgorithm(convexShape->getType(),
|
||||
CollisionShapeType::CONVEX_POLYHEDRON);
|
||||
assert(mOverlappingPairs.mNarrowPhaseAlgorithmType[pairIndex] != NarrowPhaseAlgorithmType::None);
|
||||
|
||||
assert(algorithmType != NarrowPhaseAlgorithmType::None);
|
||||
Transform& shape1LocalToWorldTransform = mProxyShapesComponents.mLocalToWorldTransforms[proxyShape1Index];
|
||||
Transform& shape2LocalToWorldTransform = mProxyShapesComponents.mLocalToWorldTransforms[proxyShape2Index];
|
||||
|
||||
// Compute the convex shape AABB in the local-space of the convex shape
|
||||
const Transform convexToConcaveTransform = mProxyShapesComponents.getLocalToWorldTransform(concaveProxyShape->getEntity()).getInverse() *
|
||||
mProxyShapesComponents.getLocalToWorldTransform(convexProxyShape->getEntity());
|
||||
const Transform convexToConcaveTransform = (isShape1Convex ? shape2LocalToWorldTransform : shape1LocalToWorldTransform).getInverse() *
|
||||
(isShape1Convex ? shape1LocalToWorldTransform : shape2LocalToWorldTransform);
|
||||
AABB aabb;
|
||||
convexShape->computeAABB(aabb, convexToConcaveTransform);
|
||||
|
||||
|
@ -463,11 +381,10 @@ void CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase(uint64 pairId,
|
|||
#endif
|
||||
|
||||
// Create a narrow phase info for the narrow-phase collision detection
|
||||
narrowPhaseInput.addNarrowPhaseTest(pairId, proxyShape1, proxyShape2, isShape1Convex ? convexShape : triangleShape,
|
||||
narrowPhaseInput.addNarrowPhaseTest(mOverlappingPairs.mPairIds[pairIndex], pairIndex, proxyShape1, proxyShape2, isShape1Convex ? convexShape : triangleShape,
|
||||
isShape1Convex ? triangleShape : convexShape,
|
||||
mProxyShapesComponents.getLocalToWorldTransform(proxyShape1),
|
||||
mProxyShapesComponents.getLocalToWorldTransform(proxyShape2),
|
||||
algorithmType, allocator);
|
||||
shape1LocalToWorldTransform, shape2LocalToWorldTransform,
|
||||
mOverlappingPairs.mNarrowPhaseAlgorithmType[pairIndex], allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ class CollisionDetectionSystem {
|
|||
bool testNarrowPhaseCollision(NarrowPhaseInput& narrowPhaseInput, bool reportContacts, bool clipWithPreviousAxisIfStillColliding, MemoryAllocator& allocator);
|
||||
|
||||
/// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
|
||||
void computeConvexVsConcaveMiddlePhase(uint64 pairId, Entity proxyShape1, Entity proxyShape2, MemoryAllocator& allocator,
|
||||
void computeConvexVsConcaveMiddlePhase(uint64 pairIndex, MemoryAllocator& allocator,
|
||||
NarrowPhaseInput& narrowPhaseInput);
|
||||
|
||||
/// Swap the previous and current contacts lists
|
||||
|
@ -358,6 +358,7 @@ class CollisionDetectionSystem {
|
|||
|
||||
friend class DynamicsWorld;
|
||||
friend class ConvexMeshShape;
|
||||
friend class RigidBody;
|
||||
};
|
||||
|
||||
// Return a reference to the collision dispatch configuration
|
||||
|
|
Loading…
Reference in New Issue
Block a user