mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 12:54:30 +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