mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 22:07:34 +02:00
split ShapeInfo into shared and physics parts
This commit is contained in:
parent
e6a9081184
commit
919214b7cb
11 changed files with 230 additions and 203 deletions
|
@ -18,6 +18,8 @@ public:
|
|||
static unsigned int hashFunction(unsigned int value, int primeIndex);
|
||||
static unsigned int hashFunction2(unsigned int value);
|
||||
|
||||
DoubleHashKey() : _hash(0), _hash2(0) { }
|
||||
|
||||
DoubleHashKey(unsigned int value, int primeIndex = 0) :
|
||||
_hash(hashFunction(value, primeIndex)),
|
||||
_hash2(hashFunction2(value)) {
|
||||
|
@ -29,10 +31,6 @@ public:
|
|||
|
||||
unsigned int getHash() const { return (unsigned int)_hash; }
|
||||
|
||||
protected:
|
||||
// the default ctor is protected so that only derived classes can use it
|
||||
DoubleHashKey() : _hash(0), _hash2(0) { }
|
||||
|
||||
int _hash;
|
||||
int _hash2;
|
||||
};
|
||||
|
|
|
@ -107,13 +107,9 @@ void EntityMotionState::applyGravity() const {
|
|||
}
|
||||
|
||||
void EntityMotionState::computeShapeInfo(ShapeInfo& info) {
|
||||
#ifdef USE_BULLET_PHYSICS
|
||||
// HACK: for now we make everything a box.
|
||||
glm::vec3 halfExtents = 0.5f * _entity->getDimensionsInMeters();
|
||||
btVector3 bulletHalfExtents;
|
||||
glmToBullet(halfExtents, bulletHalfExtents);
|
||||
info.setBox(bulletHalfExtents);
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
info.setBox(halfExtents);
|
||||
}
|
||||
|
||||
void EntityMotionState::getBoundingCubes(AACube& oldCube, AACube& newCube) {
|
||||
|
|
|
@ -9,80 +9,133 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <Shape.h> // for FOO_SHAPE types
|
||||
#include <SharedUtil.h> // for MILLIMETERS_PER_METER
|
||||
|
||||
#include "ShapeInfoUtil.h"
|
||||
#include "BulletUtil.h"
|
||||
|
||||
#ifdef USE_BULLET_PHYSICS
|
||||
|
||||
|
||||
int ShapeInfoUtil::toBulletShapeType(int shapeInfoType) {
|
||||
int bulletShapeType = INVALID_SHAPE_PROXYTYPE;
|
||||
switch(shapeInfoType) {
|
||||
case BOX_SHAPE:
|
||||
bulletShapeType = BOX_SHAPE_PROXYTYPE;
|
||||
break;
|
||||
case SPHERE_SHAPE:
|
||||
bulletShapeType = SPHERE_SHAPE_PROXYTYPE;
|
||||
break;
|
||||
case CAPSULE_SHAPE:
|
||||
bulletShapeType = CAPSULE_SHAPE_PROXYTYPE;
|
||||
break;
|
||||
case CYLINDER_SHAPE:
|
||||
bulletShapeType = CYLINDER_SHAPE_PROXYTYPE;
|
||||
break;
|
||||
}
|
||||
return bulletShapeType;
|
||||
}
|
||||
|
||||
int ShapeInfoUtil::fromBulletShapeType(int bulletShapeType) {
|
||||
int shapeInfoType = INVALID_SHAPE;
|
||||
switch(bulletShapeType) {
|
||||
case BOX_SHAPE_PROXYTYPE:
|
||||
shapeInfoType = BOX_SHAPE;
|
||||
break;
|
||||
case SPHERE_SHAPE_PROXYTYPE:
|
||||
shapeInfoType = SPHERE_SHAPE;
|
||||
break;
|
||||
case CAPSULE_SHAPE_PROXYTYPE:
|
||||
shapeInfoType = CAPSULE_SHAPE;
|
||||
break;
|
||||
case CYLINDER_SHAPE_PROXYTYPE:
|
||||
shapeInfoType = CYLINDER_SHAPE;
|
||||
break;
|
||||
}
|
||||
return shapeInfoType;
|
||||
}
|
||||
|
||||
void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInfo& info) {
|
||||
info._data.clear();
|
||||
if (shape) {
|
||||
info._type = (unsigned int)(shape->getShapeType());
|
||||
switch(_type) {
|
||||
case BOX_SHAPE_PROXYTYPE:
|
||||
info._type = ShapeInfoUtil::fromBulletShapeType(shape->getShapeType());
|
||||
switch(info._type) {
|
||||
case BOX_SHAPE:
|
||||
{
|
||||
const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
|
||||
info._data.push_back(boxShape->getHalfExtentsWithMargin());
|
||||
glm::vec3 halfExtents;
|
||||
bulletToGLM(boxShape->getHalfExtentsWithMargin(), halfExtents);
|
||||
info._data.push_back(halfExtents);
|
||||
}
|
||||
break;
|
||||
case SPHERE_SHAPE_PROXYTYPE:
|
||||
case SPHERE_SHAPE:
|
||||
{
|
||||
const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
|
||||
info._data.push_back(btVector3(0.0f, 0.0f, sphereShape->getRadius()));
|
||||
glm::vec3 data;
|
||||
bulletToGLM(btVector3(0.0f, 0.0f, sphereShape->getRadius()), data);
|
||||
info._data.push_back(data);
|
||||
}
|
||||
break;
|
||||
case CYLINDER_SHAPE_PROXYTYPE:
|
||||
case CYLINDER_SHAPE:
|
||||
{
|
||||
const btCylinderShape* cylinderShape = static_cast<const btCylinderShape*>(shape);
|
||||
info._data.push_back(cylinderShape->getHalfExtentsWithMargin());
|
||||
glm::vec3 halfExtents;
|
||||
bulletToGLM(cylinderShape->getHalfExtentsWithMargin(), halfExtents);
|
||||
info._data.push_back(halfExtents);
|
||||
}
|
||||
break;
|
||||
case CAPSULE_SHAPE_PROXYTYPE:
|
||||
case CAPSULE_SHAPE:
|
||||
{
|
||||
const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
|
||||
info._data.push_back(btVector3(capsuleShape->getRadius(), capsuleShape->getHalfHeight(), 0.0f));
|
||||
glm::vec3 data;
|
||||
bulletToGLM(btVector3(capsuleShape->getRadius(), capsuleShape->getHalfHeight(), 0.0f), data);
|
||||
info._data.push_back(data);
|
||||
// NOTE: we only support capsules with axis along yAxis
|
||||
}
|
||||
break;
|
||||
default:
|
||||
info._type = INVALID_SHAPE_PROXYTYPE;
|
||||
info._type = INVALID_SHAPE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
info._type = INVALID_SHAPE_PROXYTYPE;
|
||||
info._type = INVALID_SHAPE;
|
||||
}
|
||||
}
|
||||
|
||||
btCollisionShape* ShapeInfoUtil::createShape(const ShapeInfo& info) {
|
||||
btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) {
|
||||
btCollisionShape* shape = NULL;
|
||||
int numData = info._data.size();
|
||||
switch(info._type) {
|
||||
case BOX_SHAPE_PROXYTYPE: {
|
||||
case BOX_SHAPE: {
|
||||
if (numData > 0) {
|
||||
btVector3 halfExtents = info._data[0];
|
||||
btVector3 halfExtents;
|
||||
glmToBullet(info._data[0], halfExtents);
|
||||
shape = new btBoxShape(halfExtents);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SPHERE_SHAPE_PROXYTYPE: {
|
||||
case SPHERE_SHAPE: {
|
||||
if (numData > 0) {
|
||||
float radius = info._data[0].getZ();
|
||||
float radius = info._data[0].z;
|
||||
shape = new btSphereShape(radius);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CYLINDER_SHAPE_PROXYTYPE: {
|
||||
case CYLINDER_SHAPE: {
|
||||
if (numData > 0) {
|
||||
btVector3 halfExtents = info._data[0];
|
||||
btVector3 halfExtents;
|
||||
glmToBullet(info._data[0], halfExtents);
|
||||
// NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X
|
||||
// halfExtents = btVector3(radius, halfHeight, unused)
|
||||
shape = new btCylinderShape(halfExtents);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAPSULE_SHAPE_PROXYTYPE: {
|
||||
case CAPSULE_SHAPE: {
|
||||
if (numData > 0) {
|
||||
float radius = info._data[0].getX();
|
||||
float height = 2.0f * info._data[0].getY();
|
||||
float radius = info._data[0].x;
|
||||
float height = 2.0f * info._data[0].y;
|
||||
shape = new btCapsuleShape(radius, height);
|
||||
}
|
||||
}
|
||||
|
@ -91,4 +144,50 @@ btCollisionShape* ShapeInfoUtil::createShape(const ShapeInfo& info) {
|
|||
return shape;
|
||||
}
|
||||
|
||||
DoubleHashKey ShapeInfoUtil::computeHash(const ShapeInfo& info) {
|
||||
DoubleHashKey key;
|
||||
// compute hash
|
||||
// scramble the bits of the type
|
||||
// TODO?: provide lookup table for hash of info._type rather than recompute?
|
||||
int primeIndex = 0;
|
||||
unsigned int hash = DoubleHashKey::hashFunction((unsigned int)info._type, primeIndex++);
|
||||
|
||||
glm::vec3 tmpData;
|
||||
int numData = info._data.size();
|
||||
for (int i = 0; i < numData; ++i) {
|
||||
tmpData = info._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()
|
||||
unsigned int floatHash =
|
||||
DoubleHashKey::hashFunction((int)(tmpData[j] * MILLIMETERS_PER_METER + copysignf(1.0f, tmpData[j]) * 0.49f), primeIndex++);
|
||||
hash ^= floatHash;
|
||||
}
|
||||
}
|
||||
key._hash = (int)hash;
|
||||
|
||||
// compute hash2
|
||||
// scramble the bits of the type
|
||||
// TODO?: provide lookup table for hash2 of info._type rather than recompute?
|
||||
hash = DoubleHashKey::hashFunction2((unsigned int)info._type);
|
||||
|
||||
for (int i = 0; i < numData; ++i) {
|
||||
tmpData = info._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()
|
||||
unsigned int floatHash =
|
||||
DoubleHashKey::hashFunction2((int)(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);
|
||||
}
|
||||
}
|
||||
key._hash2 = (int)hash;
|
||||
return key;
|
||||
}
|
||||
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
|
|
|
@ -19,12 +19,20 @@
|
|||
|
||||
#include <ShapeInfo.h>
|
||||
|
||||
#include "DoubleHashKey.h"
|
||||
|
||||
// translates between ShapeInfo and btShape
|
||||
|
||||
namespace ShapeInfoUtil {
|
||||
void collectInfoFromShape(const btCollisionShape* shape, ShapeInfo& info);
|
||||
|
||||
btCollisionShape* createShapeFromInfo(const ShapeInfo& info);
|
||||
|
||||
DoubleHashKey computeHash(const ShapeInfo& info);
|
||||
|
||||
// TODO? just use bullet shape types everywhere?
|
||||
int toBulletShapeType(int shapeInfoType);
|
||||
int fromBulletShapeType(int bulletShapeType);
|
||||
};
|
||||
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
|
|
|
@ -27,7 +27,7 @@ ShapeManager::~ShapeManager() {
|
|||
|
||||
|
||||
btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) {
|
||||
ShapeKey key(info);
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
ShapeReference* shapeRef = _shapeMap.find(key);
|
||||
if (shapeRef) {
|
||||
shapeRef->_refCount++;
|
||||
|
@ -45,7 +45,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) {
|
|||
}
|
||||
|
||||
bool ShapeManager::releaseShape(const ShapeInfo& info) {
|
||||
ShapeKey key(info);
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
ShapeReference* shapeRef = _shapeMap.find(key);
|
||||
if (shapeRef) {
|
||||
if (shapeRef->_refCount > 0) {
|
||||
|
@ -70,14 +70,15 @@ bool ShapeManager::releaseShape(const ShapeInfo& info) {
|
|||
}
|
||||
|
||||
bool ShapeManager::releaseShape(const btCollisionShape* shape) {
|
||||
ShapeInfo info(shape);
|
||||
ShapeInfo info;
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, info);
|
||||
return releaseShape(info);
|
||||
}
|
||||
|
||||
void ShapeManager::collectGarbage() {
|
||||
int numShapes = _pendingGarbage.size();
|
||||
for (int i = 0; i < numShapes; ++i) {
|
||||
ShapeKey& key = _pendingGarbage[i];
|
||||
DoubleHashKey& key = _pendingGarbage[i];
|
||||
ShapeReference* shapeRef = _shapeMap.find(key);
|
||||
if (shapeRef && shapeRef->_refCount == 0) {
|
||||
delete shapeRef->_shape;
|
||||
|
@ -88,7 +89,7 @@ void ShapeManager::collectGarbage() {
|
|||
}
|
||||
|
||||
int ShapeManager::getNumReferences(const ShapeInfo& info) const {
|
||||
ShapeKey key(info);
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
const ShapeReference* shapeRef = _shapeMap.find(key);
|
||||
if (shapeRef) {
|
||||
return shapeRef->_refCount;
|
||||
|
|
|
@ -17,17 +17,9 @@
|
|||
#include <btBulletDynamicsCommon.h>
|
||||
#include <LinearMath/btHashMap.h>
|
||||
|
||||
#include "DoubleHashKey.h"
|
||||
#include "ShapeInfo.h"
|
||||
#include <ShapeInfo.h>
|
||||
|
||||
class ShapeKey : public DoubleHashKey
|
||||
{
|
||||
public:
|
||||
ShapeKey(const ShapeInfo& info) : DoubleHashKey() {
|
||||
_hash = info.computeHash();
|
||||
_hash2 = info.computeHash2();
|
||||
}
|
||||
};
|
||||
#include "DoubleHashKey.h"
|
||||
|
||||
class ShapeManager {
|
||||
public:
|
||||
|
@ -56,8 +48,8 @@ private:
|
|||
ShapeReference() : _refCount(0), _shape(NULL) {}
|
||||
};
|
||||
|
||||
btHashMap<ShapeKey, ShapeReference> _shapeMap;
|
||||
btAlignedObjectArray<ShapeKey> _pendingGarbage;
|
||||
btHashMap<DoubleHashKey, ShapeReference> _shapeMap;
|
||||
btAlignedObjectArray<DoubleHashKey> _pendingGarbage;
|
||||
};
|
||||
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
|
|
|
@ -25,12 +25,15 @@ class VerletPoint;
|
|||
|
||||
const float MAX_SHAPE_MASS = 1.0e18f; // something less than sqrt(FLT_MAX)
|
||||
|
||||
const quint8 SPHERE_SHAPE = 0;
|
||||
const quint8 CAPSULE_SHAPE = 1;
|
||||
const quint8 PLANE_SHAPE = 2;
|
||||
const quint8 AACUBE_SHAPE = 3;
|
||||
const quint8 LIST_SHAPE = 4;
|
||||
const quint8 UNKNOWN_SHAPE = 5;
|
||||
const quint8 UNKNOWN_SHAPE = 0;
|
||||
const quint8 INVALID_SHAPE = 0;
|
||||
const quint8 SPHERE_SHAPE = 1;
|
||||
const quint8 CAPSULE_SHAPE = 2;
|
||||
const quint8 PLANE_SHAPE = 3;
|
||||
const quint8 BOX_SHAPE = 4;
|
||||
const quint8 AACUBE_SHAPE = 5;
|
||||
const quint8 CYLINDER_SHAPE = 6;
|
||||
const quint8 LIST_SHAPE = 7;
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
|
|
|
@ -9,91 +9,36 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifdef USE_BULLET_PHYSICS
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <SharedUtil.h> // for MILLIMETERS_PER_METER
|
||||
#include "SharedUtil.h" // for MILLIMETERS_PER_METER
|
||||
#include "StreamUtils.h" // adebug
|
||||
|
||||
#include "BulletUtil.h"
|
||||
#include "DoubleHashKey.h"
|
||||
//#include "DoubleHashKey.h"
|
||||
#include "ShapeInfo.h"
|
||||
|
||||
void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
||||
_type = BOX_SHAPE_PROXYTYPE;
|
||||
_type = BOX_SHAPE;
|
||||
_data.clear();
|
||||
_data.push_back(halfExtents);
|
||||
}
|
||||
|
||||
void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
||||
_type = BOX_SHAPE_PROXYTYPE;
|
||||
_data.clear();
|
||||
_data.push_back(bulletHalfExtents);
|
||||
}
|
||||
|
||||
void ShapeInfo::setSphere(float radius) {
|
||||
_type = SPHERE_SHAPE_PROXYTYPE;
|
||||
_type = SPHERE_SHAPE;
|
||||
_data.clear();
|
||||
_data.push_back(glm::vec3(0.0f, 0.0f, radius));
|
||||
}
|
||||
|
||||
void ShapeInfo::setCylinder(float radius, float height) {
|
||||
_type = CYLINDER_SHAPE_PROXYTYPE;
|
||||
_type = CYLINDER_SHAPE;
|
||||
_data.clear();
|
||||
// NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X
|
||||
_data.push_back(glm::vec3btVector3(radius, 0.5f * height, radius));
|
||||
_data.push_back(glm::vec3(radius, 0.5f * height, radius));
|
||||
}
|
||||
|
||||
void ShapeInfo::setCapsule(float radius, float height) {
|
||||
_type = CAPSULE_SHAPE_PROXYTYPE;
|
||||
_type = CAPSULE_SHAPE;
|
||||
_data.clear();
|
||||
_data.push_back(glm::vec3(radius, 0.5f * height, 0.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 = DoubleHashKey::hashFunction((unsigned int)_type, primeIndex++);
|
||||
|
||||
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()
|
||||
unsigned int floatHash =
|
||||
DoubleHashKey::hashFunction((int)(tmpData[j] * MILLIMETERS_PER_METER + copysignf(1.0f, tmpData[j]) * 0.49f), primeIndex++);
|
||||
hash ^= floatHash;
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
int ShapeInfo::computeHash2() const {
|
||||
// scramble the bits of the type
|
||||
// TODO?: provide lookup table for hash of _type?
|
||||
unsigned int hash = DoubleHashKey::hashFunction2((unsigned int)_type);
|
||||
|
||||
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()
|
||||
unsigned int floatHash =
|
||||
DoubleHashKey::hashFunction2((int)(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);
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
|
|
|
@ -12,30 +12,23 @@
|
|||
#ifndef hifi_ShapeInfo_h
|
||||
#define hifi_ShapeInfo_h
|
||||
|
||||
#ifdef USE_BULLET_PHYSICS
|
||||
|
||||
//#include <btBulletDynamicsCommon.h>
|
||||
#include <QVector>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Shape.h"
|
||||
|
||||
class ShapeInfo {
|
||||
public:
|
||||
ShapeInfo() : _type(INVALID_SHAPE_PROXYTYPE) {}
|
||||
ShapeInfo() : _type(INVALID_SHAPE) {}
|
||||
|
||||
|
||||
void setBox(const btVector3& halfExtents);
|
||||
void setBox(const glm::vec3& halfExtents);
|
||||
void setSphere(float radius);
|
||||
void setCylinder(float radius, float height);
|
||||
void setCapsule(float radius, float height);
|
||||
|
||||
int computeHash() const;
|
||||
int computeHash2() const;
|
||||
|
||||
int _type;
|
||||
QVector<glm::vec3> _data;
|
||||
};
|
||||
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
#endif // hifi_ShapeInfo_h
|
||||
|
||||
|
|
|
@ -10,7 +10,13 @@
|
|||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <LinearMath/btHashMap.h>
|
||||
|
||||
#include <DoubleHashKey.h>
|
||||
#include <ShapeInfo.h>
|
||||
#include <ShapeInfoUtil.h>
|
||||
#include <StreamUtils.h>
|
||||
|
||||
#include "ShapeInfoTests.h"
|
||||
|
@ -40,21 +46,20 @@ void ShapeInfoTests::testHashFunctions() {
|
|||
// test sphere
|
||||
info.setSphere(radiusX);
|
||||
++testCount;
|
||||
int hash = info.computeHash();
|
||||
int hash2 = info.computeHash2();
|
||||
int* hashPtr = hashes.find(hash);
|
||||
if (hashPtr && *hashPtr == hash2) {
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
int* hashPtr = hashes.find(key._hash);
|
||||
if (hashPtr && *hashPtr == key._hash2) {
|
||||
std::cout << testCount << " hash collision radiusX = " << radiusX
|
||||
<< " h1 = 0x" << std::hex << (unsigned int)(hash)
|
||||
<< " h2 = 0x" << std::hex << (unsigned int)(hash2)
|
||||
<< " h1 = 0x" << std::hex << (unsigned int)(key._hash)
|
||||
<< " h2 = 0x" << std::hex << (unsigned int)(key._hash2)
|
||||
<< std::endl;
|
||||
++numCollisions;
|
||||
assert(false);
|
||||
} else {
|
||||
hashes.insert(hash, hash2);
|
||||
hashes.insert(key._hash, key._hash2);
|
||||
}
|
||||
for (int k = 0; k < 32; ++k) {
|
||||
if (masks[k] & hash2) {
|
||||
if (masks[k] & key._hash2) {
|
||||
++bits[k];
|
||||
}
|
||||
}
|
||||
|
@ -76,21 +81,20 @@ void ShapeInfoTests::testHashFunctions() {
|
|||
}
|
||||
|
||||
++testCount;
|
||||
hash = info.computeHash();
|
||||
hash2 = info.computeHash2();
|
||||
hashPtr = hashes.find(hash);
|
||||
if (hashPtr && *hashPtr == hash2) {
|
||||
key = ShapeInfoUtil::computeHash(info);
|
||||
hashPtr = hashes.find(key._hash);
|
||||
if (hashPtr && *hashPtr == key._hash2) {
|
||||
std::cout << testCount << " hash collision radiusX = " << radiusX << " radiusY = " << radiusY
|
||||
<< " h1 = 0x" << std::hex << (unsigned int)(hash)
|
||||
<< " h2 = 0x" << std::hex << (unsigned int)(hash2)
|
||||
<< " h1 = 0x" << std::hex << (unsigned int)(key._hash)
|
||||
<< " h2 = 0x" << std::hex << (unsigned int)(key._hash2)
|
||||
<< std::endl;
|
||||
++numCollisions;
|
||||
assert(false);
|
||||
} else {
|
||||
hashes.insert(hash, hash2);
|
||||
hashes.insert(key._hash, key._hash2);
|
||||
}
|
||||
for (int k = 0; k < 32; ++k) {
|
||||
if (masks[k] & hash2) {
|
||||
if (masks[k] & key._hash2) {
|
||||
++bits[k];
|
||||
}
|
||||
}
|
||||
|
@ -99,24 +103,23 @@ void ShapeInfoTests::testHashFunctions() {
|
|||
for (int z = 1; z < numSteps && testCount < maxTests; ++z) {
|
||||
float radiusZ = (float)z * deltaLength;
|
||||
// test box
|
||||
info.setBox(btVector3(radiusX, radiusY, radiusZ));
|
||||
info.setBox(glm::vec3(radiusX, radiusY, radiusZ));
|
||||
++testCount;
|
||||
hash = info.computeHash();
|
||||
hash2 = info.computeHash2();
|
||||
hashPtr = hashes.find(hash);
|
||||
if (hashPtr && *hashPtr == hash2) {
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
hashPtr = hashes.find(key._hash);
|
||||
if (hashPtr && *hashPtr == key._hash2) {
|
||||
std::cout << testCount << " hash collision radiusX = " << radiusX
|
||||
<< " radiusY = " << radiusY << " radiusZ = " << radiusZ
|
||||
<< " h1 = 0x" << std::hex << (unsigned int)(hash)
|
||||
<< " h2 = 0x" << std::hex << (unsigned int)(hash2)
|
||||
<< " h1 = 0x" << std::hex << (unsigned int)(key._hash)
|
||||
<< " h2 = 0x" << std::hex << (unsigned int)(key._hash2)
|
||||
<< std::endl;
|
||||
++numCollisions;
|
||||
assert(false);
|
||||
} else {
|
||||
hashes.insert(hash, hash2);
|
||||
hashes.insert(key._hash, key._hash2);
|
||||
}
|
||||
for (int k = 0; k < 32; ++k) {
|
||||
if (masks[k] & hash2) {
|
||||
if (masks[k] & key._hash2) {
|
||||
++bits[k];
|
||||
}
|
||||
}
|
||||
|
@ -136,29 +139,27 @@ void ShapeInfoTests::testHashFunctions() {
|
|||
void ShapeInfoTests::testBoxShape() {
|
||||
#ifdef USE_BULLET_PHYSICS
|
||||
ShapeInfo info;
|
||||
btVector3 halfExtents(1.23f, 4.56f, 7.89f);
|
||||
glm::vec3 halfExtents(1.23f, 4.56f, 7.89f);
|
||||
info.setBox(halfExtents);
|
||||
int hash = info.computeHash();
|
||||
int hash2 = info.computeHash2();
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
|
||||
btCollisionShape* shape = info.createShape();
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
if (!shape) {
|
||||
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: NULL Box shape" << std::endl;
|
||||
}
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
otherInfo.collectInfo(shape);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
int otherHash = otherInfo.computeHash();
|
||||
if (hash != otherHash) {
|
||||
DoubleHashKey otherKey = ShapeInfoUtil::computeHash(otherInfo);
|
||||
if (key._hash != otherKey._hash) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Box shape hash = " << hash << " but found hash = " << otherHash << std::endl;
|
||||
<< " ERROR: expected Box shape hash = " << key._hash << " but found hash = " << otherKey._hash << std::endl;
|
||||
}
|
||||
|
||||
int otherHash2= otherInfo.computeHash2();
|
||||
if (hash2 != otherHash2) {
|
||||
if (key._hash2 != otherKey._hash2) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Box shape hash2 = " << hash2 << " but found hash2 = " << otherHash2 << std::endl;
|
||||
<< " ERROR: expected Box shape hash2 = " << key._hash2 << " but found hash2 = " << otherKey._hash2 << std::endl;
|
||||
}
|
||||
|
||||
delete shape;
|
||||
|
@ -170,24 +171,21 @@ void ShapeInfoTests::testSphereShape() {
|
|||
ShapeInfo info;
|
||||
float radius = 1.23f;
|
||||
info.setSphere(radius);
|
||||
int hash = info.computeHash();
|
||||
int hash2 = info.computeHash2();
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
|
||||
btCollisionShape* shape = info.createShape();
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
otherInfo.collectInfo(shape);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
int otherHash = otherInfo.computeHash();
|
||||
if (hash != otherHash) {
|
||||
DoubleHashKey otherKey = ShapeInfoUtil::computeHash(otherInfo);
|
||||
if (key._hash != otherKey._hash) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Sphere shape hash = " << hash << " but found hash = " << otherHash << std::endl;
|
||||
<< " ERROR: expected Sphere shape hash = " << key._hash << " but found hash = " << otherKey._hash << std::endl;
|
||||
}
|
||||
|
||||
int otherHash2 = otherInfo.computeHash2();
|
||||
if (hash2 != otherHash2) {
|
||||
if (key._hash2 != otherKey._hash2) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Sphere shape hash2 = " << hash2 << " but found hash2 = " << otherHash2 << std::endl;
|
||||
<< " ERROR: expected Sphere shape hash2 = " << key._hash2 << " but found hash2 = " << otherKey._hash2 << std::endl;
|
||||
}
|
||||
|
||||
delete shape;
|
||||
|
@ -200,24 +198,21 @@ void ShapeInfoTests::testCylinderShape() {
|
|||
float radius = 1.23f;
|
||||
float height = 4.56f;
|
||||
info.setCylinder(radius, height);
|
||||
int hash = info.computeHash();
|
||||
int hash2 = info.computeHash2();
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
|
||||
btCollisionShape* shape = info.createShape();
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
otherInfo.collectInfo(shape);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
int otherHash = otherInfo.computeHash();
|
||||
if (hash != otherHash) {
|
||||
DoubleHashKey otherKey = ShapeInfoUtil::computeHash(otherInfo);
|
||||
if (key._hash != otherKey._hash) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Cylinder shape hash = " << hash << " but found hash = " << otherHash << std::endl;
|
||||
<< " ERROR: expected Cylinder shape hash = " << key._hash << " but found hash = " << otherKey._hash << std::endl;
|
||||
}
|
||||
|
||||
int otherHash2 = otherInfo.computeHash2();
|
||||
if (hash2 != otherHash2) {
|
||||
if (key._hash2 != otherKey._hash2) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Cylinder shape hash2 = " << hash2 << " but found hash2 = " << otherHash2 << std::endl;
|
||||
<< " ERROR: expected Cylinder shape hash2 = " << key._hash2 << " but found hash2 = " << otherKey._hash2 << std::endl;
|
||||
}
|
||||
|
||||
delete shape;
|
||||
|
@ -230,24 +225,21 @@ void ShapeInfoTests::testCapsuleShape() {
|
|||
float radius = 1.23f;
|
||||
float height = 4.56f;
|
||||
info.setCapsule(radius, height);
|
||||
int hash = info.computeHash();
|
||||
int hash2 = info.computeHash2();
|
||||
DoubleHashKey key = ShapeInfoUtil::computeHash(info);
|
||||
|
||||
btCollisionShape* shape = info.createShape();
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
otherInfo.collectInfo(shape);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
int otherHash = otherInfo.computeHash();
|
||||
if (hash != otherHash) {
|
||||
DoubleHashKey otherKey = ShapeInfoUtil::computeHash(otherInfo);
|
||||
if (key._hash != otherKey._hash) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Capsule shape hash = " << hash << " but found hash = " << otherHash << std::endl;
|
||||
<< " ERROR: expected Capsule shape hash = " << key._hash << " but found hash = " << otherKey._hash << std::endl;
|
||||
}
|
||||
|
||||
int otherHash2 = otherInfo.computeHash2();
|
||||
if (hash2 != otherHash2) {
|
||||
if (key._hash2 != otherKey._hash2) {
|
||||
std::cout << __FILE__ << ":" << __LINE__
|
||||
<< " ERROR: expected Capsule shape hash2 = " << hash2 << " but found hash2 = " << otherHash2 << std::endl;
|
||||
<< " ERROR: expected Capsule shape hash2 = " << key._hash2 << " but found hash2 = " << otherKey._hash2 << std::endl;
|
||||
}
|
||||
|
||||
delete shape;
|
||||
|
|
|
@ -20,7 +20,7 @@ void ShapeManagerTests::testShapeAccounting() {
|
|||
#ifdef USE_BULLET_PHYSICS
|
||||
ShapeManager shapeManager;
|
||||
ShapeInfo info;
|
||||
info.setBox(btVector3(1.0f, 1.0f, 1.0f));
|
||||
info.setBox(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
// NOTE: ShapeManager returns -1 as refcount when the shape is unknown,
|
||||
// which is distinct from "known but with zero references"
|
||||
|
@ -132,7 +132,7 @@ void ShapeManagerTests::addManyShapes() {
|
|||
ShapeInfo info;
|
||||
for (int i = 0; i < numSizes; ++i) {
|
||||
float s = startSize + (float)i * deltaSize;
|
||||
btVector3 scale(s, 1.23f + s, s - 0.573f);
|
||||
glm::vec3 scale(s, 1.23f + s, s - 0.573f);
|
||||
info.setBox(0.5f * scale);
|
||||
btCollisionShape* shape = shapeManager.getShape(info);
|
||||
if (!shape) {
|
||||
|
@ -157,14 +157,14 @@ void ShapeManagerTests::addManyShapes() {
|
|||
void ShapeManagerTests::addBoxShape() {
|
||||
#ifdef USE_BULLET_PHYSICS
|
||||
ShapeInfo info;
|
||||
btVector3 halfExtents(1.23f, 4.56f, 7.89f);
|
||||
glm::vec3 halfExtents(1.23f, 4.56f, 7.89f);
|
||||
info.setBox(halfExtents);
|
||||
|
||||
ShapeManager shapeManager;
|
||||
btCollisionShape* shape = shapeManager.getShape(info);
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
collectInfoFromShape(shape, otherInfo);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
|
||||
if (shape != otherShape) {
|
||||
|
@ -184,7 +184,7 @@ void ShapeManagerTests::addSphereShape() {
|
|||
btCollisionShape* shape = shapeManager.getShape(info);
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
collectInfoFromShape(shape, otherInfo);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
|
||||
if (shape != otherShape) {
|
||||
|
@ -205,7 +205,7 @@ void ShapeManagerTests::addCylinderShape() {
|
|||
btCollisionShape* shape = shapeManager.getShape(info);
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
collectInfoFromShape(shape, otherInfo);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
|
||||
if (shape != otherShape) {
|
||||
|
@ -226,7 +226,7 @@ void ShapeManagerTests::addCapsuleShape() {
|
|||
btCollisionShape* shape = shapeManager.getShape(info);
|
||||
|
||||
ShapeInfo otherInfo;
|
||||
collectInfoFromShape(shape, otherInfo);
|
||||
ShapeInfoUtil::collectInfoFromShape(shape, otherInfo);
|
||||
|
||||
btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
|
||||
if (shape != otherShape) {
|
||||
|
|
Loading…
Reference in a new issue