Move BulletShapeManager and BulletShape to resource/

openmw-38
scrawl 9 years ago
parent eb2f16d682
commit 8cf57ef6ac

@ -6,7 +6,7 @@
#include <BulletCollision/CollisionShapes/btBoxShape.h>
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
#include <components/nifbullet/bulletnifloader.hpp>
#include <components/resource/bulletshape.hpp>
#include "../mwworld/class.hpp"
@ -17,7 +17,7 @@ namespace MWPhysics
{
Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<NifBullet::BulletShapeInstance> shape, btCollisionWorld* world)
Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shape, btCollisionWorld* world)
: mCanWaterWalk(false), mWalkingOnWater(false)
, mCollisionObject(0), mForce(0.f, 0.f, 0.f), mOnGround(false)
, mInternalCollisionMode(true)

@ -13,7 +13,7 @@ class btCollisionWorld;
class btCollisionShape;
class btCollisionObject;
namespace NifBullet
namespace Resource
{
class BulletShapeInstance;
}
@ -43,7 +43,7 @@ namespace MWPhysics
class Actor : public PtrHolder
{
public:
Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<NifBullet::BulletShapeInstance> shape, btCollisionWorld* world);
Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shape, btCollisionWorld* world);
~Actor();
/**

@ -17,9 +17,9 @@
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
#include <LinearMath/btQuickprof.h>
#include <components/nifbullet/bulletshapemanager.hpp>
#include <components/nifbullet/bulletnifloader.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/bulletshapemanager.hpp>
#include <components/esm/loadgmst.hpp>
@ -520,7 +520,7 @@ namespace MWPhysics
class Object : public PtrHolder
{
public:
Object(const MWWorld::Ptr& ptr, osg::ref_ptr<NifBullet::BulletShapeInstance> shapeInstance)
Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance)
: mShapeInstance(shapeInstance)
{
mPtr = ptr;
@ -599,13 +599,13 @@ namespace MWPhysics
private:
std::auto_ptr<btCollisionObject> mCollisionObject;
osg::ref_ptr<NifBullet::BulletShapeInstance> mShapeInstance;
osg::ref_ptr<Resource::BulletShapeInstance> mShapeInstance;
};
// ---------------------------------------------------------------
PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode)
: mShapeManager(new NifBullet::BulletShapeManager(resourceSystem->getVFS()))
: mShapeManager(new Resource::BulletShapeManager(resourceSystem->getVFS()))
, mDebugDrawEnabled(false)
, mTimeAccum(0.0f)
, mWaterHeight(0)
@ -974,7 +974,7 @@ namespace MWPhysics
void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh)
{
osg::ref_ptr<NifBullet::BulletShapeInstance> shapeInstance = mShapeManager->createInstance(mesh);
osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->createInstance(mesh);
if (!shapeInstance || !shapeInstance->getCollisionShape())
return;
@ -1115,7 +1115,7 @@ namespace MWPhysics
}
void PhysicsSystem::addActor (const MWWorld::Ptr& ptr, const std::string& mesh) {
osg::ref_ptr<NifBullet::BulletShapeInstance> shapeInstance = mShapeManager->createInstance(mesh);
osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->createInstance(mesh);
if (!shapeInstance)
return;

@ -21,7 +21,7 @@ namespace MWRender
class DebugDrawer;
}
namespace NifBullet
namespace Resource
{
class BulletShapeManager;
}
@ -154,7 +154,7 @@ namespace MWPhysics
btCollisionDispatcher* mDispatcher;
btCollisionWorld* mCollisionWorld;
std::auto_ptr<NifBullet::BulletShapeManager> mShapeManager;
std::auto_ptr<Resource::BulletShapeManager> mShapeManager;
typedef std::map<MWWorld::Ptr, Object*> ObjectMap;
ObjectMap mObjects;

@ -37,7 +37,7 @@ add_component_dir (vfs
)
add_component_dir (resource
scenemanager texturemanager resourcesystem
scenemanager texturemanager resourcesystem bulletshapemanager bulletshape
)
add_component_dir (sceneutil
@ -55,7 +55,7 @@ add_component_dir (nifosg
)
add_component_dir (nifbullet
bulletnifloader bulletshapemanager
bulletnifloader
)
add_component_dir (to_utf8

@ -40,21 +40,6 @@ btVector3 getbtVector(const osg::Vec3f &v)
namespace NifBullet
{
// Subclass btBhvTriangleMeshShape to auto-delete the meshInterface
struct TriangleMeshShape : public btBvhTriangleMeshShape
{
TriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression)
: btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression)
{
}
virtual ~TriangleMeshShape()
{
delete getTriangleInfoMap();
delete m_meshInterface;
}
};
BulletNifLoader::BulletNifLoader()
: mCompoundShape(NULL)
, mStaticMesh(NULL)
@ -65,9 +50,9 @@ BulletNifLoader::~BulletNifLoader()
{
}
osg::ref_ptr<BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr nif)
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr nif)
{
mShape = new BulletShape;
mShape = new Resource::BulletShape;
mCompoundShape = NULL;
mStaticMesh = NULL;
@ -126,11 +111,11 @@ osg::ref_ptr<BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr nif)
{
btTransform trans;
trans.setIdentity();
mCompoundShape->addChildShape(trans, new TriangleMeshShape(mStaticMesh,true));
mCompoundShape->addChildShape(trans, new Resource::TriangleMeshShape(mStaticMesh,true));
}
}
else if (mStaticMesh)
mShape->mCollisionShape = new TriangleMeshShape(mStaticMesh,true);
mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh,true);
return mShape;
}
@ -306,7 +291,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags,
childMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3));
}
TriangleMeshShape* childShape = new TriangleMeshShape(childMesh,true);
Resource::TriangleMeshShape* childShape = new Resource::TriangleMeshShape(childMesh,true);
float scale = shape->trafo.scale;
const Nif::Node* parent = shape;
@ -346,93 +331,4 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags,
}
}
BulletShape::BulletShape()
: mCollisionShape(NULL)
{
}
BulletShape::~BulletShape()
{
deleteShape(mCollisionShape);
}
void BulletShape::deleteShape(btCollisionShape* shape)
{
if(shape!=NULL)
{
if(shape->isCompound())
{
btCompoundShape* ms = static_cast<btCompoundShape*>(shape);
int a = ms->getNumChildShapes();
for(int i=0; i <a;i++)
deleteShape(ms->getChildShape(i));
}
delete shape;
}
}
btCollisionShape* BulletShape::duplicateCollisionShape(btCollisionShape *shape) const
{
if(shape->isCompound())
{
btCompoundShape *comp = static_cast<btCompoundShape*>(shape);
btCompoundShape *newShape = new btCompoundShape;
int numShapes = comp->getNumChildShapes();
for(int i = 0;i < numShapes;++i)
{
btCollisionShape *child = duplicateCollisionShape(comp->getChildShape(i));
btTransform trans = comp->getChildTransform(i);
newShape->addChildShape(trans, child);
}
return newShape;
}
if(btBvhTriangleMeshShape* trishape = dynamic_cast<btBvhTriangleMeshShape*>(shape))
{
#if BT_BULLET_VERSION >= 283
btScaledBvhTriangleMeshShape* newShape = new btScaledBvhTriangleMeshShape(trishape, btVector3(1.f, 1.f, 1.f));
#else
// work around btScaledBvhTriangleMeshShape bug ( https://code.google.com/p/bullet/issues/detail?id=371 ) in older bullet versions
btTriangleMesh* oldMesh = static_cast<btTriangleMesh*>(trishape->getMeshInterface());
btTriangleMesh* newMesh = new btTriangleMesh(*oldMesh);
NifBullet::TriangleMeshShape* newShape = new NifBullet::TriangleMeshShape(newMesh, true);
#endif
return newShape;
}
if (btBoxShape* boxshape = dynamic_cast<btBoxShape*>(shape))
{
return new btBoxShape(*boxshape);
}
throw std::logic_error(std::string("Unhandled Bullet shape duplication: ")+shape->getName());
}
btCollisionShape *BulletShape::getCollisionShape()
{
return mCollisionShape;
}
osg::ref_ptr<BulletShapeInstance> BulletShape::makeInstance()
{
osg::ref_ptr<BulletShapeInstance> instance (new BulletShapeInstance(this));
return instance;
}
BulletShapeInstance::BulletShapeInstance(osg::ref_ptr<BulletShape> source)
: BulletShape()
, mSource(source)
{
mCollisionBoxHalfExtents = source->mCollisionBoxHalfExtents;
mCollisionBoxTranslate = source->mCollisionBoxTranslate;
mAnimatedShapes = source->mAnimatedShapes;
if (source->mCollisionShape)
mCollisionShape = duplicateCollisionShape(source->mCollisionShape);
}
} // namespace NifBullet

@ -13,6 +13,7 @@
#include <osg/Referenced>
#include <components/nif/niffile.hpp>
#include <components/resource/bulletshape.hpp>
class btTriangleMesh;
class btCompoundShape;
@ -28,48 +29,6 @@ namespace Nif
namespace NifBullet
{
class BulletShapeInstance;
class BulletShape : public osg::Referenced
{
public:
BulletShape();
virtual ~BulletShape();
btCollisionShape* mCollisionShape;
// Used for actors. Note, ideally actors would use a separate loader - as it is
// we have to keep a redundant copy of the actor model around in mCollisionShape, which isn't used.
// For now, use one file <-> one resource for simplicity.
osg::Vec3f mCollisionBoxHalfExtents;
osg::Vec3f mCollisionBoxTranslate;
// Stores animated collision shapes. If any collision nodes in the NIF are animated, then mCollisionShape
// will be a btCompoundShape (which consists of one or more child shapes).
// In this map, for each animated collision shape,
// we store the node's record index mapped to the child index of the shape in the btCompoundShape.
std::map<int, int> mAnimatedShapes;
osg::ref_ptr<BulletShapeInstance> makeInstance();
btCollisionShape* duplicateCollisionShape(btCollisionShape* shape) const;
btCollisionShape* getCollisionShape();
private:
void deleteShape(btCollisionShape* shape);
};
// An instance of a BulletShape that may have its own unique scaling set on the mCollisionShape.
// Vertex data is shallow-copied where possible. A ref_ptr to the original shape needs to be held to keep vertex pointers intact.
class BulletShapeInstance : public BulletShape
{
public:
BulletShapeInstance(osg::ref_ptr<BulletShape> source);
private:
osg::ref_ptr<BulletShape> mSource;
};
/**
*Load bulletShape from NIF files.
*/
@ -91,7 +50,7 @@ public:
abort();
}
osg::ref_ptr<BulletShape> load(const Nif::NIFFilePtr file);
osg::ref_ptr<Resource::BulletShape> load(const Nif::NIFFilePtr file);
private:
bool findBoundingBox(const Nif::Node* node, int flags = 0);
@ -106,7 +65,7 @@ private:
btTriangleMesh* mStaticMesh;
osg::ref_ptr<BulletShape> mShape;
osg::ref_ptr<Resource::BulletShape> mShape;
};
}

@ -0,0 +1,102 @@
#include "bulletshape.hpp"
#include <stdexcept>
#include <BulletCollision/CollisionShapes/btBoxShape.h>
#include <BulletCollision/CollisionShapes/btTriangleMesh.h>
#include <BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h>
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
namespace Resource
{
BulletShape::BulletShape()
: mCollisionShape(NULL)
{
}
BulletShape::~BulletShape()
{
deleteShape(mCollisionShape);
}
void BulletShape::deleteShape(btCollisionShape* shape)
{
if(shape!=NULL)
{
if(shape->isCompound())
{
btCompoundShape* ms = static_cast<btCompoundShape*>(shape);
int a = ms->getNumChildShapes();
for(int i=0; i <a;i++)
deleteShape(ms->getChildShape(i));
}
delete shape;
}
}
btCollisionShape* BulletShape::duplicateCollisionShape(btCollisionShape *shape) const
{
if(shape->isCompound())
{
btCompoundShape *comp = static_cast<btCompoundShape*>(shape);
btCompoundShape *newShape = new btCompoundShape;
int numShapes = comp->getNumChildShapes();
for(int i = 0;i < numShapes;++i)
{
btCollisionShape *child = duplicateCollisionShape(comp->getChildShape(i));
btTransform trans = comp->getChildTransform(i);
newShape->addChildShape(trans, child);
}
return newShape;
}
if(btBvhTriangleMeshShape* trishape = dynamic_cast<btBvhTriangleMeshShape*>(shape))
{
#if BT_BULLET_VERSION >= 283
btScaledBvhTriangleMeshShape* newShape = new btScaledBvhTriangleMeshShape(trishape, btVector3(1.f, 1.f, 1.f));
#else
// work around btScaledBvhTriangleMeshShape bug ( https://code.google.com/p/bullet/issues/detail?id=371 ) in older bullet versions
btTriangleMesh* oldMesh = static_cast<btTriangleMesh*>(trishape->getMeshInterface());
btTriangleMesh* newMesh = new btTriangleMesh(*oldMesh);
TriangleMeshShape* newShape = new TriangleMeshShape(newMesh, true);
#endif
return newShape;
}
if (btBoxShape* boxshape = dynamic_cast<btBoxShape*>(shape))
{
return new btBoxShape(*boxshape);
}
throw std::logic_error(std::string("Unhandled Bullet shape duplication: ")+shape->getName());
}
btCollisionShape *BulletShape::getCollisionShape()
{
return mCollisionShape;
}
osg::ref_ptr<BulletShapeInstance> BulletShape::makeInstance()
{
osg::ref_ptr<BulletShapeInstance> instance (new BulletShapeInstance(this));
return instance;
}
BulletShapeInstance::BulletShapeInstance(osg::ref_ptr<BulletShape> source)
: BulletShape()
, mSource(source)
{
mCollisionBoxHalfExtents = source->mCollisionBoxHalfExtents;
mCollisionBoxTranslate = source->mCollisionBoxTranslate;
mAnimatedShapes = source->mAnimatedShapes;
if (source->mCollisionShape)
mCollisionShape = duplicateCollisionShape(source->mCollisionShape);
}
}

@ -0,0 +1,78 @@
#ifndef OPENMW_COMPONENTS_RESOURCE_BULLETSHAPE_H
#define OPENMW_COMPONENTS_RESOURCE_BULLETSHAPE_H
#include <map>
#include <osg/Referenced>
#include <osg/ref_ptr>
#include <osg/Vec3f>
#include <BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h>
class btCollisionShape;
namespace Resource
{
class BulletShapeInstance;
class BulletShape : public osg::Referenced
{
public:
BulletShape();
virtual ~BulletShape();
btCollisionShape* mCollisionShape;
// Used for actors. Note, ideally actors would use a separate loader - as it is
// we have to keep a redundant copy of the actor model around in mCollisionShape, which isn't used.
// For now, use one file <-> one resource for simplicity.
osg::Vec3f mCollisionBoxHalfExtents;
osg::Vec3f mCollisionBoxTranslate;
// Stores animated collision shapes. If any collision nodes in the NIF are animated, then mCollisionShape
// will be a btCompoundShape (which consists of one or more child shapes).
// In this map, for each animated collision shape,
// we store the node's record index mapped to the child index of the shape in the btCompoundShape.
std::map<int, int> mAnimatedShapes;
osg::ref_ptr<BulletShapeInstance> makeInstance();
btCollisionShape* duplicateCollisionShape(btCollisionShape* shape) const;
btCollisionShape* getCollisionShape();
private:
void deleteShape(btCollisionShape* shape);
};
// An instance of a BulletShape that may have its own unique scaling set on the mCollisionShape.
// Vertex data is shallow-copied where possible. A ref_ptr to the original shape is held to keep vertex pointers intact.
class BulletShapeInstance : public BulletShape
{
public:
BulletShapeInstance(osg::ref_ptr<BulletShape> source);
private:
osg::ref_ptr<BulletShape> mSource;
};
// Subclass btBhvTriangleMeshShape to auto-delete the meshInterface
struct TriangleMeshShape : public btBvhTriangleMeshShape
{
TriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression)
: btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression)
{
}
virtual ~TriangleMeshShape()
{
delete getTriangleInfoMap();
delete m_meshInterface;
}
};
}
#endif

@ -4,7 +4,9 @@
#include <components/nifbullet/bulletnifloader.hpp>
namespace NifBullet
#include "bulletshape.hpp"
namespace Resource
{
BulletShapeManager::BulletShapeManager(const VFS::Manager* vfs)
@ -38,7 +40,7 @@ osg::ref_ptr<BulletShapeInstance> BulletShapeManager::createInstance(const std::
if (ext != "nif")
return NULL;
BulletNifLoader loader;
NifBullet::BulletNifLoader loader;
// might be worth sharing NIFFiles with SceneManager in some way
shape = loader.load(Nif::NIFFilePtr(new Nif::NIFFile(file, normalized)));

@ -6,6 +6,8 @@
#include <osg/ref_ptr>
#include "bulletshape.hpp"
namespace VFS
{
class Manager;
@ -14,10 +16,6 @@ namespace VFS
namespace Resource
{
class SceneManager;
}
namespace NifBullet
{
class BulletShape;
class BulletShapeInstance;
Loading…
Cancel
Save