Fix issues in PhysicsWorld::createIslands() method and add more optimization in CollisionDetectionSystem::computeNarrowPhase() method
This commit is contained in:
parent
8fd5c58986
commit
b410b26e23
|
@ -113,6 +113,9 @@ class Components {
|
||||||
/// Return true if there is a component for a given entity
|
/// Return true if there is a component for a given entity
|
||||||
bool hasComponent(Entity entity) const;
|
bool hasComponent(Entity entity) const;
|
||||||
|
|
||||||
|
/// Return true if there is a component for a given entiy and if so set the entity index
|
||||||
|
bool hasComponentGetIndex(Entity entity, uint32& entityIndex) const;
|
||||||
|
|
||||||
/// Return the number of components
|
/// Return the number of components
|
||||||
uint32 getNbComponents() const;
|
uint32 getNbComponents() const;
|
||||||
|
|
||||||
|
@ -134,6 +137,19 @@ inline bool Components::hasComponent(Entity entity) const {
|
||||||
return mMapEntityToComponentIndex.containsKey(entity);
|
return mMapEntityToComponentIndex.containsKey(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if there is a component for a given entiy and if so set the entity index
|
||||||
|
inline bool Components::hasComponentGetIndex(Entity entity, uint32& entityIndex) const {
|
||||||
|
|
||||||
|
auto it = mMapEntityToComponentIndex.find(entity);
|
||||||
|
|
||||||
|
if (it != mMapEntityToComponentIndex.end()) {
|
||||||
|
entityIndex = it->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the number of components
|
// Return the number of components
|
||||||
inline uint32 Components::getNbComponents() const {
|
inline uint32 Components::getNbComponents() const {
|
||||||
return mNbComponents;
|
return mNbComponents;
|
||||||
|
|
|
@ -145,6 +145,9 @@ class RigidBodyComponents : public Components {
|
||||||
/// For each body, the list of joints entities the body is part of
|
/// For each body, the list of joints entities the body is part of
|
||||||
List<Entity>* mJoints;
|
List<Entity>* mJoints;
|
||||||
|
|
||||||
|
/// For each body, the list of the indices of contact pairs in which the body is involved
|
||||||
|
List<uint>* mContactPairs;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Allocate memory for a given number of components
|
/// Allocate memory for a given number of components
|
||||||
|
@ -342,6 +345,9 @@ class RigidBodyComponents : public Components {
|
||||||
/// Remove a joint from a body component
|
/// Remove a joint from a body component
|
||||||
void removeJointFromBody(Entity bodyEntity, Entity jointEntity);
|
void removeJointFromBody(Entity bodyEntity, Entity jointEntity);
|
||||||
|
|
||||||
|
/// A an associated contact pairs into the contact pairs array of the body
|
||||||
|
void addContacPair(Entity bodyEntity, uint contactPairIndex);
|
||||||
|
|
||||||
// -------------------- Friendship -------------------- //
|
// -------------------- Friendship -------------------- //
|
||||||
|
|
||||||
friend class PhysicsWorld;
|
friend class PhysicsWorld;
|
||||||
|
@ -769,6 +775,13 @@ inline void RigidBodyComponents::removeJointFromBody(Entity bodyEntity, Entity j
|
||||||
mJoints[mMapEntityToComponentIndex[bodyEntity]].remove(jointEntity);
|
mJoints[mMapEntityToComponentIndex[bodyEntity]].remove(jointEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A an associated contact pairs into the contact pairs array of the body
|
||||||
|
inline void RigidBodyComponents::addContacPair(Entity bodyEntity, uint contactPairIndex) {
|
||||||
|
|
||||||
|
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
|
||||||
|
mContactPairs[mMapEntityToComponentIndex[bodyEntity]].add(contactPairIndex);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -83,6 +83,9 @@ class CollisionDetectionSystem {
|
||||||
/// Reference the collider components
|
/// Reference the collider components
|
||||||
ColliderComponents& mCollidersComponents;
|
ColliderComponents& mCollidersComponents;
|
||||||
|
|
||||||
|
/// Reference to the rigid bodies components
|
||||||
|
RigidBodyComponents& mRigidBodyComponents;
|
||||||
|
|
||||||
/// Collision Detection Dispatch configuration
|
/// Collision Detection Dispatch configuration
|
||||||
CollisionDispatch mCollisionDispatch;
|
CollisionDispatch mCollisionDispatch;
|
||||||
|
|
||||||
|
@ -163,9 +166,6 @@ class CollisionDetectionSystem {
|
||||||
/// Pointer to the contact points of the current frame (either mContactPoints1 or mContactPoints2)
|
/// Pointer to the contact points of the current frame (either mContactPoints1 or mContactPoints2)
|
||||||
List<ContactPoint>* mCurrentContactPoints;
|
List<ContactPoint>* mCurrentContactPoints;
|
||||||
|
|
||||||
/// Map a body entity to the list of contact pairs in which it is involved
|
|
||||||
Map<Entity, List<uint>> mMapBodyToContactPairs;
|
|
||||||
|
|
||||||
#ifdef IS_RP3D_PROFILING_ENABLED
|
#ifdef IS_RP3D_PROFILING_ENABLED
|
||||||
|
|
||||||
/// Pointer to the profiler
|
/// Pointer to the profiler
|
||||||
|
@ -224,14 +224,12 @@ class CollisionDetectionSystem {
|
||||||
void processPotentialContacts(NarrowPhaseInfoBatch& narrowPhaseInfoBatch,
|
void processPotentialContacts(NarrowPhaseInfoBatch& narrowPhaseInfoBatch,
|
||||||
bool updateLastFrameInfo, List<ContactPointInfo>& potentialContactPoints,
|
bool updateLastFrameInfo, List<ContactPointInfo>& potentialContactPoints,
|
||||||
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
||||||
List<ContactManifoldInfo>& potentialContactManifolds, List<ContactPair>* contactPairs,
|
List<ContactManifoldInfo>& potentialContactManifolds, List<ContactPair>* contactPairs);
|
||||||
Map<Entity, List<uint>>& mapBodyToContactPairs);
|
|
||||||
|
|
||||||
/// Process the potential contacts after narrow-phase collision detection
|
/// Process the potential contacts after narrow-phase collision detection
|
||||||
void processAllPotentialContacts(NarrowPhaseInput& narrowPhaseInput, bool updateLastFrameInfo, List<ContactPointInfo>& potentialContactPoints,
|
void processAllPotentialContacts(NarrowPhaseInput& narrowPhaseInput, bool updateLastFrameInfo, List<ContactPointInfo>& potentialContactPoints,
|
||||||
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
||||||
List<ContactManifoldInfo>& potentialContactManifolds, List<ContactPair>* contactPairs,
|
List<ContactManifoldInfo>& potentialContactManifolds, List<ContactPair>* contactPairs);
|
||||||
Map<Entity, List<uint>>& mapBodyToContactPairs);
|
|
||||||
|
|
||||||
/// Reduce the potential contact manifolds and contact points of the overlapping pair contacts
|
/// Reduce the potential contact manifolds and contact points of the overlapping pair contacts
|
||||||
void reducePotentialContactManifolds(List<ContactPair>* contactPairs, List<ContactManifoldInfo>& potentialContactManifolds,
|
void reducePotentialContactManifolds(List<ContactPair>* contactPairs, List<ContactManifoldInfo>& potentialContactManifolds,
|
||||||
|
|
|
@ -43,7 +43,7 @@ RigidBodyComponents::RigidBodyComponents(MemoryAllocator& allocator)
|
||||||
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
|
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
|
||||||
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
|
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
|
||||||
sizeof(Quaternion) + sizeof(Vector3) + sizeof(Vector3) +
|
sizeof(Quaternion) + sizeof(Vector3) + sizeof(Vector3) +
|
||||||
sizeof(bool) + sizeof(bool) + sizeof(List<Entity>)) {
|
sizeof(bool) + sizeof(bool) + sizeof(List<Entity>) + sizeof(List<uint>)) {
|
||||||
|
|
||||||
// Allocate memory for the components data
|
// Allocate memory for the components data
|
||||||
allocate(INIT_NB_ALLOCATED_COMPONENTS);
|
allocate(INIT_NB_ALLOCATED_COMPONENTS);
|
||||||
|
@ -89,6 +89,7 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
|
||||||
bool* newIsGravityEnabled = reinterpret_cast<bool*>(newCentersOfMassWorld + nbComponentsToAllocate);
|
bool* newIsGravityEnabled = reinterpret_cast<bool*>(newCentersOfMassWorld + nbComponentsToAllocate);
|
||||||
bool* newIsAlreadyInIsland = reinterpret_cast<bool*>(newIsGravityEnabled + nbComponentsToAllocate);
|
bool* newIsAlreadyInIsland = reinterpret_cast<bool*>(newIsGravityEnabled + nbComponentsToAllocate);
|
||||||
List<Entity>* newJoints = reinterpret_cast<List<Entity>*>(newIsAlreadyInIsland + nbComponentsToAllocate);
|
List<Entity>* newJoints = reinterpret_cast<List<Entity>*>(newIsAlreadyInIsland + nbComponentsToAllocate);
|
||||||
|
List<uint>* newContactPairs = reinterpret_cast<List<uint>*>(newJoints + nbComponentsToAllocate);
|
||||||
|
|
||||||
// If there was already components before
|
// If there was already components before
|
||||||
if (mNbComponents > 0) {
|
if (mNbComponents > 0) {
|
||||||
|
@ -121,6 +122,7 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
|
||||||
memcpy(newIsGravityEnabled, mIsGravityEnabled, mNbComponents * sizeof(bool));
|
memcpy(newIsGravityEnabled, mIsGravityEnabled, mNbComponents * sizeof(bool));
|
||||||
memcpy(newIsAlreadyInIsland, mIsAlreadyInIsland, mNbComponents * sizeof(bool));
|
memcpy(newIsAlreadyInIsland, mIsAlreadyInIsland, mNbComponents * sizeof(bool));
|
||||||
memcpy(newJoints, mJoints, mNbComponents * sizeof(List<Entity>));
|
memcpy(newJoints, mJoints, mNbComponents * sizeof(List<Entity>));
|
||||||
|
memcpy(newContactPairs, mContactPairs, mNbComponents * sizeof(List<uint>));
|
||||||
|
|
||||||
// Deallocate previous memory
|
// Deallocate previous memory
|
||||||
mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize);
|
mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize);
|
||||||
|
@ -155,6 +157,7 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
|
||||||
mIsGravityEnabled = newIsGravityEnabled;
|
mIsGravityEnabled = newIsGravityEnabled;
|
||||||
mIsAlreadyInIsland = newIsAlreadyInIsland;
|
mIsAlreadyInIsland = newIsAlreadyInIsland;
|
||||||
mJoints = newJoints;
|
mJoints = newJoints;
|
||||||
|
mContactPairs = newContactPairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a component
|
// Add a component
|
||||||
|
@ -191,6 +194,7 @@ void RigidBodyComponents::addComponent(Entity bodyEntity, bool isSleeping, const
|
||||||
mIsGravityEnabled[index] = true;
|
mIsGravityEnabled[index] = true;
|
||||||
mIsAlreadyInIsland[index] = false;
|
mIsAlreadyInIsland[index] = false;
|
||||||
new (mJoints + index) List<Entity>(mMemoryAllocator);
|
new (mJoints + index) List<Entity>(mMemoryAllocator);
|
||||||
|
new (mContactPairs + index) List<uint>(mMemoryAllocator);
|
||||||
|
|
||||||
// Map the entity with the new component lookup index
|
// Map the entity with the new component lookup index
|
||||||
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(bodyEntity, index));
|
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(bodyEntity, index));
|
||||||
|
@ -235,6 +239,7 @@ void RigidBodyComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex
|
||||||
mIsGravityEnabled[destIndex] = mIsGravityEnabled[srcIndex];
|
mIsGravityEnabled[destIndex] = mIsGravityEnabled[srcIndex];
|
||||||
mIsAlreadyInIsland[destIndex] = mIsAlreadyInIsland[srcIndex];
|
mIsAlreadyInIsland[destIndex] = mIsAlreadyInIsland[srcIndex];
|
||||||
new (mJoints + destIndex) List<Entity>(mJoints[srcIndex]);
|
new (mJoints + destIndex) List<Entity>(mJoints[srcIndex]);
|
||||||
|
new (mContactPairs + destIndex) List<uint>(mContactPairs[srcIndex]);
|
||||||
|
|
||||||
// Destroy the source component
|
// Destroy the source component
|
||||||
destroyComponent(srcIndex);
|
destroyComponent(srcIndex);
|
||||||
|
@ -278,6 +283,7 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
|
||||||
bool isGravityEnabled1 = mIsGravityEnabled[index1];
|
bool isGravityEnabled1 = mIsGravityEnabled[index1];
|
||||||
bool isAlreadyInIsland1 = mIsAlreadyInIsland[index1];
|
bool isAlreadyInIsland1 = mIsAlreadyInIsland[index1];
|
||||||
List<Entity> joints1 = mJoints[index1];
|
List<Entity> joints1 = mJoints[index1];
|
||||||
|
List<uint> contactPairs1 = mContactPairs[index1];
|
||||||
|
|
||||||
// Destroy component 1
|
// Destroy component 1
|
||||||
destroyComponent(index1);
|
destroyComponent(index1);
|
||||||
|
@ -312,6 +318,7 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
|
||||||
mIsGravityEnabled[index2] = isGravityEnabled1;
|
mIsGravityEnabled[index2] = isGravityEnabled1;
|
||||||
mIsAlreadyInIsland[index2] = isAlreadyInIsland1;
|
mIsAlreadyInIsland[index2] = isAlreadyInIsland1;
|
||||||
new (mJoints + index2) List<Entity>(joints1);
|
new (mJoints + index2) List<Entity>(joints1);
|
||||||
|
new (mContactPairs + index2) List<uint>(contactPairs1);
|
||||||
|
|
||||||
// Update the entity to component index mapping
|
// Update the entity to component index mapping
|
||||||
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(entity1, index2));
|
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(entity1, index2));
|
||||||
|
@ -347,4 +354,5 @@ void RigidBodyComponents::destroyComponent(uint32 index) {
|
||||||
mCentersOfMassLocal[index].~Vector3();
|
mCentersOfMassLocal[index].~Vector3();
|
||||||
mCentersOfMassWorld[index].~Vector3();
|
mCentersOfMassWorld[index].~Vector3();
|
||||||
mJoints[index].~List<Entity>();
|
mJoints[index].~List<Entity>();
|
||||||
|
mContactPairs[index].~List<uint>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,9 +233,9 @@ void PhysicsWorld::setBodyDisabled(Entity bodyEntity, bool isDisabled) {
|
||||||
mCollisionBodyComponents.setIsEntityDisabled(bodyEntity, isDisabled);
|
mCollisionBodyComponents.setIsEntityDisabled(bodyEntity, isDisabled);
|
||||||
mTransformComponents.setIsEntityDisabled(bodyEntity, isDisabled);
|
mTransformComponents.setIsEntityDisabled(bodyEntity, isDisabled);
|
||||||
|
|
||||||
if (mRigidBodyComponents.hasComponent(bodyEntity)) {
|
assert(mRigidBodyComponents.hasComponent(bodyEntity));
|
||||||
|
|
||||||
mRigidBodyComponents.setIsEntityDisabled(bodyEntity, isDisabled);
|
mRigidBodyComponents.setIsEntityDisabled(bodyEntity, isDisabled);
|
||||||
}
|
|
||||||
|
|
||||||
// For each collider of the body
|
// For each collider of the body
|
||||||
const List<Entity>& collidersEntities = mCollisionBodyComponents.getColliders(bodyEntity);
|
const List<Entity>& collidersEntities = mCollisionBodyComponents.getColliders(bodyEntity);
|
||||||
|
@ -245,8 +245,6 @@ void PhysicsWorld::setBodyDisabled(Entity bodyEntity, bool isDisabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable the joints of the body if necessary
|
// Disable the joints of the body if necessary
|
||||||
if (mRigidBodyComponents.hasComponent(bodyEntity)) {
|
|
||||||
|
|
||||||
// For each joint of the body
|
// For each joint of the body
|
||||||
const List<Entity>& joints = mRigidBodyComponents.getJoints(bodyEntity);
|
const List<Entity>& joints = mRigidBodyComponents.getJoints(bodyEntity);
|
||||||
for(uint32 i=0; i < joints.size(); i++) {
|
for(uint32 i=0; i < joints.size(); i++) {
|
||||||
|
@ -255,8 +253,7 @@ void PhysicsWorld::setBodyDisabled(Entity bodyEntity, bool isDisabled) {
|
||||||
const Entity body2Entity = mJointsComponents.getBody2Entity(joints[i]);
|
const Entity body2Entity = mJointsComponents.getBody2Entity(joints[i]);
|
||||||
|
|
||||||
// If both bodies of the joint are disabled
|
// If both bodies of the joint are disabled
|
||||||
if (mRigidBodyComponents.getIsEntityDisabled(body1Entity) &&
|
if (mRigidBodyComponents.getIsEntityDisabled(body1Entity) && mRigidBodyComponents.getIsEntityDisabled(body2Entity)) {
|
||||||
mRigidBodyComponents.getIsEntityDisabled(body2Entity)) {
|
|
||||||
|
|
||||||
// We disable the joint
|
// We disable the joint
|
||||||
setJointDisabled(joints[i], true);
|
setJointDisabled(joints[i], true);
|
||||||
|
@ -267,7 +264,6 @@ void PhysicsWorld::setBodyDisabled(Entity bodyEntity, bool isDisabled) {
|
||||||
setJointDisabled(joints[i], false);
|
setJointDisabled(joints[i], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the world whether a joint is disabled or not
|
// Notify the world whether a joint is disabled or not
|
||||||
|
@ -760,10 +756,10 @@ void PhysicsWorld::createIslands() {
|
||||||
mIslands.reserveMemory();
|
mIslands.reserveMemory();
|
||||||
|
|
||||||
// Create a stack for the bodies to visit during the Depth First Search
|
// Create a stack for the bodies to visit during the Depth First Search
|
||||||
Stack<uint32> bodyEntityIndicesToVisit(mMemoryManager.getSingleFrameAllocator(), mIslands.getNbMaxBodiesInIslandPreviousFrame());
|
Stack<Entity> bodyEntitiesToVisit(mMemoryManager.getSingleFrameAllocator(), mIslands.getNbMaxBodiesInIslandPreviousFrame());
|
||||||
|
|
||||||
// List of static bodies added to the current island (used to reset the isAlreadyInIsland variable of static bodies)
|
// List of static bodies added to the current island (used to reset the isAlreadyInIsland variable of static bodies)
|
||||||
List<uint32> staticBodiesAddedToIsland(mMemoryManager.getSingleFrameAllocator());
|
List<Entity> staticBodiesAddedToIsland(mMemoryManager.getSingleFrameAllocator());
|
||||||
|
|
||||||
uint nbTotalManifolds = 0;
|
uint nbTotalManifolds = 0;
|
||||||
|
|
||||||
|
@ -777,59 +773,55 @@ void PhysicsWorld::createIslands() {
|
||||||
if (mRigidBodyComponents.mBodyTypes[b] == BodyType::STATIC) continue;
|
if (mRigidBodyComponents.mBodyTypes[b] == BodyType::STATIC) continue;
|
||||||
|
|
||||||
// Reset the stack of bodies to visit
|
// Reset the stack of bodies to visit
|
||||||
bodyEntityIndicesToVisit.clear();
|
bodyEntitiesToVisit.clear();
|
||||||
|
|
||||||
// Add the body into the stack of bodies to visit
|
// Add the body into the stack of bodies to visit
|
||||||
mRigidBodyComponents.mIsAlreadyInIsland[b] = true;
|
mRigidBodyComponents.mIsAlreadyInIsland[b] = true;
|
||||||
bodyEntityIndicesToVisit.push(b);
|
bodyEntitiesToVisit.push(mRigidBodyComponents.mBodiesEntities[b]);
|
||||||
|
|
||||||
// Create the new island
|
// Create the new island
|
||||||
uint32 islandIndex = mIslands.addIsland(nbTotalManifolds);
|
uint32 islandIndex = mIslands.addIsland(nbTotalManifolds);
|
||||||
|
|
||||||
// While there are still some bodies to visit in the stack
|
// While there are still some bodies to visit in the stack
|
||||||
while (bodyEntityIndicesToVisit.size() > 0) {
|
while (bodyEntitiesToVisit.size() > 0) {
|
||||||
|
|
||||||
// Get the next body to visit from the stack
|
|
||||||
const uint32 bodyToVisitIndex = bodyEntityIndicesToVisit.pop();
|
|
||||||
|
|
||||||
// Get the body entity
|
// Get the body entity
|
||||||
const Entity bodyToVisitEntity = mRigidBodyComponents.mBodiesEntities[bodyToVisitIndex];
|
const Entity bodyToVisitEntity = bodyEntitiesToVisit.pop();
|
||||||
|
|
||||||
// Add the body into the island
|
// Add the body into the island
|
||||||
mIslands.addBodyToIsland(bodyToVisitEntity);
|
mIslands.addBodyToIsland(bodyToVisitEntity);
|
||||||
|
|
||||||
RigidBody* rigidBodyToVisit = mRigidBodyComponents.mRigidBodies[bodyToVisitIndex];
|
RigidBody* rigidBodyToVisit = mRigidBodyComponents.getRigidBody(bodyToVisitEntity);
|
||||||
|
|
||||||
// Awake the body if it is sleeping (note that this called might change the body index in the mRigidBodyComponents array)
|
// Awake the body if it is sleeping (note that this called might change the body index in the mRigidBodyComponents array)
|
||||||
rigidBodyToVisit->setIsSleeping(false);
|
rigidBodyToVisit->setIsSleeping(false);
|
||||||
|
|
||||||
// If the current body is static, we do not want to perform the DFS search across that body
|
// Compute the body index in the array (Note that it could have changed because of the previous call to rigidBodyToVisit->setIsSleeping(false))
|
||||||
if (rigidBodyToVisit->getType() == BodyType::STATIC) {
|
const uint32 bodyToVisitIndex = mRigidBodyComponents.getEntityIndex(bodyToVisitEntity);
|
||||||
|
|
||||||
// Get the new body index in the mRigidBodyComponents (this index might have changed due to the call to rigidBodyToVisite->setIsSleeping(false))
|
// If the currenbodyEntityIndicesToVisitt body is static, we do not want to perform the DFS search across that body
|
||||||
const uint32 newBodyIndex = mRigidBodyComponents.getEntityIndex(bodyToVisitEntity);
|
if (mRigidBodyComponents.mBodyTypes[bodyToVisitIndex] == BodyType::STATIC) {
|
||||||
|
|
||||||
staticBodiesAddedToIsland.add(newBodyIndex);
|
staticBodiesAddedToIsland.add(bodyToVisitEntity);
|
||||||
|
|
||||||
// Go to the next body
|
// Go to the next body
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the body is involved in contacts with other bodies
|
// If the body is involved in contacts with other bodies
|
||||||
auto itBodyContactPairs = mCollisionDetection.mMapBodyToContactPairs.find(bodyToVisitEntity);
|
|
||||||
if (itBodyContactPairs != mCollisionDetection.mMapBodyToContactPairs.end()) {
|
|
||||||
|
|
||||||
// For each contact pair in which the current body is involded
|
// For each contact pair in which the current body is involded
|
||||||
List<uint>& contactPairs = itBodyContactPairs->second;
|
for (uint p=0; p < mRigidBodyComponents.mContactPairs[bodyToVisitIndex].size(); p++) {
|
||||||
for (uint p=0; p < contactPairs.size(); p++) {
|
|
||||||
|
|
||||||
ContactPair& pair = (*mCollisionDetection.mCurrentContactPairs)[contactPairs[p]];
|
ContactPair& pair = (*mCollisionDetection.mCurrentContactPairs)[mRigidBodyComponents.mContactPairs[bodyToVisitIndex][p]];
|
||||||
|
|
||||||
// Check if the current contact pair has already been added into an island
|
// Check if the current contact pair has already been added into an island
|
||||||
if (pair.isAlreadyInIsland) continue;
|
if (pair.isAlreadyInIsland) continue;
|
||||||
|
|
||||||
|
const Entity otherBodyEntity = pair.body1Entity == bodyToVisitEntity ? pair.body2Entity : pair.body1Entity;
|
||||||
|
|
||||||
// If the colliding body is a RigidBody (and not a CollisionBody) and is not a trigger
|
// If the colliding body is a RigidBody (and not a CollisionBody) and is not a trigger
|
||||||
if (mRigidBodyComponents.hasComponent(pair.body1Entity) && mRigidBodyComponents.hasComponent(pair.body2Entity)
|
uint32 otherBodyIndex;
|
||||||
|
if (mRigidBodyComponents.hasComponentGetIndex(otherBodyEntity, otherBodyIndex)
|
||||||
&& !mCollidersComponents.getIsTrigger(pair.collider1Entity) && !mCollidersComponents.getIsTrigger(pair.collider2Entity)) {
|
&& !mCollidersComponents.getIsTrigger(pair.collider1Entity) && !mCollidersComponents.getIsTrigger(pair.collider2Entity)) {
|
||||||
|
|
||||||
assert(pair.potentialContactManifoldsIndices.size() > 0);
|
assert(pair.potentialContactManifoldsIndices.size() > 0);
|
||||||
|
@ -839,14 +831,11 @@ void PhysicsWorld::createIslands() {
|
||||||
mIslands.nbContactManifolds[islandIndex] += pair.potentialContactManifoldsIndices.size();
|
mIslands.nbContactManifolds[islandIndex] += pair.potentialContactManifoldsIndices.size();
|
||||||
pair.isAlreadyInIsland = true;
|
pair.isAlreadyInIsland = true;
|
||||||
|
|
||||||
const Entity otherBodyEntity = pair.body1Entity == bodyToVisitEntity ? pair.body2Entity : pair.body1Entity;
|
|
||||||
const uint32 otherBodyIndex = mRigidBodyComponents.getEntityIndex(otherBodyEntity);
|
|
||||||
|
|
||||||
// Check if the other body has already been added to the island
|
// Check if the other body has already been added to the island
|
||||||
if (mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex]) continue;
|
if (mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex]) continue;
|
||||||
|
|
||||||
// Insert the other body into the stack of bodies to visit
|
// Insert the other body into the stack of bodies to visit
|
||||||
bodyEntityIndicesToVisit.push(otherBodyIndex);
|
bodyEntitiesToVisit.push(otherBodyEntity);
|
||||||
mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex] = true;
|
mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex] = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -855,7 +844,6 @@ void PhysicsWorld::createIslands() {
|
||||||
pair.isAlreadyInIsland = true;
|
pair.isAlreadyInIsland = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// For each joint in which the current body is involved
|
// For each joint in which the current body is involved
|
||||||
const List<Entity>& joints = mRigidBodyComponents.getJoints(rigidBodyToVisit->getEntity());
|
const List<Entity>& joints = mRigidBodyComponents.getJoints(rigidBodyToVisit->getEntity());
|
||||||
|
@ -877,7 +865,7 @@ void PhysicsWorld::createIslands() {
|
||||||
if (mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex]) continue;
|
if (mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex]) continue;
|
||||||
|
|
||||||
// Insert the other body into the stack of bodies to visit
|
// Insert the other body into the stack of bodies to visit
|
||||||
bodyEntityIndicesToVisit.push(otherBodyIndex);
|
bodyEntitiesToVisit.push(otherBodyEntity);
|
||||||
mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex] = true;
|
mRigidBodyComponents.mIsAlreadyInIsland[otherBodyIndex] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -886,14 +874,17 @@ void PhysicsWorld::createIslands() {
|
||||||
// can also be included in the other islands
|
// can also be included in the other islands
|
||||||
for (uint j=0; j < staticBodiesAddedToIsland.size(); j++) {
|
for (uint j=0; j < staticBodiesAddedToIsland.size(); j++) {
|
||||||
|
|
||||||
assert(mRigidBodyComponents.mBodyTypes[staticBodiesAddedToIsland[j]] == BodyType::STATIC);
|
assert(mRigidBodyComponents.getBodyType(staticBodiesAddedToIsland[j]) == BodyType::STATIC);
|
||||||
mRigidBodyComponents.mIsAlreadyInIsland[staticBodiesAddedToIsland[j]] = false;
|
mRigidBodyComponents.setIsAlreadyInIsland(staticBodiesAddedToIsland[j], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
staticBodiesAddedToIsland.clear();
|
staticBodiesAddedToIsland.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mCollisionDetection.mMapBodyToContactPairs.clear(true);
|
// Clear the associated contacts pairs of rigid bodies
|
||||||
|
for (uint b=0; b < mRigidBodyComponents.getNbEnabledComponents(); b++) {
|
||||||
|
mRigidBodyComponents.mContactPairs[b].clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put bodies to sleep if needed.
|
// Put bodies to sleep if needed.
|
||||||
|
|
|
@ -50,8 +50,9 @@ using namespace std;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CollisionDetectionSystem::CollisionDetectionSystem(PhysicsWorld* world, ColliderComponents& collidersComponents, TransformComponents& transformComponents,
|
CollisionDetectionSystem::CollisionDetectionSystem(PhysicsWorld* world, ColliderComponents& collidersComponents, TransformComponents& transformComponents,
|
||||||
CollisionBodyComponents& collisionBodyComponents, RigidBodyComponents& rigidBodyComponents, MemoryManager& memoryManager)
|
CollisionBodyComponents& collisionBodyComponents, RigidBodyComponents& rigidBodyComponents,
|
||||||
: mMemoryManager(memoryManager), mCollidersComponents(collidersComponents),
|
MemoryManager& memoryManager)
|
||||||
|
: mMemoryManager(memoryManager), mCollidersComponents(collidersComponents), mRigidBodyComponents(rigidBodyComponents),
|
||||||
mCollisionDispatch(mMemoryManager.getPoolAllocator()), mWorld(world),
|
mCollisionDispatch(mMemoryManager.getPoolAllocator()), mWorld(world),
|
||||||
mNoCollisionPairs(mMemoryManager.getPoolAllocator()),
|
mNoCollisionPairs(mMemoryManager.getPoolAllocator()),
|
||||||
mOverlappingPairs(mMemoryManager.getPoolAllocator(), mMemoryManager.getSingleFrameAllocator(), mCollidersComponents,
|
mOverlappingPairs(mMemoryManager.getPoolAllocator(), mMemoryManager.getSingleFrameAllocator(), mCollidersComponents,
|
||||||
|
@ -67,7 +68,7 @@ CollisionDetectionSystem::CollisionDetectionSystem(PhysicsWorld* world, Collider
|
||||||
mContactManifolds2(mMemoryManager.getPoolAllocator()), mPreviousContactManifolds(&mContactManifolds1), mCurrentContactManifolds(&mContactManifolds2),
|
mContactManifolds2(mMemoryManager.getPoolAllocator()), mPreviousContactManifolds(&mContactManifolds1), mCurrentContactManifolds(&mContactManifolds2),
|
||||||
mContactPoints1(mMemoryManager.getPoolAllocator()),
|
mContactPoints1(mMemoryManager.getPoolAllocator()),
|
||||||
mContactPoints2(mMemoryManager.getPoolAllocator()), mPreviousContactPoints(&mContactPoints1),
|
mContactPoints2(mMemoryManager.getPoolAllocator()), mPreviousContactPoints(&mContactPoints1),
|
||||||
mCurrentContactPoints(&mContactPoints2), mMapBodyToContactPairs(mMemoryManager.getSingleFrameAllocator()) {
|
mCurrentContactPoints(&mContactPoints2) {
|
||||||
|
|
||||||
#ifdef IS_RP3D_PROFILING_ENABLED
|
#ifdef IS_RP3D_PROFILING_ENABLED
|
||||||
|
|
||||||
|
@ -481,8 +482,7 @@ void CollisionDetectionSystem::processAllPotentialContacts(NarrowPhaseInput& nar
|
||||||
List<ContactPointInfo>& potentialContactPoints,
|
List<ContactPointInfo>& potentialContactPoints,
|
||||||
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
||||||
List<ContactManifoldInfo>& potentialContactManifolds,
|
List<ContactManifoldInfo>& potentialContactManifolds,
|
||||||
List<ContactPair>* contactPairs,
|
List<ContactPair>* contactPairs) {
|
||||||
Map<Entity, List<uint>>& mapBodyToContactPairs) {
|
|
||||||
|
|
||||||
assert(contactPairs->size() == 0);
|
assert(contactPairs->size() == 0);
|
||||||
assert(mapPairIdToContactPairIndex->size() == 0);
|
assert(mapPairIdToContactPairIndex->size() == 0);
|
||||||
|
@ -497,17 +497,17 @@ void CollisionDetectionSystem::processAllPotentialContacts(NarrowPhaseInput& nar
|
||||||
|
|
||||||
// Process the potential contacts
|
// Process the potential contacts
|
||||||
processPotentialContacts(sphereVsSphereBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
processPotentialContacts(sphereVsSphereBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
||||||
potentialContactManifolds, contactPairs, mapBodyToContactPairs);
|
potentialContactManifolds, contactPairs);
|
||||||
processPotentialContacts(sphereVsCapsuleBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
processPotentialContacts(sphereVsCapsuleBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
||||||
potentialContactManifolds, contactPairs, mapBodyToContactPairs);
|
potentialContactManifolds, contactPairs);
|
||||||
processPotentialContacts(capsuleVsCapsuleBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
processPotentialContacts(capsuleVsCapsuleBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
||||||
potentialContactManifolds, contactPairs, mapBodyToContactPairs);
|
potentialContactManifolds, contactPairs);
|
||||||
processPotentialContacts(sphereVsConvexPolyhedronBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
processPotentialContacts(sphereVsConvexPolyhedronBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
||||||
potentialContactManifolds, contactPairs, mapBodyToContactPairs);
|
potentialContactManifolds, contactPairs);
|
||||||
processPotentialContacts(capsuleVsConvexPolyhedronBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
processPotentialContacts(capsuleVsConvexPolyhedronBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
||||||
potentialContactManifolds, contactPairs, mapBodyToContactPairs);
|
potentialContactManifolds, contactPairs);
|
||||||
processPotentialContacts(convexPolyhedronVsConvexPolyhedronBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
processPotentialContacts(convexPolyhedronVsConvexPolyhedronBatch, updateLastFrameInfo, potentialContactPoints, mapPairIdToContactPairIndex,
|
||||||
potentialContactManifolds, contactPairs, mapBodyToContactPairs);
|
potentialContactManifolds, contactPairs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the narrow-phase collision detection
|
// Compute the narrow-phase collision detection
|
||||||
|
@ -528,7 +528,7 @@ void CollisionDetectionSystem::computeNarrowPhase() {
|
||||||
|
|
||||||
// Process all the potential contacts after narrow-phase collision
|
// Process all the potential contacts after narrow-phase collision
|
||||||
processAllPotentialContacts(mNarrowPhaseInput, true, mPotentialContactPoints, mCurrentMapPairIdToContactPairIndex,
|
processAllPotentialContacts(mNarrowPhaseInput, true, mPotentialContactPoints, mCurrentMapPairIdToContactPairIndex,
|
||||||
mPotentialContactManifolds, mCurrentContactPairs, mMapBodyToContactPairs);
|
mPotentialContactManifolds, mCurrentContactPairs);
|
||||||
|
|
||||||
// Reduce the number of contact points in the manifolds
|
// Reduce the number of contact points in the manifolds
|
||||||
reducePotentialContactManifolds(mCurrentContactPairs, mPotentialContactManifolds, mPotentialContactPoints);
|
reducePotentialContactManifolds(mCurrentContactPairs, mPotentialContactManifolds, mPotentialContactPoints);
|
||||||
|
@ -662,18 +662,15 @@ bool CollisionDetectionSystem::computeNarrowPhaseCollisionSnapshot(NarrowPhaseIn
|
||||||
List<ContactPair> lostContactPairs(allocator); // Not used during collision snapshots
|
List<ContactPair> lostContactPairs(allocator); // Not used during collision snapshots
|
||||||
List<ContactManifold> contactManifolds(allocator);
|
List<ContactManifold> contactManifolds(allocator);
|
||||||
List<ContactPoint> contactPoints(allocator);
|
List<ContactPoint> contactPoints(allocator);
|
||||||
Map<Entity, List<uint>> mapBodyToContactPairs(allocator);
|
|
||||||
|
|
||||||
// Process all the potential contacts after narrow-phase collision
|
// Process all the potential contacts after narrow-phase collision
|
||||||
processAllPotentialContacts(narrowPhaseInput, true, potentialContactPoints, &mapPairIdToContactPairIndex, potentialContactManifolds,
|
processAllPotentialContacts(narrowPhaseInput, true, potentialContactPoints, &mapPairIdToContactPairIndex, potentialContactManifolds, &contactPairs);
|
||||||
&contactPairs, mapBodyToContactPairs);
|
|
||||||
|
|
||||||
// Reduce the number of contact points in the manifolds
|
// Reduce the number of contact points in the manifolds
|
||||||
reducePotentialContactManifolds(&contactPairs, potentialContactManifolds, potentialContactPoints);
|
reducePotentialContactManifolds(&contactPairs, potentialContactManifolds, potentialContactPoints);
|
||||||
|
|
||||||
// Create the actual contact manifolds and contact points
|
// Create the actual contact manifolds and contact points
|
||||||
createSnapshotContacts(contactPairs, contactManifolds, contactPoints, potentialContactManifolds,
|
createSnapshotContacts(contactPairs, contactManifolds, contactPoints, potentialContactManifolds, potentialContactPoints);
|
||||||
potentialContactPoints);
|
|
||||||
|
|
||||||
// Report the contacts to the user
|
// Report the contacts to the user
|
||||||
reportContacts(callback, &contactPairs, &contactManifolds, &contactPoints, lostContactPairs);
|
reportContacts(callback, &contactPairs, &contactManifolds, &contactPoints, lostContactPairs);
|
||||||
|
@ -728,6 +725,14 @@ void CollisionDetectionSystem::createContacts() {
|
||||||
contactPair.nbContactManifolds = contactPair.potentialContactManifoldsIndices.size();
|
contactPair.nbContactManifolds = contactPair.potentialContactManifoldsIndices.size();
|
||||||
contactPair.contactPointsIndex = mCurrentContactPoints->size();
|
contactPair.contactPointsIndex = mCurrentContactPoints->size();
|
||||||
|
|
||||||
|
// Add the associated contact pair to both bodies of the pair (used to create islands later)
|
||||||
|
if (mRigidBodyComponents.hasComponent(contactPair.body1Entity)) {
|
||||||
|
mRigidBodyComponents.addContacPair(contactPair.body1Entity, p);
|
||||||
|
}
|
||||||
|
if (mRigidBodyComponents.hasComponent(contactPair.body2Entity)) {
|
||||||
|
mRigidBodyComponents.addContacPair(contactPair.body2Entity, p);
|
||||||
|
}
|
||||||
|
|
||||||
// For each potential contact manifold of the pair
|
// For each potential contact manifold of the pair
|
||||||
for (uint m=0; m < contactPair.potentialContactManifoldsIndices.size(); m++) {
|
for (uint m=0; m < contactPair.potentialContactManifoldsIndices.size(); m++) {
|
||||||
|
|
||||||
|
@ -985,8 +990,7 @@ void CollisionDetectionSystem::processPotentialContacts(NarrowPhaseInfoBatch& na
|
||||||
List<ContactPointInfo>& potentialContactPoints,
|
List<ContactPointInfo>& potentialContactPoints,
|
||||||
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
Map<uint64, uint>* mapPairIdToContactPairIndex,
|
||||||
List<ContactManifoldInfo>& potentialContactManifolds,
|
List<ContactManifoldInfo>& potentialContactManifolds,
|
||||||
List<ContactPair>* contactPairs,
|
List<ContactPair>* contactPairs) {
|
||||||
Map<Entity, List<uint>>& mapBodyToContactPairs) {
|
|
||||||
|
|
||||||
RP3D_PROFILE("CollisionDetectionSystem::processPotentialContacts()", mProfiler);
|
RP3D_PROFILE("CollisionDetectionSystem::processPotentialContacts()", mProfiler);
|
||||||
|
|
||||||
|
@ -1035,25 +1039,6 @@ void CollisionDetectionSystem::processPotentialContacts(NarrowPhaseInfoBatch& na
|
||||||
contactPairs->add(overlappingPairContact);
|
contactPairs->add(overlappingPairContact);
|
||||||
pairContact = &((*contactPairs)[newContactPairIndex]);
|
pairContact = &((*contactPairs)[newContactPairIndex]);
|
||||||
mapPairIdToContactPairIndex->add(Pair<uint64, uint>(pairId, newContactPairIndex));
|
mapPairIdToContactPairIndex->add(Pair<uint64, uint>(pairId, newContactPairIndex));
|
||||||
|
|
||||||
auto itbodyContactPairs = mapBodyToContactPairs.find(body1Entity);
|
|
||||||
if (itbodyContactPairs != mapBodyToContactPairs.end()) {
|
|
||||||
itbodyContactPairs->second.add(newContactPairIndex);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<uint> contactPairs(mMemoryManager.getPoolAllocator(), 1);
|
|
||||||
contactPairs.add(newContactPairIndex);
|
|
||||||
mapBodyToContactPairs.add(Pair<Entity, List<uint>>(body1Entity, contactPairs));
|
|
||||||
}
|
|
||||||
itbodyContactPairs = mapBodyToContactPairs.find(body2Entity);
|
|
||||||
if (itbodyContactPairs != mapBodyToContactPairs.end()) {
|
|
||||||
itbodyContactPairs->second.add(newContactPairIndex);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<uint> contactPairs(mMemoryManager.getPoolAllocator(), 1);
|
|
||||||
contactPairs.add(newContactPairIndex);
|
|
||||||
mapBodyToContactPairs.add(Pair<Entity, List<uint>>(body2Entity, contactPairs));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else { // If a ContactPair already exists for this overlapping pair, we use this one
|
else { // If a ContactPair already exists for this overlapping pair, we use this one
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user