From 57e972d87665d588a5a66b99565503f2eb71dadc Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 4 Nov 2014 14:54:35 -0800 Subject: [PATCH] ShapeKey now derives from DoubleHashKey --- libraries/physics/src/DoubleHashKey.cpp | 43 +++++++++++++++++++++++++ libraries/physics/src/DoubleHashKey.h | 36 +++++++++++++++++++++ libraries/physics/src/ShapeInfo.cpp | 40 +++-------------------- libraries/physics/src/ShapeInfo.h | 5 ++- libraries/physics/src/ShapeManager.cpp | 28 ++-------------- libraries/physics/src/ShapeManager.h | 18 +++-------- 6 files changed, 91 insertions(+), 79 deletions(-) create mode 100644 libraries/physics/src/DoubleHashKey.cpp create mode 100644 libraries/physics/src/DoubleHashKey.h diff --git a/libraries/physics/src/DoubleHashKey.cpp b/libraries/physics/src/DoubleHashKey.cpp new file mode 100644 index 0000000000..fae1d715fb --- /dev/null +++ b/libraries/physics/src/DoubleHashKey.cpp @@ -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; +} diff --git a/libraries/physics/src/DoubleHashKey.h b/libraries/physics/src/DoubleHashKey.h new file mode 100644 index 0000000000..090eab38a6 --- /dev/null +++ b/libraries/physics/src/DoubleHashKey.h @@ -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 diff --git a/libraries/physics/src/ShapeInfo.cpp b/libraries/physics/src/ShapeInfo.cpp index 3d2b8c0f81..85a01f6bda 100644 --- a/libraries/physics/src/ShapeInfo.cpp +++ b/libraries/physics/src/ShapeInfo.cpp @@ -15,19 +15,6 @@ #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) { _data.clear(); if (shape) { @@ -93,32 +80,13 @@ void ShapeInfo::setCapsule(float radius, float height) { _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; int ShapeInfo::computeHash() const { // scramble the bits of the type // TODO?: provide lookup table for hash of _type? int primeIndex = 0; - unsigned int hash = ShapeInfo::hashFunction((unsigned int)_type, primeIndex++); + unsigned int hash = DoubleHashKey::hashFunction((unsigned int)_type, primeIndex++); btVector3 tmpData; int numData = _data.size(); @@ -126,7 +94,7 @@ int ShapeInfo::computeHash() const { tmpData = _data[i]; for (int j = 0; j < 3; ++j) { // 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; } } @@ -136,14 +104,14 @@ int ShapeInfo::computeHash() const { int ShapeInfo::computeHash2() const { // scramble the bits of the 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; int numData = _data.size(); for (int i = 0; i < numData; ++i) { tmpData = _data[i]; 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 >> 11); hash += (floatHash << 4); diff --git a/libraries/physics/src/ShapeInfo.h b/libraries/physics/src/ShapeInfo.h index d5d70d7b56..f2a39b5320 100644 --- a/libraries/physics/src/ShapeInfo.h +++ b/libraries/physics/src/ShapeInfo.h @@ -17,6 +17,8 @@ #include #include +#include "DoubleHashKey.h" + class ShapeInfo { public: ShapeInfo() : _type(INVALID_SHAPE_PROXYTYPE) {} @@ -35,9 +37,6 @@ public: int computeHash() const; int computeHash2() const; - static unsigned int hashFunction(unsigned int value, int primeIndex); - static unsigned int hashFunction2(unsigned int value); - btCollisionShape* createShape() const; private: diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 61f0ceabad..c75bfd67ea 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -68,34 +68,10 @@ bool ShapeManager::releaseShape(const ShapeInfo& info) { return false; } -/* bool ShapeManager::releaseShape(const btCollisionShape* shape) { - // when the number of shapes is high it's probably cheaper to try to construct a ShapeInfo - // and then compute the hash rather than walking the list in search of the pointer. - 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; + ShapeInfo info(shape); + return releaseShape(info); } -*/ void ShapeManager::collectGarbage() { int numShapes = _pendingGarbage.size(); diff --git a/libraries/physics/src/ShapeManager.h b/libraries/physics/src/ShapeManager.h index 6c497dd981..b205103f19 100644 --- a/libraries/physics/src/ShapeManager.h +++ b/libraries/physics/src/ShapeManager.h @@ -17,28 +17,18 @@ #include #include +#include "DoubleHashKey.h" #include "ShapeInfo.h" -class ShapeKey +class ShapeKey : public DoubleHashKey { public: - ShapeKey(const ShapeInfo& info) : _hash(0), _hash2(0) { + ShapeKey(const ShapeInfo& info) : DoubleHashKey() { _hash = info.computeHash(); _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 { public: @@ -50,7 +40,7 @@ public: /// \return true if shape was found and released bool releaseShape(const ShapeInfo& info); -// bool removeReference(const btCollisionShape*); + bool releaseShape(const btCollisionShape* shape); /// delete shapes that have zero references void collectGarbage();