mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
Merge pull request #4474 from AndrewMeadows/thermonuclear
proper shape management for ConvexHull shapes
This commit is contained in:
commit
f800b29682
4 changed files with 43 additions and 89 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<glm::vec3>* 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<ShapeInfo*>(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<glm::vec3>* 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;
|
||||
|
|
|
@ -40,7 +40,7 @@ class ShapeInfo {
|
|||
public:
|
||||
void clear();
|
||||
|
||||
void setParams(ShapeType type, const glm::vec3& halfExtents, QVector<glm::vec3>* 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<glm::vec3>* data) { _externalData = data; }
|
||||
const QVector<glm::vec3>* getData() const { return _externalData; }
|
||||
|
||||
const QVector<glm::vec3>& 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<glm::vec3>* _externalData = NULL;
|
||||
QVector<glm::vec3> _points; // points for convex collision hull
|
||||
QUrl _url; // url for model of convex collision hull
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue