From c032b29633db7f2313ce35072586459f196070aa Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 18 Mar 2015 16:29:57 -0700 Subject: [PATCH] proper shape management for ConvexHull shapes --- .../src/RenderableModelEntityItem.cpp | 2 +- libraries/physics/src/PhysicsEngine.cpp | 4 +- libraries/shared/src/ShapeInfo.cpp | 120 ++++++------------ libraries/shared/src/ShapeInfo.h | 6 +- 4 files changed, 43 insertions(+), 89 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 7e57323d68..210fa70b65 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -303,7 +303,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { _points << mesh.vertices; } - info.setParams(getShapeType(), 0.5f * getDimensions(), NULL, _collisionModelURL); + info.setParams(getShapeType(), 0.5f * getDimensions(), _collisionModelURL); info.setConvexHull(_points); } } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 3f5921a6bb..a2420e0572 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -505,10 +505,8 @@ void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { btRigidBody* body = motionState->getRigidBody(); if (body) { const btCollisionShape* shape = body->getCollisionShape(); - ShapeInfo shapeInfo; - ShapeInfoUtil::collectInfoFromShape(shape, shapeInfo); _dynamicsWorld->removeRigidBody(body); - _shapeManager.releaseShape(shapeInfo); + _shapeManager.releaseShape(shape); // NOTE: setRigidBody() modifies body->m_userPointer so we should clear the MotionState's body BEFORE deleting it. motionState->setRigidBody(NULL); delete body; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index d92decad2a..61432830e7 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -19,10 +19,9 @@ void ShapeInfo::clear() { _type = SHAPE_TYPE_NONE; _halfExtents = glm::vec3(0.0f); _doubleHashKey.clear(); - _externalData = NULL; } -void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QVector* data, QString url) { +void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) { _type = type; switch(type) { case SHAPE_TYPE_NONE: @@ -45,7 +44,6 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QVector< _halfExtents = halfExtents; break; } - _externalData = data; } void ShapeInfo::setBox(const glm::vec3& halfExtents) { @@ -109,91 +107,53 @@ float ShapeInfo::computeVolume() const { } const DoubleHashKey& ShapeInfo::getHash() const { - // NOTE: we cache the hash so we only ever need to compute it once for any valid ShapeInfo instance. + // NOTE: we cache the key so we only ever need to compute it once for any valid ShapeInfo instance. if (_doubleHashKey.isNull() && _type != SHAPE_TYPE_NONE) { - // cast this to non-const pointer so we can do our dirty work + // The key is not yet cached therefore we must compute it! To this end we bypass the const-ness + // of this method by grabbing a non-const pointer to "this" and a non-const reference to _doubleHashKey. ShapeInfo* thisPtr = const_cast(this); + DoubleHashKey& key = thisPtr->_doubleHashKey; + // compute hash1 // TODO?: provide lookup table for hash/hash2 of _type rather than recompute? uint32_t primeIndex = 0; - thisPtr->_doubleHashKey.computeHash((uint32_t)_type, primeIndex++); + key.computeHash((uint32_t)_type, primeIndex++); - const QVector* data = getData(); - if (data) { - // if externalData exists we use it to continue the hash - - // compute hash - uint32_t hash = _doubleHashKey.getHash(); + // compute hash1 + uint32_t hash = key.getHash(); + for (int j = 0; j < 3; ++j) { + // NOTE: 0.49f is used to bump the float up almost half a millimeter + // so the cast to int produces a round() effect rather than a floor() + uint32_t floatHash = + DoubleHashKey::hashFunction((uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f), primeIndex++); + hash ^= floatHash; + } + key.setHash(hash); - glm::vec3 tmpData; - int numData = data->size(); - for (int i = 0; i < numData; ++i) { - tmpData = (*data)[i]; - for (int j = 0; j < 3; ++j) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - uint32_t floatHash = - DoubleHashKey::hashFunction((uint32_t)(tmpData[j] * MILLIMETERS_PER_METER + copysignf(1.0f, tmpData[j]) * 0.49f), primeIndex++); - hash ^= floatHash; - } - } - thisPtr->_doubleHashKey.setHash(hash); - - // compute hash2 + // compute hash2 + hash = key.getHash2(); + for (int j = 0; j < 3; ++j) { + // NOTE: 0.49f is used to bump the float up almost half a millimeter + // so the cast to int produces a round() effect rather than a floor() + uint32_t floatHash = + DoubleHashKey::hashFunction2((uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f)); + hash += ~(floatHash << 17); + hash ^= (floatHash >> 11); + hash += (floatHash << 4); + hash ^= (floatHash >> 7); + hash += ~(floatHash << 10); + hash = (hash << 16) | (hash >> 16); + } + key.setHash2(hash); - QString url = _url.toString(); - - if (url == "") { - hash = _doubleHashKey.getHash2(); - for (int i = 0; i < numData; ++i) { - tmpData = (*data)[i]; - for (int j = 0; j < 3; ++j) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - uint32_t floatHash = - DoubleHashKey::hashFunction2((uint32_t)(tmpData[j] * MILLIMETERS_PER_METER + copysignf(1.0f, tmpData[j]) * 0.49f)); - hash += ~(floatHash << 17); - hash ^= (floatHash >> 11); - hash += (floatHash << 4); - hash ^= (floatHash >> 7); - hash += ~(floatHash << 10); - hash = (hash << 16) | (hash >> 16); - } - } - } else { - QByteArray baUrl = url.toLocal8Bit(); - const char *cUrl = baUrl.data(); - hash = qChecksum(cUrl, baUrl.count()); - } - thisPtr->_doubleHashKey.setHash2(hash); - } else { - // this shape info has no external data so type+extents should be enough to generate a unique hash - // compute hash1 - uint32_t hash = _doubleHashKey.getHash(); - for (int j = 0; j < 3; ++j) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - uint32_t floatHash = - DoubleHashKey::hashFunction((uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f), primeIndex++); - hash ^= floatHash; - } - thisPtr->_doubleHashKey.setHash(hash); - - // compute hash2 - hash = _doubleHashKey.getHash2(); - for (int j = 0; j < 3; ++j) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - uint32_t floatHash = - DoubleHashKey::hashFunction2((uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f)); - hash += ~(floatHash << 17); - hash ^= (floatHash >> 11); - hash += (floatHash << 4); - hash ^= (floatHash >> 7); - hash += ~(floatHash << 10); - hash = (hash << 16) | (hash >> 16); - } - thisPtr->_doubleHashKey.setHash2(hash); + QString url = _url.toString(); + if (!url.isEmpty()) { + // fold the urlHash into both parts + QByteArray baUrl = url.toLocal8Bit(); + const char *cUrl = baUrl.data(); + uint32_t urlHash = qChecksum(cUrl, baUrl.count()); + key.setHash(key.getHash() ^ urlHash); + key.setHash2(key.getHash2() ^ urlHash); } } return _doubleHashKey; diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index ff0b5ca8ff..0a55f7c51d 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -40,7 +40,7 @@ class ShapeInfo { public: void clear(); - void setParams(ShapeType type, const glm::vec3& halfExtents, QVector* data = NULL, QString url=""); + void setParams(ShapeType type, const glm::vec3& halfExtents, QString url=""); void setBox(const glm::vec3& halfExtents); void setSphere(float radius); void setEllipsoid(const glm::vec3& halfExtents); @@ -51,9 +51,6 @@ public: const glm::vec3& getHalfExtents() const { return _halfExtents; } - void setData(const QVector* data) { _externalData = data; } - const QVector* getData() const { return _externalData; } - const QVector& getPoints() const { return _points; } void clearPoints () { _points.clear(); } @@ -67,7 +64,6 @@ protected: ShapeType _type = SHAPE_TYPE_NONE; glm::vec3 _halfExtents = glm::vec3(0.0f); DoubleHashKey _doubleHashKey; - const QVector* _externalData = NULL; QVector _points; // points for convex collision hull QUrl _url; // url for model of convex collision hull };