mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 14:12:50 +02:00
clean HashKey API, reduce dependency tree
This commit is contained in:
parent
17ab0cb92e
commit
a3567dea3a
5 changed files with 43 additions and 42 deletions
|
@ -33,8 +33,8 @@ const btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) {
|
|||
if (info.getType() == SHAPE_TYPE_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
HashKey key = info.getHash();
|
||||
ShapeReference* shapeRef = _shapeMap.find(key);
|
||||
HashKey hashKey(info.getHash());
|
||||
ShapeReference* shapeRef = _shapeMap.find(hashKey);
|
||||
if (shapeRef) {
|
||||
shapeRef->refCount++;
|
||||
return shapeRef->shape;
|
||||
|
@ -44,27 +44,28 @@ const btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) {
|
|||
ShapeReference newRef;
|
||||
newRef.refCount = 1;
|
||||
newRef.shape = shape;
|
||||
newRef.key = key;
|
||||
_shapeMap.insert(key, newRef);
|
||||
newRef.key = info.getHash();
|
||||
_shapeMap.insert(hashKey, newRef);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
// private helper method
|
||||
bool ShapeManager::releaseShapeByKey(const HashKey& key) {
|
||||
ShapeReference* shapeRef = _shapeMap.find(key);
|
||||
bool ShapeManager::releaseShapeByKey(uint64_t key) {
|
||||
HashKey hashKey(key);
|
||||
ShapeReference* shapeRef = _shapeMap.find(hashKey);
|
||||
if (shapeRef) {
|
||||
if (shapeRef->refCount > 0) {
|
||||
shapeRef->refCount--;
|
||||
if (shapeRef->refCount == 0) {
|
||||
// look for existing entry in _pendingGarbage, starting from the back
|
||||
for (int32_t i = _pendingGarbage.size() - 1; i > -1; --i) {
|
||||
if (_pendingGarbage[i] == key.getHash64()) {
|
||||
if (_pendingGarbage[i] == key) {
|
||||
// already on the list, don't add it again
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_pendingGarbage.push_back(key.getHash64());
|
||||
_pendingGarbage.push_back(key);
|
||||
const int MAX_SHAPE_GARBAGE_CAPACITY = 255;
|
||||
if (_pendingGarbage.size() > MAX_SHAPE_GARBAGE_CAPACITY) {
|
||||
collectGarbage();
|
||||
|
@ -107,8 +108,8 @@ void ShapeManager::collectGarbage() {
|
|||
}
|
||||
|
||||
int ShapeManager::getNumReferences(const ShapeInfo& info) const {
|
||||
HashKey key = info.getHash();
|
||||
const ShapeReference* shapeRef = _shapeMap.find(key);
|
||||
HashKey hashKey(info.getHash());
|
||||
const ShapeReference* shapeRef = _shapeMap.find(hashKey);
|
||||
if (shapeRef) {
|
||||
return shapeRef->refCount;
|
||||
}
|
||||
|
|
|
@ -63,13 +63,13 @@ public:
|
|||
bool hasShape(const btCollisionShape* shape) const;
|
||||
|
||||
private:
|
||||
bool releaseShapeByKey(const HashKey& key);
|
||||
bool releaseShapeByKey(uint64_t key);
|
||||
|
||||
class ShapeReference {
|
||||
public:
|
||||
int refCount;
|
||||
const btCollisionShape* shape;
|
||||
HashKey key;
|
||||
uint64_t key { 0 };
|
||||
ShapeReference() : refCount(0), shape(nullptr) {}
|
||||
};
|
||||
|
||||
|
|
|
@ -39,13 +39,12 @@ public:
|
|||
bool equals(const HashKey& other) const { return _hash == other._hash; }
|
||||
int32_t getHash() const { return (int32_t)((uint32_t)_hash); }
|
||||
|
||||
void clear() { _hash = _hashCount = 0; }
|
||||
bool isNull() const { return _hash == 0 && _hashCount == 0; }
|
||||
// These methods for accumulating a hash.
|
||||
void hashUint64(uint64_t data);
|
||||
void hashFloat(float data);
|
||||
void hashVec3(const glm::vec3& data);
|
||||
|
||||
uint64_t getHash64() const { return _hash; } // for debug/test purposes
|
||||
uint64_t getHash64() const { return _hash; }
|
||||
|
||||
private:
|
||||
uint64_t _hash { 0 };
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "HashKey.h"
|
||||
#include "NumericalConstants.h" // for MILLIMETERS_PER_METER
|
||||
|
||||
/**jsdoc
|
||||
|
@ -96,7 +97,7 @@ void ShapeInfo::clear() {
|
|||
_sphereCollection.clear();
|
||||
_halfExtents = glm::vec3(0.0f);
|
||||
_offset = glm::vec3(0.0f);
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
_type = SHAPE_TYPE_NONE;
|
||||
}
|
||||
|
||||
|
@ -131,14 +132,14 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString
|
|||
default:
|
||||
break;
|
||||
}
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
||||
void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
||||
_url = "";
|
||||
_type = SHAPE_TYPE_BOX;
|
||||
setHalfExtents(halfExtents);
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
||||
void ShapeInfo::setSphere(float radius) {
|
||||
|
@ -146,7 +147,7 @@ void ShapeInfo::setSphere(float radius) {
|
|||
_type = SHAPE_TYPE_SPHERE;
|
||||
radius = glm::max(radius, MIN_HALF_EXTENT);
|
||||
_halfExtents = glm::vec3(radius);
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
||||
void ShapeInfo::setMultiSphere(const std::vector<glm::vec3>& centers, const std::vector<float>& radiuses) {
|
||||
|
@ -158,12 +159,12 @@ void ShapeInfo::setMultiSphere(const std::vector<glm::vec3>& centers, const std:
|
|||
SphereData sphere = SphereData(centers[i], radiuses[i]);
|
||||
_sphereCollection.push_back(sphere);
|
||||
}
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
||||
void ShapeInfo::setPointCollection(const ShapeInfo::PointCollection& pointCollection) {
|
||||
_pointCollection = pointCollection;
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
||||
void ShapeInfo::setCapsuleY(float radius, float cylinderHalfHeight) {
|
||||
|
@ -172,12 +173,12 @@ void ShapeInfo::setCapsuleY(float radius, float cylinderHalfHeight) {
|
|||
radius = glm::max(radius, MIN_HALF_EXTENT);
|
||||
cylinderHalfHeight = glm::max(cylinderHalfHeight, 0.0f);
|
||||
_halfExtents = glm::vec3(radius, cylinderHalfHeight + radius, radius);
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
||||
void ShapeInfo::setOffset(const glm::vec3& offset) {
|
||||
_offset = offset;
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
||||
uint32_t ShapeInfo::getNumSubShapes() const {
|
||||
|
@ -269,20 +270,21 @@ float ShapeInfo::computeVolume() const {
|
|||
return volume;
|
||||
}
|
||||
|
||||
const HashKey& ShapeInfo::getHash() const {
|
||||
uint64_t ShapeInfo::getHash() const {
|
||||
// NOTE: we cache the key so we only ever need to compute it once for any valid ShapeInfo instance.
|
||||
if (_hashKey.isNull() && _type != SHAPE_TYPE_NONE) {
|
||||
if (_hash64 == 0 && _type != SHAPE_TYPE_NONE) {
|
||||
HashKey hashKey;
|
||||
// The key is not yet cached therefore we must compute it.
|
||||
|
||||
_hashKey.hashUint64((uint64_t)_type);
|
||||
hashKey.hashUint64((uint64_t)_type);
|
||||
if (_type == SHAPE_TYPE_MULTISPHERE) {
|
||||
for (auto &sphereData : _sphereCollection) {
|
||||
_hashKey.hashVec3(glm::vec3(sphereData));
|
||||
_hashKey.hashFloat(sphereData.w);
|
||||
hashKey.hashVec3(glm::vec3(sphereData));
|
||||
hashKey.hashFloat(sphereData.w);
|
||||
}
|
||||
} else if (_type != SHAPE_TYPE_SIMPLE_HULL) {
|
||||
_hashKey.hashVec3(_halfExtents);
|
||||
_hashKey.hashVec3(_offset);
|
||||
hashKey.hashVec3(_halfExtents);
|
||||
hashKey.hashVec3(_offset);
|
||||
} else {
|
||||
// TODO: we could avoid hashing all of these points if we were to supply the ShapeInfo with a unique
|
||||
// descriptive string. Shapes that are uniquely described by their type and URL could just put their
|
||||
|
@ -292,7 +294,7 @@ const HashKey& ShapeInfo::getHash() const {
|
|||
const int numPoints = (int)points.size();
|
||||
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
_hashKey.hashVec3(points[i]);
|
||||
hashKey.hashVec3(points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,23 +302,24 @@ const HashKey& ShapeInfo::getHash() const {
|
|||
if (!url.isEmpty()) {
|
||||
QByteArray baUrl = url.toLocal8Bit();
|
||||
uint32_t urlHash = qChecksum(baUrl.data(), baUrl.size());
|
||||
_hashKey.hashUint64((uint64_t)urlHash);
|
||||
hashKey.hashUint64((uint64_t)urlHash);
|
||||
}
|
||||
|
||||
if (_type == SHAPE_TYPE_COMPOUND || _type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||
uint64_t numHulls = (uint64_t)_pointCollection.size();
|
||||
_hashKey.hashUint64(numHulls);
|
||||
hashKey.hashUint64(numHulls);
|
||||
} else if (_type == SHAPE_TYPE_MULTISPHERE) {
|
||||
uint64_t numSpheres = (uint64_t)_sphereCollection.size();
|
||||
_hashKey.hashUint64(numSpheres);
|
||||
hashKey.hashUint64(numSpheres);
|
||||
} else if (_type == SHAPE_TYPE_SIMPLE_HULL) {
|
||||
_hashKey.hashUint64(1);
|
||||
}
|
||||
hashKey.hashUint64(1);
|
||||
}
|
||||
_hash64 = hashKey.getHash64();
|
||||
}
|
||||
return _hashKey;
|
||||
return _hash64;
|
||||
}
|
||||
|
||||
void ShapeInfo::setHalfExtents(const glm::vec3& halfExtents) {
|
||||
_halfExtents = glm::max(halfExtents, glm::vec3(MIN_HALF_EXTENT));
|
||||
_hashKey.clear();
|
||||
_hash64 = 0;
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include "HashKey.h"
|
||||
|
||||
const float MIN_SHAPE_OFFSET = 0.001f; // offsets less than 1mm will be ignored
|
||||
|
||||
// Bullet has a mesh generation util for convex shapes that we used to
|
||||
|
@ -91,7 +89,7 @@ public:
|
|||
|
||||
float computeVolume() const;
|
||||
|
||||
const HashKey& getHash() const;
|
||||
uint64_t getHash() const;
|
||||
|
||||
protected:
|
||||
void setHalfExtents(const glm::vec3& halfExtents);
|
||||
|
@ -102,7 +100,7 @@ protected:
|
|||
TriangleIndices _triangleIndices;
|
||||
glm::vec3 _halfExtents = glm::vec3(0.0f);
|
||||
glm::vec3 _offset = glm::vec3(0.0f);
|
||||
mutable HashKey _hashKey;
|
||||
mutable uint64_t _hash64;
|
||||
ShapeType _type = SHAPE_TYPE_NONE;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue