reduce footprint of ShapeManager::_shapeMap

This commit is contained in:
Andrew Meadows 2019-04-17 14:43:49 -07:00
parent 86f562de1b
commit 7fb7e503f9
3 changed files with 27 additions and 22 deletions

View file

@ -51,15 +51,15 @@ float HashKey::getNumQuantizedValuesPerMeter() {
return QUANTIZED_VALUES_PER_METER;
}
void HashKey::hashUint64(uint64_t data) {
void HashKey::Hasher::hashUint64(uint64_t data) {
_hash += squirrel3_64(data, ++_hashCount);
}
void HashKey::hashFloat(float data) {
void HashKey::Hasher::hashFloat(float data) {
_hash += squirrel3_64((uint64_t)((int64_t)(data * QUANTIZED_VALUES_PER_METER)), ++_hashCount);
}
void HashKey::hashVec3(const glm::vec3& data) {
void HashKey::Hasher::hashVec3(const glm::vec3& data) {
_hash += squirrel3_64((uint64_t)((int64_t)(data[0] * QUANTIZED_VALUES_PER_METER)), ++_hashCount);
_hash *= squirrel3_64((uint64_t)((int64_t)(data[1] * QUANTIZED_VALUES_PER_METER)), ++_hashCount);
_hash ^= squirrel3_64((uint64_t)((int64_t)(data[2] * QUANTIZED_VALUES_PER_METER)), ++_hashCount);

View file

@ -30,6 +30,18 @@
class HashKey {
public:
class Hasher {
public:
Hasher() {}
void hashUint64(uint64_t data);
void hashFloat(float data);
void hashVec3(const glm::vec3& data);
uint64_t getHash64() const { return _hash; }
private:
uint64_t _hash { 0 };
uint8_t _hashCount { 0 };
};
static float getNumQuantizedValuesPerMeter();
HashKey() {}
@ -39,16 +51,9 @@ public:
bool equals(const HashKey& other) const { return _hash == other._hash; }
int32_t getHash() const { return (int32_t)((uint32_t)_hash); }
// 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; }
private:
uint64_t _hash { 0 };
uint8_t _hashCount { 0 };
};
#endif // hifi_HashKey_h

View file

@ -273,18 +273,18 @@ float ShapeInfo::computeVolume() 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 (_hash64 == 0 && _type != SHAPE_TYPE_NONE) {
HashKey hashKey;
HashKey::Hasher hasher;
// The key is not yet cached therefore we must compute it.
hashKey.hashUint64((uint64_t)_type);
hasher.hashUint64((uint64_t)_type);
if (_type == SHAPE_TYPE_MULTISPHERE) {
for (auto &sphereData : _sphereCollection) {
hashKey.hashVec3(glm::vec3(sphereData));
hashKey.hashFloat(sphereData.w);
hasher.hashVec3(glm::vec3(sphereData));
hasher.hashFloat(sphereData.w);
}
} else if (_type != SHAPE_TYPE_SIMPLE_HULL) {
hashKey.hashVec3(_halfExtents);
hashKey.hashVec3(_offset);
hasher.hashVec3(_halfExtents);
hasher.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
@ -294,7 +294,7 @@ uint64_t ShapeInfo::getHash() const {
const int numPoints = (int)points.size();
for (int i = 0; i < numPoints; ++i) {
hashKey.hashVec3(points[i]);
hasher.hashVec3(points[i]);
}
}
@ -302,19 +302,19 @@ uint64_t ShapeInfo::getHash() const {
if (!url.isEmpty()) {
QByteArray baUrl = url.toLocal8Bit();
uint32_t urlHash = qChecksum(baUrl.data(), baUrl.size());
hashKey.hashUint64((uint64_t)urlHash);
hasher.hashUint64((uint64_t)urlHash);
}
if (_type == SHAPE_TYPE_COMPOUND || _type == SHAPE_TYPE_SIMPLE_COMPOUND) {
uint64_t numHulls = (uint64_t)_pointCollection.size();
hashKey.hashUint64(numHulls);
hasher.hashUint64(numHulls);
} else if (_type == SHAPE_TYPE_MULTISPHERE) {
uint64_t numSpheres = (uint64_t)_sphereCollection.size();
hashKey.hashUint64(numSpheres);
hasher.hashUint64(numSpheres);
} else if (_type == SHAPE_TYPE_SIMPLE_HULL) {
hashKey.hashUint64(1);
hasher.hashUint64(1);
}
_hash64 = hashKey.getHash64();
_hash64 = hasher.getHash64();
}
return _hash64;
}