Remove the PairManager class
This commit is contained in:
parent
5f7af61593
commit
5d2cf593b5
@ -1,289 +0,0 @@
|
|||||||
/********************************************************************************
|
|
||||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
|
||||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
|
||||||
*********************************************************************************
|
|
||||||
* *
|
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
|
||||||
* In no event will the authors be held liable for any damages arising from the *
|
|
||||||
* use of this software. *
|
|
||||||
* *
|
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
|
||||||
* freely, subject to the following restrictions: *
|
|
||||||
* *
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
|
||||||
* that you wrote the original software. If you use this software in a *
|
|
||||||
* product, an acknowledgment in the product documentation would be *
|
|
||||||
* appreciated but is not required. *
|
|
||||||
* *
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
|
||||||
* misrepresented as being the original software. *
|
|
||||||
* *
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
|
||||||
* *
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
// Libraries
|
|
||||||
#include "PairManager.h"
|
|
||||||
#include "../CollisionDetection.h"
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using namespace reactphysics3d;
|
|
||||||
|
|
||||||
// Initialization of static variables
|
|
||||||
bodyindex PairManager::INVALID_INDEX = std::numeric_limits<reactphysics3d::bodyindex>::max();
|
|
||||||
|
|
||||||
// Constructor of PairManager
|
|
||||||
PairManager::PairManager(CollisionDetection& collisionDetection)
|
|
||||||
: mCollisionDetection(collisionDetection) {
|
|
||||||
mHashTable = NULL;
|
|
||||||
mOverlappingPairs = NULL;
|
|
||||||
mOffsetNextPair = NULL;
|
|
||||||
mNbOverlappingPairs = 0;
|
|
||||||
mHashMask = 0;
|
|
||||||
mNbElementsHashTable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destructor of PairManager
|
|
||||||
PairManager::~PairManager() {
|
|
||||||
|
|
||||||
// Release the allocated memory
|
|
||||||
free(mOffsetNextPair);
|
|
||||||
free(mOverlappingPairs);
|
|
||||||
free(mHashTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a pair of bodies in the pair manager and returns a pointer to that pair.
|
|
||||||
/// If the pair to add does not already exist in the set of
|
|
||||||
/// overlapping pairs, it will be created and if it already exists, we only
|
|
||||||
/// return a pointer to that pair.
|
|
||||||
BodyPair* PairManager::addPair(CollisionBody* body1, CollisionBody* body2) {
|
|
||||||
|
|
||||||
// Sort the bodies to have the body with smallest ID first
|
|
||||||
sortBodiesUsingID(body1, body2);
|
|
||||||
|
|
||||||
// Get the bodies IDs
|
|
||||||
bodyindex id1 = body1->getID();
|
|
||||||
bodyindex id2 = body2->getID();
|
|
||||||
|
|
||||||
// Compute the hash value of the two bodies
|
|
||||||
uint hashValue = computeHashBodies(id1, id2) & mHashMask;
|
|
||||||
|
|
||||||
// Try to find the pair in the current overlapping pairs.
|
|
||||||
BodyPair* pair = findPairWithHashValue(id1, id2, hashValue);
|
|
||||||
|
|
||||||
// If the pair is already in the set of overlapping pairs
|
|
||||||
if (pair) {
|
|
||||||
// We only return a pointer to that pair
|
|
||||||
return pair;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we need to allocate more pairs in the set of overlapping pairs
|
|
||||||
if (mNbOverlappingPairs >= mNbElementsHashTable) {
|
|
||||||
// Increase the size of the hash table (always a power of two)
|
|
||||||
mNbElementsHashTable = computeNextPowerOfTwo(mNbOverlappingPairs + 1);
|
|
||||||
|
|
||||||
// Compute the new hash mask with the new hash size
|
|
||||||
mHashMask = mNbElementsHashTable - 1;
|
|
||||||
|
|
||||||
// Reallocate more pairs
|
|
||||||
reallocatePairs();
|
|
||||||
|
|
||||||
// Compute the new hash value (using the new hash size and hash mask)
|
|
||||||
hashValue = computeHashBodies(id1, id2) & mHashMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the new overlapping pair
|
|
||||||
BodyPair* newPair = &mOverlappingPairs[mNbOverlappingPairs];
|
|
||||||
newPair->body1 = body1;
|
|
||||||
newPair->body2 = body2;
|
|
||||||
|
|
||||||
// Put the new pair as the initial pair with this hash value
|
|
||||||
mOffsetNextPair[mNbOverlappingPairs] = mHashTable[hashValue];
|
|
||||||
mHashTable[hashValue] = mNbOverlappingPairs++;
|
|
||||||
|
|
||||||
// Notify the collision detection about this new overlapping pair
|
|
||||||
mCollisionDetection.broadPhaseNotifyOverlappingPair(newPair);
|
|
||||||
|
|
||||||
// Return a pointer to the new created pair
|
|
||||||
return newPair;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a pair of bodies from the pair manager.
|
|
||||||
/// This method returns true if the pair has been found and removed.
|
|
||||||
bool PairManager::removePair(bodyindex id1, bodyindex id2) {
|
|
||||||
|
|
||||||
// Sort the bodies IDs
|
|
||||||
sortIDs(id1, id2);
|
|
||||||
|
|
||||||
// Compute the hash value of the pair to remove
|
|
||||||
const uint hashValue = computeHashBodies(id1, id2) & mHashMask;
|
|
||||||
|
|
||||||
// Find the pair to remove
|
|
||||||
BodyPair* pair = findPairWithHashValue(id1, id2, hashValue);
|
|
||||||
|
|
||||||
// If we have not found the pair
|
|
||||||
if (pair == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(pair->body1->getID() == id1);
|
|
||||||
assert(pair->body2->getID() == id2);
|
|
||||||
|
|
||||||
// Notify the collision detection about this removed overlapping pair
|
|
||||||
mCollisionDetection.broadPhaseNotifyRemovedOverlappingPair(pair);
|
|
||||||
|
|
||||||
// Remove the pair from the set of overlapping pairs
|
|
||||||
removePairWithHashValue(id1, id2, hashValue, computePairOffset(pair));
|
|
||||||
|
|
||||||
// Try to shrink the memory used by the pair manager
|
|
||||||
shrinkMemory();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal method to remove a pair from the set of overlapping pair
|
|
||||||
void PairManager::removePairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue,
|
|
||||||
bodyindex indexPair) {
|
|
||||||
|
|
||||||
// Get the initial offset of the pairs with
|
|
||||||
// the corresponding hash value
|
|
||||||
bodyindex offset = mHashTable[hashValue];
|
|
||||||
assert(offset != INVALID_INDEX);
|
|
||||||
|
|
||||||
// Look for the pair in the set of overlapping pairs
|
|
||||||
bodyindex previousPair = INVALID_INDEX;
|
|
||||||
while(offset != indexPair) {
|
|
||||||
previousPair = offset;
|
|
||||||
offset = mOffsetNextPair[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the pair was the first one with this hash
|
|
||||||
// value in the hash table
|
|
||||||
if (previousPair == INVALID_INDEX) {
|
|
||||||
// Replace the pair to remove in the
|
|
||||||
// hash table by the next one
|
|
||||||
mHashTable[hashValue] = mOffsetNextPair[indexPair];
|
|
||||||
}
|
|
||||||
else { // If the pair was not the first one
|
|
||||||
// Replace the pair to remove in the
|
|
||||||
// hash table by the next one
|
|
||||||
assert(mOffsetNextPair[previousPair] == indexPair);
|
|
||||||
mOffsetNextPair[previousPair] = mOffsetNextPair[indexPair];
|
|
||||||
}
|
|
||||||
|
|
||||||
const bodyindex indexLastPair = mNbOverlappingPairs - 1;
|
|
||||||
|
|
||||||
// If the pair to remove is the last one in the list
|
|
||||||
if (indexPair == indexLastPair) {
|
|
||||||
|
|
||||||
// We simply decrease the number of overlapping pairs
|
|
||||||
mNbOverlappingPairs--;
|
|
||||||
}
|
|
||||||
else { // If the pair to remove is in the middle of the list
|
|
||||||
|
|
||||||
// Now, we want to move the last pair into the location that is
|
|
||||||
// now free because of the pair we want to remove
|
|
||||||
|
|
||||||
// Get the last pair
|
|
||||||
const BodyPair* lastPair = &mOverlappingPairs[indexLastPair];
|
|
||||||
const uint lastPairHashValue = computeHashBodies(lastPair->body1->getID(),
|
|
||||||
lastPair->body2->getID()) & mHashMask;
|
|
||||||
|
|
||||||
// Compute the initial offset of the last pair
|
|
||||||
bodyindex offset = mHashTable[lastPairHashValue];
|
|
||||||
assert(offset != INVALID_INDEX);
|
|
||||||
|
|
||||||
// Go through the pairs with the same hash value
|
|
||||||
// and find the offset of the last pair
|
|
||||||
bodyindex previous = INVALID_INDEX;
|
|
||||||
while(offset != indexLastPair) {
|
|
||||||
previous = offset;
|
|
||||||
offset = mOffsetNextPair[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the last pair is not the first one with this hash value
|
|
||||||
if (previous != INVALID_INDEX) {
|
|
||||||
|
|
||||||
// Remove the offset of the last pair in the "nextOffset" array
|
|
||||||
assert(mOffsetNextPair[previous] == indexLastPair);
|
|
||||||
mOffsetNextPair[previous] = mOffsetNextPair[indexLastPair];
|
|
||||||
}
|
|
||||||
else { // If the last pair is the first offset with this hash value
|
|
||||||
|
|
||||||
// Remove the offset of the last pair in the "nextOffset" array
|
|
||||||
mHashTable[lastPairHashValue] = mOffsetNextPair[indexLastPair];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the pair to remove by the last pair in
|
|
||||||
// the overlapping pairs array
|
|
||||||
mOverlappingPairs[indexPair] = mOverlappingPairs[indexLastPair];
|
|
||||||
mOffsetNextPair[indexPair] = mHashTable[lastPairHashValue];
|
|
||||||
mHashTable[lastPairHashValue] = indexPair;
|
|
||||||
|
|
||||||
mNbOverlappingPairs--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for a pair in the set of overlapping pairs
|
|
||||||
BodyPair* PairManager::lookForAPair(bodyindex id1, bodyindex id2, luint hashValue) const {
|
|
||||||
|
|
||||||
// Look for the pair in the set of overlapping pairs
|
|
||||||
bodyindex offset = mHashTable[hashValue];
|
|
||||||
while (offset != INVALID_INDEX && isDifferentPair(mOverlappingPairs[offset], id1, id2)) {
|
|
||||||
offset = mOffsetNextPair[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the pair has not been found in the overlapping pairs
|
|
||||||
if (offset == INVALID_INDEX) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(offset < mNbOverlappingPairs);
|
|
||||||
|
|
||||||
// The pair has been found in the set of overlapping pairs, then
|
|
||||||
// we return a pointer to it
|
|
||||||
return &mOverlappingPairs[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reallocate more pairs
|
|
||||||
void PairManager::reallocatePairs() {
|
|
||||||
|
|
||||||
// Reallocate the hash table and initialize it
|
|
||||||
free(mHashTable);
|
|
||||||
mHashTable = (bodyindex*) malloc(mNbElementsHashTable * sizeof(bodyindex));
|
|
||||||
assert(mHashTable != NULL);
|
|
||||||
for (bodyindex i=0; i<mNbElementsHashTable; i++) {
|
|
||||||
mHashTable[i] = INVALID_INDEX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reallocate the overlapping pairs
|
|
||||||
BodyPair* newOverlappingPairs = (BodyPair*) malloc(mNbElementsHashTable * sizeof(BodyPair));
|
|
||||||
bodyindex* newOffsetNextPair = (bodyindex*) malloc(mNbElementsHashTable * sizeof(bodyindex));
|
|
||||||
|
|
||||||
assert(newOverlappingPairs != NULL);
|
|
||||||
assert(newOffsetNextPair != NULL);
|
|
||||||
|
|
||||||
// If there is already some overlapping pairs
|
|
||||||
if (mNbOverlappingPairs) {
|
|
||||||
// Copy the pairs to the new location
|
|
||||||
memcpy(newOverlappingPairs, mOverlappingPairs, mNbOverlappingPairs * sizeof(BodyPair));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recompute the hash table with the new hash values
|
|
||||||
for (bodyindex i=0; i<mNbOverlappingPairs; i++) {
|
|
||||||
const uint newHashValue = computeHashBodies(mOverlappingPairs[i].body1->getID(),
|
|
||||||
mOverlappingPairs[i].body2->getID()) & mHashMask;
|
|
||||||
newOffsetNextPair[i] = mHashTable[newHashValue];
|
|
||||||
mHashTable[newHashValue] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the old pairs
|
|
||||||
free(mOffsetNextPair);
|
|
||||||
free(mOverlappingPairs);
|
|
||||||
|
|
||||||
// Replace by the new data
|
|
||||||
mOverlappingPairs = newOverlappingPairs;
|
|
||||||
mOffsetNextPair = newOffsetNextPair;
|
|
||||||
}
|
|
||||||
@ -1,333 +0,0 @@
|
|||||||
/********************************************************************************
|
|
||||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
|
||||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
|
||||||
*********************************************************************************
|
|
||||||
* *
|
|
||||||
* This software is provided 'as-is', without any express or implied warranty. *
|
|
||||||
* In no event will the authors be held liable for any damages arising from the *
|
|
||||||
* use of this software. *
|
|
||||||
* *
|
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
|
||||||
* including commercial applications, and to alter it and redistribute it *
|
|
||||||
* freely, subject to the following restrictions: *
|
|
||||||
* *
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
|
||||||
* that you wrote the original software. If you use this software in a *
|
|
||||||
* product, an acknowledgment in the product documentation would be *
|
|
||||||
* appreciated but is not required. *
|
|
||||||
* *
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
|
||||||
* misrepresented as being the original software. *
|
|
||||||
* *
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution. *
|
|
||||||
* *
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef REACTPHYSICS3D_PAIR_MANAGER_H
|
|
||||||
#define REACTPHYSICS3D_PAIR_MANAGER_H
|
|
||||||
|
|
||||||
// TODO : REMOVE THE PAIR MANAGER CLASS
|
|
||||||
|
|
||||||
// Libraries
|
|
||||||
#include "../../body/CollisionBody.h"
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
|
|
||||||
/// Namespace ReactPhysics3D
|
|
||||||
namespace reactphysics3d {
|
|
||||||
|
|
||||||
// Declaration
|
|
||||||
class CollisionDetection;
|
|
||||||
|
|
||||||
// Structure BodyPair
|
|
||||||
/**
|
|
||||||
* This structure represents a pair of bodies
|
|
||||||
* during the broad-phase collision detection.
|
|
||||||
*/
|
|
||||||
struct BodyPair {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Pointer to the first body
|
|
||||||
CollisionBody* body1;
|
|
||||||
|
|
||||||
/// Pointer to the second body
|
|
||||||
CollisionBody* body2;
|
|
||||||
|
|
||||||
/// Return the pair of bodies index
|
|
||||||
bodyindexpair getBodiesIndexPair() const {
|
|
||||||
|
|
||||||
// Construct the pair of body index
|
|
||||||
bodyindexpair indexPair = body1->getID() < body2->getID() ?
|
|
||||||
std::make_pair(body1->getID(), body2->getID()) :
|
|
||||||
std::make_pair(body2->getID(), body1->getID());
|
|
||||||
|
|
||||||
assert(indexPair.first != indexPair.second);
|
|
||||||
return indexPair;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Class PairManager
|
|
||||||
/**
|
|
||||||
* This class is a data-structure contains the pairs of bodies that
|
|
||||||
* are overlapping during the broad-phase collision detection.
|
|
||||||
* This class implements the pair manager described by Pierre Terdiman
|
|
||||||
* in www.codercorner.com/SAP.pdf.
|
|
||||||
*/
|
|
||||||
class PairManager {
|
|
||||||
|
|
||||||
private :
|
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
|
||||||
|
|
||||||
/// Number of elements in the hash table
|
|
||||||
bodyindex mNbElementsHashTable;
|
|
||||||
|
|
||||||
/// Hash mask for the hash function
|
|
||||||
uint mHashMask;
|
|
||||||
|
|
||||||
/// Number of overlapping pairs
|
|
||||||
bodyindex mNbOverlappingPairs;
|
|
||||||
|
|
||||||
/// Hash table that contains the offset of the first pair of the list of
|
|
||||||
/// pairs with the same hash value in the "overlappingPairs" array
|
|
||||||
bodyindex* mHashTable;
|
|
||||||
|
|
||||||
/// Array that contains for each offset, the offset of the next pair with
|
|
||||||
/// the same hash value for a given same hash value
|
|
||||||
bodyindex* mOffsetNextPair;
|
|
||||||
|
|
||||||
/// Array that contains the overlapping pairs
|
|
||||||
BodyPair* mOverlappingPairs;
|
|
||||||
|
|
||||||
/// Invalid ID
|
|
||||||
static bodyindex INVALID_INDEX;
|
|
||||||
|
|
||||||
/// Reference to the collision detection
|
|
||||||
CollisionDetection& mCollisionDetection;
|
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Private copy-constructor
|
|
||||||
PairManager(const PairManager& pairManager);
|
|
||||||
|
|
||||||
/// Private assignment operator
|
|
||||||
PairManager& operator=(const PairManager& pairManager);
|
|
||||||
|
|
||||||
/// Sort the bodies according to their IDs (smallest ID first)
|
|
||||||
void sortBodiesUsingID(CollisionBody*& body1, CollisionBody*& body2) const;
|
|
||||||
|
|
||||||
/// Sort the IDs (smallest ID first)
|
|
||||||
void sortIDs(bodyindex& id1, bodyindex& id2) const;
|
|
||||||
|
|
||||||
/// Return true if pair1 and pair2 are the same
|
|
||||||
bool isDifferentPair(const BodyPair& pair1, bodyindex pair2ID1, bodyindex pair2ID2) const;
|
|
||||||
|
|
||||||
/// Compute the hash value of two bodies using their IDs
|
|
||||||
uint computeHashBodies(uint id1, uint id2) const;
|
|
||||||
|
|
||||||
/// This method returns an hash value for a 32 bits key.
|
|
||||||
int computeHash32Bits(int key) const;
|
|
||||||
|
|
||||||
/// Reallocate memory for more pairs
|
|
||||||
void reallocatePairs();
|
|
||||||
|
|
||||||
/// Shrink the allocated memory
|
|
||||||
void shrinkMemory();
|
|
||||||
|
|
||||||
/// Compute the offset of a given pair
|
|
||||||
bodyindex computePairOffset(const BodyPair* pair) const;
|
|
||||||
|
|
||||||
/// Look for a pair in the set of overlapping pairs
|
|
||||||
BodyPair* lookForAPair(bodyindex id1, bodyindex id2, luint hashValue) const;
|
|
||||||
|
|
||||||
/// Find a pair given two body IDs and an hash value.
|
|
||||||
BodyPair* findPairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue) const;
|
|
||||||
|
|
||||||
/// Remove a pair from the set of active pair
|
|
||||||
void removePairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue,
|
|
||||||
bodyindex indexPair);
|
|
||||||
|
|
||||||
public :
|
|
||||||
|
|
||||||
// ----- Methods ----- //
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
PairManager(CollisionDetection& collisionDetection);
|
|
||||||
|
|
||||||
/// Destructor
|
|
||||||
~PairManager();
|
|
||||||
|
|
||||||
/// Return the number of active pairs
|
|
||||||
bodyindex getNbOverlappingPairs() const;
|
|
||||||
|
|
||||||
/// Add a pair of bodies in the pair manager and returns a pointer to that pair.
|
|
||||||
BodyPair* addPair(CollisionBody* body1, CollisionBody* body2);
|
|
||||||
|
|
||||||
/// Remove a pair of bodies from the pair manager.
|
|
||||||
bool removePair(bodyindex id1, bodyindex id2);
|
|
||||||
|
|
||||||
/// Find a pair given two body IDs
|
|
||||||
BodyPair* findPair(bodyindex id1, bodyindex id2) const;
|
|
||||||
|
|
||||||
/// Return the next power of two
|
|
||||||
static luint computeNextPowerOfTwo(luint number);
|
|
||||||
|
|
||||||
/// Return a pointer to the first overlapping pair (used to
|
|
||||||
/// iterate over the active pairs).
|
|
||||||
BodyPair* beginOverlappingPairsPointer() const;
|
|
||||||
|
|
||||||
/// Return a pointer to the last overlapping pair (used to
|
|
||||||
/// iterate over the active pairs).
|
|
||||||
BodyPair* endOverlappingPairsPointer() const;
|
|
||||||
|
|
||||||
/// Register a callback function (using a function pointer) that will be
|
|
||||||
/// called when a new overlapping pair is added in the pair manager.
|
|
||||||
void registerAddedOverlappingPairCallback(void (CollisionDetection::*callbackFunction)
|
|
||||||
(const BodyPair* addedActivePair));
|
|
||||||
|
|
||||||
/// Unregister the callback function that will be called
|
|
||||||
/// when a new active pair is added in the pair manager
|
|
||||||
void unregisterAddedOverlappingPairCallback();
|
|
||||||
|
|
||||||
/// Register a callback function (using a function pointer)
|
|
||||||
/// that will be called when an overlapping pair is removed from the pair manager
|
|
||||||
void registerRemovedOverlappingPairCallback(void (CollisionDetection::*callbackFunction)
|
|
||||||
(const BodyPair* removedActivePair));
|
|
||||||
|
|
||||||
/// Unregister a callback function that will be called
|
|
||||||
/// when a active pair is removed from the pair manager
|
|
||||||
void unregisterRemovedOverlappingPairCallback();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the number of overlapping pairs
|
|
||||||
inline bodyindex PairManager::getNbOverlappingPairs() const {
|
|
||||||
return mNbOverlappingPairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the hash value of two bodies
|
|
||||||
inline uint PairManager::computeHashBodies(uint id1, uint id2) const {
|
|
||||||
return computeHash32Bits(id1 | (id2 << 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return true if pair1 and pair2 are the same
|
|
||||||
inline bool PairManager::isDifferentPair(const BodyPair& pair1, bodyindex pair2ID1,
|
|
||||||
bodyindex pair2ID2) const {
|
|
||||||
return (pair2ID1 != pair1.body1->getID() || pair2ID2 != pair1.body2->getID());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the next power of two of a 32bits integer using a SWAR algorithm
|
|
||||||
inline luint PairManager::computeNextPowerOfTwo(luint number) {
|
|
||||||
number |= (number >> 1);
|
|
||||||
number |= (number >> 2);
|
|
||||||
number |= (number >> 4);
|
|
||||||
number |= (number >> 8);
|
|
||||||
number |= (number >> 16);
|
|
||||||
return number+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the bodies according to their IDs (smallest ID first)
|
|
||||||
inline void PairManager::sortBodiesUsingID(CollisionBody*& body1, CollisionBody*& body2) const {
|
|
||||||
|
|
||||||
// If the ID of body1 is larger than the ID of body 2
|
|
||||||
if (body1->getID() > body2->getID()) {
|
|
||||||
|
|
||||||
// Swap the two bodies pointers
|
|
||||||
CollisionBody* temp = body2;
|
|
||||||
body2 = body1;
|
|
||||||
body1 = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the IDs (smallest ID first)
|
|
||||||
inline void PairManager::sortIDs(bodyindex &id1, bodyindex &id2) const {
|
|
||||||
if (id1 > id2) {
|
|
||||||
bodyindex temp = id2;
|
|
||||||
id2 = id1;
|
|
||||||
id1 = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method returns an hash value for a 32 bits key.
|
|
||||||
/// using Thomas Wang's hash technique.
|
|
||||||
/// This hash function can be found at :
|
|
||||||
/// http://www.concentric.net/~ttwang/tech/inthash.htm
|
|
||||||
inline int PairManager::computeHash32Bits(int key) const {
|
|
||||||
key += ~(key << 15);
|
|
||||||
key ^= (key >> 10);
|
|
||||||
key += (key << 3);
|
|
||||||
key ^= (key >> 6);
|
|
||||||
key += ~(key << 11);
|
|
||||||
key ^= (key >> 16);
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find a pair given two body IDs
|
|
||||||
inline BodyPair* PairManager::findPair(bodyindex id1, bodyindex id2) const {
|
|
||||||
|
|
||||||
// Check if the hash table has been allocated yet
|
|
||||||
if (mHashTable == NULL) return NULL;
|
|
||||||
|
|
||||||
// Sort the IDs
|
|
||||||
sortIDs(id1, id2);
|
|
||||||
|
|
||||||
// Compute the hash value of the pair to find
|
|
||||||
uint hashValue = computeHashBodies(id1, id2) & mHashMask;
|
|
||||||
|
|
||||||
// Look for the pair in the set of overlapping pairs
|
|
||||||
return lookForAPair(id1, id2, hashValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find a pair given two body IDs and an hash value.
|
|
||||||
/// This internal version is used to avoid computing multiple times in the
|
|
||||||
/// caller method
|
|
||||||
inline BodyPair* PairManager::findPairWithHashValue(bodyindex id1, bodyindex id2,
|
|
||||||
luint hashValue) const {
|
|
||||||
|
|
||||||
// Check if the hash table has been allocated yet
|
|
||||||
if (mHashTable == NULL) return NULL;
|
|
||||||
|
|
||||||
// Look for the pair in the set of overlapping pairs
|
|
||||||
return lookForAPair(id1, id2, hashValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to reduce the allocated memory by the pair manager
|
|
||||||
inline void PairManager::shrinkMemory() {
|
|
||||||
|
|
||||||
// Check if the allocated memory can be reduced
|
|
||||||
const bodyindex correctNbElementsHashTable = computeNextPowerOfTwo(mNbOverlappingPairs);
|
|
||||||
if (mNbElementsHashTable == correctNbElementsHashTable) return;
|
|
||||||
|
|
||||||
// Reduce the allocated memory
|
|
||||||
mNbElementsHashTable = correctNbElementsHashTable;
|
|
||||||
mHashMask = mNbElementsHashTable - 1;
|
|
||||||
reallocatePairs();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the offset of a given pair in the array of overlapping pairs
|
|
||||||
inline bodyindex PairManager::computePairOffset(const BodyPair* pair) const {
|
|
||||||
return ((bodyindex)((size_t(pair) - size_t(mOverlappingPairs))) / sizeof(BodyPair));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the first overlapping pair (used to iterate over the overlapping pairs) or
|
|
||||||
// returns 0 if there is no overlapping pairs.
|
|
||||||
inline BodyPair* PairManager::beginOverlappingPairsPointer() const {
|
|
||||||
return &mOverlappingPairs[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a pointer to the last overlapping pair (used to iterate over the overlapping pairs) or
|
|
||||||
// returns 0 if there is no overlapping pairs.
|
|
||||||
inline BodyPair* PairManager::endOverlappingPairsPointer() const {
|
|
||||||
if (mNbOverlappingPairs > 0) {
|
|
||||||
return &mOverlappingPairs[mNbOverlappingPairs-1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return &mOverlappingPairs[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@ -29,7 +29,6 @@
|
|||||||
// Libraries
|
// Libraries
|
||||||
#include "body/Body.h"
|
#include "body/Body.h"
|
||||||
#include "constraint/ContactPoint.h"
|
#include "constraint/ContactPoint.h"
|
||||||
#include "collision/broadphase/PairManager.h"
|
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/MemoryAllocator.h"
|
||||||
#include "engine/OverlappingPair.h"
|
#include "engine/OverlappingPair.h"
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user