mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-11 05:31:58 +02:00
Add PhysicsWorld and ShapeManager classes
This commit is contained in:
parent
29fd359385
commit
50a97849bb
4 changed files with 246 additions and 0 deletions
23
libraries/physics/src/PhysicsWorld.cpp
Normal file
23
libraries/physics/src/PhysicsWorld.cpp
Normal 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);
|
||||
}
|
41
libraries/physics/src/PhysicsWorld.h
Normal file
41
libraries/physics/src/PhysicsWorld.h
Normal 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
|
94
libraries/physics/src/ShapeManager.cpp
Normal file
94
libraries/physics/src/ShapeManager.cpp
Normal 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
|
88
libraries/physics/src/ShapeManager.h
Normal file
88
libraries/physics/src/ShapeManager.h
Normal 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
|
Loading…
Reference in a new issue