diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index b0e62beac4..6962355d5d 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -12,6 +12,8 @@ #include "PhysicsEngine.h" #ifdef USE_BULLET_PHYSICS +#include "ShapeInfoUtil.h" + PhysicsEngine::~PhysicsEngine() { } @@ -176,7 +178,7 @@ bool PhysicsEngine::removeObject(CustomMotionState* motionState) { if (body) { const btCollisionShape* shape = body->getCollisionShape(); ShapeInfo info; - info.collectInfo(shape); + ShapeInfoUtil::collectInfoFromShape(shape, info); _dynamicsWorld->removeRigidBody(body); _shapeManager.releaseShape(info); delete body; diff --git a/libraries/physics/src/ShapeInfo.cpp b/libraries/physics/src/ShapeInfo.cpp index 5587a6b528..dc53b1eaf3 100644 --- a/libraries/physics/src/ShapeInfo.cpp +++ b/libraries/physics/src/ShapeInfo.cpp @@ -12,7 +12,6 @@ #ifdef USE_BULLET_PHYSICS #include -#include #include // for MILLIMETERS_PER_METER @@ -20,46 +19,7 @@ #include "DoubleHashKey.h" #include "ShapeInfo.h" -void ShapeInfo::collectInfo(const btCollisionShape* shape) { - _data.clear(); - if (shape) { - _type = (unsigned int)(shape->getShapeType()); - switch(_type) { - case BOX_SHAPE_PROXYTYPE: - { - const btBoxShape* boxShape = static_cast(shape); - _data.push_back(boxShape->getHalfExtentsWithMargin()); - } - break; - case SPHERE_SHAPE_PROXYTYPE: - { - const btSphereShape* sphereShape = static_cast(shape); - _data.push_back(btVector3(0.0f, 0.0f, sphereShape->getRadius())); - } - break; - case CYLINDER_SHAPE_PROXYTYPE: - { - const btCylinderShape* cylinderShape = static_cast(shape); - _data.push_back(cylinderShape->getHalfExtentsWithMargin()); - } - break; - case CAPSULE_SHAPE_PROXYTYPE: - { - const btCapsuleShape* capsuleShape = static_cast(shape); - _data.push_back(btVector3(capsuleShape->getRadius(), capsuleShape->getHalfHeight(), 0.0f)); - // NOTE: we only support capsules with axis along yAxis - } - break; - default: - _type = INVALID_SHAPE_PROXYTYPE; - break; - } - } else { - _type = INVALID_SHAPE_PROXYTYPE; - } -} - -void ShapeInfo::setBox(const btVector3& halfExtents) { +void ShapeInfo::setBox(const glm::vec3& halfExtents) { _type = BOX_SHAPE_PROXYTYPE; _data.clear(); _data.push_back(halfExtents); @@ -68,29 +28,26 @@ void ShapeInfo::setBox(const btVector3& halfExtents) { void ShapeInfo::setBox(const glm::vec3& halfExtents) { _type = BOX_SHAPE_PROXYTYPE; _data.clear(); - btVector3 bulletHalfExtents; - glmToBullet(halfExtents, bulletHalfExtents); _data.push_back(bulletHalfExtents); } void ShapeInfo::setSphere(float radius) { _type = SPHERE_SHAPE_PROXYTYPE; _data.clear(); - _data.push_back(btVector3(0.0f, 0.0f, radius)); + _data.push_back(glm::vec3(0.0f, 0.0f, radius)); } void ShapeInfo::setCylinder(float radius, float height) { _type = CYLINDER_SHAPE_PROXYTYPE; _data.clear(); // NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X - // halfExtents = btVector3(radius, halfHeight, unused) - _data.push_back(btVector3(radius, 0.5f * height, radius)); + _data.push_back(glm::vec3btVector3(radius, 0.5f * height, radius)); } void ShapeInfo::setCapsule(float radius, float height) { _type = CAPSULE_SHAPE_PROXYTYPE; _data.clear(); - _data.push_back(btVector3(radius, 0.5f * height, 0.0f)); + _data.push_back(glm::vec3(radius, 0.5f * height, 0.0f)); } int ShapeInfo::computeHash() const { @@ -99,7 +56,7 @@ int ShapeInfo::computeHash() const { int primeIndex = 0; unsigned int hash = DoubleHashKey::hashFunction((unsigned int)_type, primeIndex++); - btVector3 tmpData; + glm::vec3 tmpData; int numData = _data.size(); for (int i = 0; i < numData; ++i) { tmpData = _data[i]; @@ -119,7 +76,7 @@ int ShapeInfo::computeHash2() const { // TODO?: provide lookup table for hash of _type? unsigned int hash = DoubleHashKey::hashFunction2((unsigned int)_type); - btVector3 tmpData; + glm::vec3 tmpData; int numData = _data.size(); for (int i = 0; i < numData; ++i) { tmpData = _data[i]; @@ -139,43 +96,4 @@ int ShapeInfo::computeHash2() const { return hash; } -btCollisionShape* ShapeInfo::createShape() const { - btCollisionShape* shape = NULL; - int numData = _data.size(); - switch(_type) { - case BOX_SHAPE_PROXYTYPE: { - if (numData > 0) { - btVector3 halfExtents = _data[0]; - shape = new btBoxShape(halfExtents); - } - } - break; - case SPHERE_SHAPE_PROXYTYPE: { - if (numData > 0) { - float radius = _data[0].getZ(); - shape = new btSphereShape(radius); - } - } - break; - case CYLINDER_SHAPE_PROXYTYPE: { - if (numData > 0) { - btVector3 halfExtents = _data[0]; - // 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: { - if (numData > 0) { - float radius = _data[0].getX(); - float height = 2.0f * _data[0].getY(); - shape = new btCapsuleShape(radius, height); - } - } - break; - } - return shape; -} - #endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ShapeInfo.h b/libraries/physics/src/ShapeInfo.h index 1be59c9472..0b60a4672e 100644 --- a/libraries/physics/src/ShapeInfo.h +++ b/libraries/physics/src/ShapeInfo.h @@ -14,19 +14,14 @@ #ifdef USE_BULLET_PHYSICS -#include -#include +//#include +#include #include class ShapeInfo { public: ShapeInfo() : _type(INVALID_SHAPE_PROXYTYPE) {} - ShapeInfo(const btCollisionShape* shape) : _type(INVALID_SHAPE_PROXYTYPE) { - collectInfo(shape); - } - - void collectInfo(const btCollisionShape* shape); void setBox(const btVector3& halfExtents); void setBox(const glm::vec3& halfExtents); @@ -37,12 +32,10 @@ public: int computeHash() const; int computeHash2() const; - btCollisionShape* createShape() const; - -private: int _type; - btAlignedObjectArray _data; + QVector _data; }; #endif // USE_BULLET_PHYSICS #endif // hifi_ShapeInfo_h + diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp new file mode 100644 index 0000000000..95e2efb2c2 --- /dev/null +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -0,0 +1,94 @@ +// +// ShapeInfoUtil.cpp +// libraries/physcis/src +// +// Created by Andrew Meadows 2014.12.01 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ShapeInfoUtil.h" + +#ifdef USE_BULLET_PHYSICS + +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: + { + const btBoxShape* boxShape = static_cast(shape); + info._data.push_back(boxShape->getHalfExtentsWithMargin()); + } + break; + case SPHERE_SHAPE_PROXYTYPE: + { + const btSphereShape* sphereShape = static_cast(shape); + info._data.push_back(btVector3(0.0f, 0.0f, sphereShape->getRadius())); + } + break; + case CYLINDER_SHAPE_PROXYTYPE: + { + const btCylinderShape* cylinderShape = static_cast(shape); + info._data.push_back(cylinderShape->getHalfExtentsWithMargin()); + } + break; + case CAPSULE_SHAPE_PROXYTYPE: + { + const btCapsuleShape* capsuleShape = static_cast(shape); + info._data.push_back(btVector3(capsuleShape->getRadius(), capsuleShape->getHalfHeight(), 0.0f)); + // NOTE: we only support capsules with axis along yAxis + } + break; + default: + info._type = INVALID_SHAPE_PROXYTYPE; + break; + } + } else { + info._type = INVALID_SHAPE_PROXYTYPE; + } +} + +btCollisionShape* ShapeInfoUtil::createShape(const ShapeInfo& info) { + btCollisionShape* shape = NULL; + int numData = info._data.size(); + switch(info._type) { + case BOX_SHAPE_PROXYTYPE: { + if (numData > 0) { + btVector3 halfExtents = info._data[0]; + shape = new btBoxShape(halfExtents); + } + } + break; + case SPHERE_SHAPE_PROXYTYPE: { + if (numData > 0) { + float radius = info._data[0].getZ(); + shape = new btSphereShape(radius); + } + } + break; + case CYLINDER_SHAPE_PROXYTYPE: { + if (numData > 0) { + btVector3 halfExtents = info._data[0]; + // 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: { + if (numData > 0) { + float radius = info._data[0].getX(); + float height = 2.0f * info._data[0].getY(); + shape = new btCapsuleShape(radius, height); + } + } + break; + } + return shape; +} + +#endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ShapeInfoUtil.h b/libraries/physics/src/ShapeInfoUtil.h new file mode 100644 index 0000000000..cff9c08a81 --- /dev/null +++ b/libraries/physics/src/ShapeInfoUtil.h @@ -0,0 +1,31 @@ +// +// ShapeInfoUtil.h +// libraries/physcis/src +// +// Created by Andrew Meadows 2014.12.01 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ShapeInfoUtil_h +#define hifi_ShapeInfoUtil_h + +#ifdef USE_BULLET_PHYSICS + +#include +#include + +#include + +// translates between ShapeInfo and btShape + +namespace ShapeInfoUtil { + void collectInfoFromShape(const btCollisionShape* shape, ShapeInfo& info); + + btCollisionShape* createShapeFromInfo(const ShapeInfo& info); +}; + +#endif // USE_BULLET_PHYSICS +#endif // hifi_ShapeInfoUtil_h diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index c75bfd67ea..73fa15211e 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -10,6 +10,7 @@ // #ifdef USE_BULLET_PHYSICS +#include "ShapeInfoUtil.h" #include "ShapeManager.h" ShapeManager::ShapeManager() { @@ -32,7 +33,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) { shapeRef->_refCount++; return shapeRef->_shape; } else { - btCollisionShape* shape = info.createShape(); + btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info); if (shape) { ShapeReference newRef; newRef._refCount = 1; diff --git a/tests/physics/src/ShapeManagerTests.cpp b/tests/physics/src/ShapeManagerTests.cpp index 78ef45f107..3bfc8b1829 100644 --- a/tests/physics/src/ShapeManagerTests.cpp +++ b/tests/physics/src/ShapeManagerTests.cpp @@ -10,6 +10,7 @@ // #include +#include #include #include @@ -163,7 +164,7 @@ void ShapeManagerTests::addBoxShape() { btCollisionShape* shape = shapeManager.getShape(info); ShapeInfo otherInfo; - otherInfo.collectInfo(shape); + collectInfoFromShape(shape, otherInfo); btCollisionShape* otherShape = shapeManager.getShape(otherInfo); if (shape != otherShape) { @@ -183,7 +184,7 @@ void ShapeManagerTests::addSphereShape() { btCollisionShape* shape = shapeManager.getShape(info); ShapeInfo otherInfo; - otherInfo.collectInfo(shape); + collectInfoFromShape(shape, otherInfo); btCollisionShape* otherShape = shapeManager.getShape(otherInfo); if (shape != otherShape) { @@ -204,7 +205,7 @@ void ShapeManagerTests::addCylinderShape() { btCollisionShape* shape = shapeManager.getShape(info); ShapeInfo otherInfo; - otherInfo.collectInfo(shape); + collectInfoFromShape(shape, otherInfo); btCollisionShape* otherShape = shapeManager.getShape(otherInfo); if (shape != otherShape) { @@ -225,7 +226,7 @@ void ShapeManagerTests::addCapsuleShape() { btCollisionShape* shape = shapeManager.getShape(info); ShapeInfo otherInfo; - otherInfo.collectInfo(shape); + collectInfoFromShape(shape, otherInfo); btCollisionShape* otherShape = shapeManager.getShape(otherInfo); if (shape != otherShape) {