mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:00:41 +02:00
ShapeKey now derives from DoubleHashKey
This commit is contained in:
parent
f1bdd2ef7b
commit
57e972d876
6 changed files with 91 additions and 79 deletions
43
libraries/physics/src/DoubleHashKey.cpp
Normal file
43
libraries/physics/src/DoubleHashKey.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// DoubleHashKey.cpp
|
||||||
|
// libraries/physcis/src
|
||||||
|
//
|
||||||
|
// Created by Andrew Meadows 2014.11.02
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DoubleHashKey.h"
|
||||||
|
|
||||||
|
const int NUM_PRIMES = 64;
|
||||||
|
const unsigned int PRIMES[] = {
|
||||||
|
4194301U, 4194287U, 4194277U, 4194271U, 4194247U, 4194217U, 4194199U, 4194191U,
|
||||||
|
4194187U, 4194181U, 4194173U, 4194167U, 4194143U, 4194137U, 4194131U, 4194107U,
|
||||||
|
4194103U, 4194023U, 4194011U, 4194007U, 4193977U, 4193971U, 4193963U, 4193957U,
|
||||||
|
4193939U, 4193929U, 4193909U, 4193869U, 4193807U, 4193803U, 4193801U, 4193789U,
|
||||||
|
4193759U, 4193753U, 4193743U, 4193701U, 4193663U, 4193633U, 4193573U, 4193569U,
|
||||||
|
4193551U, 4193549U, 4193531U, 4193513U, 4193507U, 4193459U, 4193447U, 4193443U,
|
||||||
|
4193417U, 4193411U, 4193393U, 4193389U, 4193381U, 4193377U, 4193369U, 4193359U,
|
||||||
|
4193353U, 4193327U, 4193309U, 4193303U, 4193297U, 4193279U, 4193269U, 4193263U
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int DoubleHashKey::hashFunction(unsigned int value, int primeIndex) {
|
||||||
|
unsigned int hash = PRIMES[primeIndex % NUM_PRIMES] * (value + 1U);
|
||||||
|
hash += ~(hash << 15);
|
||||||
|
hash ^= (hash >> 10);
|
||||||
|
hash += (hash << 3);
|
||||||
|
hash ^= (hash >> 6);
|
||||||
|
hash += ~(hash << 11);
|
||||||
|
return hash ^ (hash >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int DoubleHashKey::hashFunction2(unsigned int value) {
|
||||||
|
unsigned hash = 0x811c9dc5U;
|
||||||
|
for (int i = 0; i < 4; i++ ) {
|
||||||
|
unsigned int byte = (value << (i * 8)) >> (24 - i * 8);
|
||||||
|
hash = ( hash ^ byte ) * 0x01000193U;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
36
libraries/physics/src/DoubleHashKey.h
Normal file
36
libraries/physics/src/DoubleHashKey.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// DoubleHashKey.h
|
||||||
|
// libraries/physcis/src
|
||||||
|
//
|
||||||
|
// Created by Andrew Meadows 2014.11.02
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_DoubleHashKey_h
|
||||||
|
#define hifi_DoubleHashKey_h
|
||||||
|
|
||||||
|
// DoubleHashKey for use with btHashMap
|
||||||
|
class DoubleHashKey {
|
||||||
|
public:
|
||||||
|
static unsigned int hashFunction(unsigned int value, int primeIndex);
|
||||||
|
static unsigned int hashFunction2(unsigned int value);
|
||||||
|
|
||||||
|
DoubleHashKey(unsigned int value, int primIndex = 0) : _hash(hashFunction(value, primIndex)), _hash2(hashFunction2(value)) { }
|
||||||
|
|
||||||
|
bool equals(const DoubleHashKey& other) const {
|
||||||
|
return _hash == other._hash && _hash2 == other._hash2;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int getHash() const { return (unsigned int)_hash; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DoubleHashKey() : _hash(0), _hash2(0) { }
|
||||||
|
|
||||||
|
int _hash;
|
||||||
|
int _hash2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_DoubleHashKey_h
|
|
@ -15,19 +15,6 @@
|
||||||
|
|
||||||
#include "ShapeInfo.h"
|
#include "ShapeInfo.h"
|
||||||
|
|
||||||
// prime numbers larger than 1e6
|
|
||||||
const int NUM_PRIMES = 64;
|
|
||||||
const unsigned int PRIMES[] = {
|
|
||||||
4194301U, 4194287U, 4194277U, 4194271U, 4194247U, 4194217U, 4194199U, 4194191U,
|
|
||||||
4194187U, 4194181U, 4194173U, 4194167U, 4194143U, 4194137U, 4194131U, 4194107U,
|
|
||||||
4194103U, 4194023U, 4194011U, 4194007U, 4193977U, 4193971U, 4193963U, 4193957U,
|
|
||||||
4193939U, 4193929U, 4193909U, 4193869U, 4193807U, 4193803U, 4193801U, 4193789U,
|
|
||||||
4193759U, 4193753U, 4193743U, 4193701U, 4193663U, 4193633U, 4193573U, 4193569U,
|
|
||||||
4193551U, 4193549U, 4193531U, 4193513U, 4193507U, 4193459U, 4193447U, 4193443U,
|
|
||||||
4193417U, 4193411U, 4193393U, 4193389U, 4193381U, 4193377U, 4193369U, 4193359U,
|
|
||||||
4193353U, 4193327U, 4193309U, 4193303U, 4193297U, 4193279U, 4193269U, 4193263U
|
|
||||||
};
|
|
||||||
|
|
||||||
void ShapeInfo::collectInfo(const btCollisionShape* shape) {
|
void ShapeInfo::collectInfo(const btCollisionShape* shape) {
|
||||||
_data.clear();
|
_data.clear();
|
||||||
if (shape) {
|
if (shape) {
|
||||||
|
@ -93,32 +80,13 @@ void ShapeInfo::setCapsule(float radius, float height) {
|
||||||
_data.push_back(btVector3(radius, 0.5f * height, 0.0f));
|
_data.push_back(btVector3(radius, 0.5f * height, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ShapeInfo::hashFunction(unsigned int value, int primeIndex) {
|
|
||||||
unsigned int hash = PRIMES[primeIndex % NUM_PRIMES] * (value + 1U);
|
|
||||||
hash += ~(hash << 15);
|
|
||||||
hash ^= (hash >> 10);
|
|
||||||
hash += (hash << 3);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
hash += ~(hash << 11);
|
|
||||||
return hash ^ (hash >> 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ShapeInfo::hashFunction2(unsigned int value) {
|
|
||||||
unsigned hash = 0x811c9dc5U;
|
|
||||||
for (int i = 0; i < 4; i++ ) {
|
|
||||||
unsigned int byte = (value << (i * 8)) >> (24 - i * 8);
|
|
||||||
hash = ( hash ^ byte ) * 0x01000193U;
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float MILLIMETERS_PER_METER = 1000.0f;
|
const float MILLIMETERS_PER_METER = 1000.0f;
|
||||||
|
|
||||||
int ShapeInfo::computeHash() const {
|
int ShapeInfo::computeHash() const {
|
||||||
// scramble the bits of the type
|
// scramble the bits of the type
|
||||||
// TODO?: provide lookup table for hash of _type?
|
// TODO?: provide lookup table for hash of _type?
|
||||||
int primeIndex = 0;
|
int primeIndex = 0;
|
||||||
unsigned int hash = ShapeInfo::hashFunction((unsigned int)_type, primeIndex++);
|
unsigned int hash = DoubleHashKey::hashFunction((unsigned int)_type, primeIndex++);
|
||||||
|
|
||||||
btVector3 tmpData;
|
btVector3 tmpData;
|
||||||
int numData = _data.size();
|
int numData = _data.size();
|
||||||
|
@ -126,7 +94,7 @@ int ShapeInfo::computeHash() const {
|
||||||
tmpData = _data[i];
|
tmpData = _data[i];
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
// multiply these mm by a new prime
|
// multiply these mm by a new prime
|
||||||
unsigned int floatHash = ShapeInfo::hashFunction((unsigned int)(tmpData[j] * MILLIMETERS_PER_METER + 0.49f), primeIndex++);
|
unsigned int floatHash = DoubleHashKey::hashFunction((unsigned int)(tmpData[j] * MILLIMETERS_PER_METER + 0.49f), primeIndex++);
|
||||||
hash ^= floatHash;
|
hash ^= floatHash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,14 +104,14 @@ int ShapeInfo::computeHash() const {
|
||||||
int ShapeInfo::computeHash2() const {
|
int ShapeInfo::computeHash2() const {
|
||||||
// scramble the bits of the type
|
// scramble the bits of the type
|
||||||
// TODO?: provide lookup table for hash of _type?
|
// TODO?: provide lookup table for hash of _type?
|
||||||
unsigned int hash = ShapeInfo::hashFunction2((unsigned int)_type);
|
unsigned int hash = DoubleHashKey::hashFunction2((unsigned int)_type);
|
||||||
|
|
||||||
btVector3 tmpData;
|
btVector3 tmpData;
|
||||||
int numData = _data.size();
|
int numData = _data.size();
|
||||||
for (int i = 0; i < numData; ++i) {
|
for (int i = 0; i < numData; ++i) {
|
||||||
tmpData = _data[i];
|
tmpData = _data[i];
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
unsigned int floatHash = ShapeInfo::hashFunction2((unsigned int)(tmpData[j] * MILLIMETERS_PER_METER + 0.49f));
|
unsigned int floatHash = DoubleHashKey::hashFunction2((unsigned int)(tmpData[j] * MILLIMETERS_PER_METER + 0.49f));
|
||||||
hash += ~(floatHash << 17);
|
hash += ~(floatHash << 17);
|
||||||
hash ^= (floatHash >> 11);
|
hash ^= (floatHash >> 11);
|
||||||
hash += (floatHash << 4);
|
hash += (floatHash << 4);
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <LinearMath/btHashMap.h>
|
#include <LinearMath/btHashMap.h>
|
||||||
|
|
||||||
|
#include "DoubleHashKey.h"
|
||||||
|
|
||||||
class ShapeInfo {
|
class ShapeInfo {
|
||||||
public:
|
public:
|
||||||
ShapeInfo() : _type(INVALID_SHAPE_PROXYTYPE) {}
|
ShapeInfo() : _type(INVALID_SHAPE_PROXYTYPE) {}
|
||||||
|
@ -35,9 +37,6 @@ public:
|
||||||
int computeHash() const;
|
int computeHash() const;
|
||||||
int computeHash2() const;
|
int computeHash2() const;
|
||||||
|
|
||||||
static unsigned int hashFunction(unsigned int value, int primeIndex);
|
|
||||||
static unsigned int hashFunction2(unsigned int value);
|
|
||||||
|
|
||||||
btCollisionShape* createShape() const;
|
btCollisionShape* createShape() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -68,34 +68,10 @@ bool ShapeManager::releaseShape(const ShapeInfo& info) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
bool ShapeManager::releaseShape(const btCollisionShape* shape) {
|
bool ShapeManager::releaseShape(const btCollisionShape* shape) {
|
||||||
// when the number of shapes is high it's probably cheaper to try to construct a ShapeInfo
|
ShapeInfo info(shape);
|
||||||
// and then compute the hash rather than walking the list in search of the pointer.
|
return releaseShape(info);
|
||||||
ShapeKey key(info);
|
|
||||||
ShapeReference* shapeRef = _shapeMap.find(key);
|
|
||||||
if (shapeRef) {
|
|
||||||
if (shapeRef->_refCount > 0) {
|
|
||||||
shapeRef->_refCount--;
|
|
||||||
if (shapeRef->_refCount == 0) {
|
|
||||||
_pendingGarbage.push_back(key);
|
|
||||||
const int MAX_GARBAGE_CAPACITY = 127;
|
|
||||||
if (_pendingGarbage.size() > MAX_GARBAGE_CAPACITY) {
|
|
||||||
collectGarbage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// attempt to remove shape that has no refs
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// attempt to remove unmanaged shape
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
void ShapeManager::collectGarbage() {
|
void ShapeManager::collectGarbage() {
|
||||||
int numShapes = _pendingGarbage.size();
|
int numShapes = _pendingGarbage.size();
|
||||||
|
|
|
@ -17,28 +17,18 @@
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <LinearMath/btHashMap.h>
|
#include <LinearMath/btHashMap.h>
|
||||||
|
|
||||||
|
#include "DoubleHashKey.h"
|
||||||
#include "ShapeInfo.h"
|
#include "ShapeInfo.h"
|
||||||
|
|
||||||
class ShapeKey
|
class ShapeKey : public DoubleHashKey
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShapeKey(const ShapeInfo& info) : _hash(0), _hash2(0) {
|
ShapeKey(const ShapeInfo& info) : DoubleHashKey() {
|
||||||
_hash = info.computeHash();
|
_hash = info.computeHash();
|
||||||
_hash2 = info.computeHash2();
|
_hash2 = info.computeHash2();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals(const ShapeKey& other) const {
|
|
||||||
return _hash == other._hash && _hash2 == other._hash2;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int getHash() const { return (unsigned int)_hash; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _hash;
|
|
||||||
int _hash2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ShapeManager {
|
class ShapeManager {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -50,7 +40,7 @@ public:
|
||||||
|
|
||||||
/// \return true if shape was found and released
|
/// \return true if shape was found and released
|
||||||
bool releaseShape(const ShapeInfo& info);
|
bool releaseShape(const ShapeInfo& info);
|
||||||
// bool removeReference(const btCollisionShape*);
|
bool releaseShape(const btCollisionShape* shape);
|
||||||
|
|
||||||
/// delete shapes that have zero references
|
/// delete shapes that have zero references
|
||||||
void collectGarbage();
|
void collectGarbage();
|
||||||
|
|
Loading…
Reference in a new issue