Add PhysicsWorld and ShapeManager classes

This commit is contained in:
Andrew Meadows 2014-10-30 10:42:44 -07:00
parent 29fd359385
commit 50a97849bb
4 changed files with 246 additions and 0 deletions

View file

@ -0,0 +1,23 @@
//
// PhysicsWorld.cpp
// libraries/physcis/src
//
// Created by Andrew Meadows 2014.10.29
// 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 "PhysicsWorld.h"
PhysicsWorld::~PhysicsWorld() {
}
void PhysicsWorld::init() {
_collisionConfig = new btDefaultCollisionConfiguration();
_collisionDispatcher = new btCollisionDispatcher(_collisionConfig);
_broadphaseFilter = new btDbvtBroadphase();
_constraintSolver = new btSequentialImpulseConstraintSolver;
_dynamicsWorld = new btDiscreteDynamicsWorld(_collisionDispatcher, _broadphaseFilter, _constraintSolver, _collisionConfig);
}

View file

@ -0,0 +1,41 @@
//
// PhysicsWorld.h
// libraries/physcis/src
//
// Created by Andrew Meadows 2014.10.29
// 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_PhysicsWorld_h
#define hifi_PhysicsWorld_h
#ifdef USE_BULLET_PHYSICS
#include <btBulletDynamicsCommon.h>
class PhysicsWorld {
public:
PhysicsWorld() : _collisionConfig(NULL), _collisionDispatcher(NULL),
_broadphaseFilter(NULL), _constraintSolver(NULL), _dynamicsWorld(NULL) { }
~PhysicsWorld();
void init();
protected:
btDefaultCollisionConfiguration* _collisionConfig;
btCollisionDispatcher* _collisionDispatcher;
btBroadphaseInterface* _broadphaseFilter;
btSequentialImpulseConstraintSolver* _constraintSolver;
btDiscreteDynamicsWorld* _dynamicsWorld;
private:
};
#endif // USE_BULLET_PHYSICS
#endif // hifi_PhysicsWorld_h

View file

@ -0,0 +1,94 @@
//
// ShapeManager.cpp
// libraries/physcis/src
//
// Created by Andrew Meadows 2014.10.29
// 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
//
#ifdef USE_BULLET_PHYSICS
#include "ShapeManager.h"
ShapeManager::ShapeManager() {
}
ShapeManager::~ShapeManager() {
int numShapes = _shapeMap.size();
for (int i = 0; i < numShapes; ++i) {
ShapeReference* shapeRef = _shapeMap.getAtIndex(i);
delete shapeRef->_shape;
}
}
btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) {
int key = info.getHash();
ShapeReference* shapeRef = _shapeMap.find(key);
if (shapeRef) {
shapeRef->_refCount++;
return shapeRef->_shape;
} else {
btCollisionShape* shape = info.createShape();
if (shape) {
ShapeReference newRef;
newRef._refCount = 1;
newRef._shape = shape;
_shapeMap.insert(key, newRef);
}
return shape;
}
}
bool ShapeManager::releaseShape(const ShapeInfo& info) {
int key = info.getHash();
ShapeReference* shapeRef = _shapeMap.find(key);
if (shapeRef) {
if (shapeRef->_refCount > 0) {
shapeRef->_refCount--;
if (shapeRef->_refCount == 0) {
_pendingGarbage.push_back(key);
const int MAX_GARBAGE_CAPACITY = 127;
if (_pendingGarbage.size() > MAX_GARBAGE_CAPACITY) {
collectGarbage();
}
}
return true;
} else {
// attempt to remove shape that has no refs
assert(false);
}
} else {
// attempt to remove unmanaged shape
assert(false);
}
return false;
}
void ShapeManager::collectGarbage() {
int numShapes = _pendingGarbage.size();
for (int i = 0; i < numShapes; ++i) {
int key = _pendingGarbage[i];
ShapeReference* shapeRef = _shapeMap.find(key);
assert(shapeRef != NULL);
if (shapeRef->_refCount == 0) {
delete shapeRef->_shape;
_shapeMap.remove(key);
}
}
_pendingGarbage.clear();
}
int ShapeManager::getNumReferences(const ShapeInfo& info) const {
int key = info.getHash();
const ShapeReference* shapeRef = _shapeMap.find(key);
if (shapeRef) {
return shapeRef->_refCount;
}
return -1;
}
#endif // USE_BULLET_PHYSICS

View file

@ -0,0 +1,88 @@
//
// ShapeManager.h
// libraries/physcis/src
//
// Created by Andrew Meadows 2014.10.29
// 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_ShapeManager_h
#define hifi_ShapeManager_h
#ifdef USE_BULLET_PHYSICS
#include <btBulletDynamicsCommon.h>
#include <LinearMath/btHashMap.h>
struct ShapeInfo {
int _type;
btVector3 _size;
ShapeInfo() : _type(BOX_SHAPE_PROXYTYPE), _size(1.0f, 1.0f, 1.0f) {}
virtual int getHash() const {
// successfully multiply components of size by primes near 256 and convert to U32
unsigned int key = (unsigned int)(241.0f * _size.getX())
+ 241 * (unsigned int)(251.0f * _size.getY())
+ (241 * 251) * (unsigned int)(257.0f * _size.getZ());
// then scramble the results
key += ~(key << 15);
key ^= (key >> 10);
key += (key << 3);
key ^= (key >> 6);
key += ~(key << 11);
key ^= (key >> 16);
// finally XOR with type
key ^= _type;
return key;
}
virtual btCollisionShape* createShape() const {
const float MAX_SHAPE_DIMENSION = 100.0f;
const float MIN_SHAPE_DIMENSION = 0.01f;
for (int i = 0; i < 3; ++i) {
float side = _size[i];
if (side > MAX_SHAPE_DIMENSION || side < MIN_SHAPE_DIMENSION) {
return NULL;
}
}
// default behavior is to create a btBoxShape
return new btBoxShape(0.5f * _size);
}
};
struct ShapeReference {
int _refCount;
btCollisionShape* _shape;
ShapeReference() : _refCount(0), _shape(NULL) {}
};
class ShapeManager {
public:
ShapeManager();
~ShapeManager();
/// \return pointer to shape
btCollisionShape* getShape(const ShapeInfo& info);
/// \return true if shape was found and released
bool releaseShape(const ShapeInfo& info);
/// delete shapes that have zero references
void collectGarbage();
// validation methods
int getNumShapes() const { return _shapeMap.size(); }
int getNumReferences(const ShapeInfo& info) const;
private:
btHashMap<btHashInt, ShapeReference> _shapeMap;
btAlignedObjectArray<int> _pendingGarbage;
};
#endif // USE_BULLET_PHYSICS
#endif // hifi_ShapeManager_h