mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-30 15:06:41 +00:00
Move BulletShapeManager and BulletShape to resource/
This commit is contained in:
parent
eb2f16d682
commit
8cf57ef6ac
11 changed files with 208 additions and 173 deletions
|
@ -6,7 +6,7 @@
|
||||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||||
|
|
||||||
#include <components/nifbullet/bulletnifloader.hpp>
|
#include <components/resource/bulletshape.hpp>
|
||||||
|
|
||||||
#include "../mwworld/class.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)
|
: mCanWaterWalk(false), mWalkingOnWater(false)
|
||||||
, mCollisionObject(0), mForce(0.f, 0.f, 0.f), mOnGround(false)
|
, mCollisionObject(0), mForce(0.f, 0.f, 0.f), mOnGround(false)
|
||||||
, mInternalCollisionMode(true)
|
, mInternalCollisionMode(true)
|
||||||
|
|
|
@ -13,7 +13,7 @@ class btCollisionWorld;
|
||||||
class btCollisionShape;
|
class btCollisionShape;
|
||||||
class btCollisionObject;
|
class btCollisionObject;
|
||||||
|
|
||||||
namespace NifBullet
|
namespace Resource
|
||||||
{
|
{
|
||||||
class BulletShapeInstance;
|
class BulletShapeInstance;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ namespace MWPhysics
|
||||||
class Actor : public PtrHolder
|
class Actor : public PtrHolder
|
||||||
{
|
{
|
||||||
public:
|
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();
|
~Actor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
|
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
|
||||||
#include <LinearMath/btQuickprof.h>
|
#include <LinearMath/btQuickprof.h>
|
||||||
|
|
||||||
#include <components/nifbullet/bulletshapemanager.hpp>
|
|
||||||
#include <components/nifbullet/bulletnifloader.hpp>
|
#include <components/nifbullet/bulletnifloader.hpp>
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
#include <components/resource/bulletshapemanager.hpp>
|
||||||
|
|
||||||
#include <components/esm/loadgmst.hpp>
|
#include <components/esm/loadgmst.hpp>
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ namespace MWPhysics
|
||||||
class Object : public PtrHolder
|
class Object : public PtrHolder
|
||||||
{
|
{
|
||||||
public:
|
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)
|
: mShapeInstance(shapeInstance)
|
||||||
{
|
{
|
||||||
mPtr = ptr;
|
mPtr = ptr;
|
||||||
|
@ -599,13 +599,13 @@ namespace MWPhysics
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::auto_ptr<btCollisionObject> mCollisionObject;
|
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)
|
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)
|
, mDebugDrawEnabled(false)
|
||||||
, mTimeAccum(0.0f)
|
, mTimeAccum(0.0f)
|
||||||
, mWaterHeight(0)
|
, mWaterHeight(0)
|
||||||
|
@ -974,7 +974,7 @@ namespace MWPhysics
|
||||||
|
|
||||||
void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh)
|
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())
|
if (!shapeInstance || !shapeInstance->getCollisionShape())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1115,7 +1115,7 @@ namespace MWPhysics
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addActor (const MWWorld::Ptr& ptr, const std::string& mesh) {
|
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)
|
if (!shapeInstance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MWRender
|
||||||
class DebugDrawer;
|
class DebugDrawer;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NifBullet
|
namespace Resource
|
||||||
{
|
{
|
||||||
class BulletShapeManager;
|
class BulletShapeManager;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ namespace MWPhysics
|
||||||
btCollisionDispatcher* mDispatcher;
|
btCollisionDispatcher* mDispatcher;
|
||||||
btCollisionWorld* mCollisionWorld;
|
btCollisionWorld* mCollisionWorld;
|
||||||
|
|
||||||
std::auto_ptr<NifBullet::BulletShapeManager> mShapeManager;
|
std::auto_ptr<Resource::BulletShapeManager> mShapeManager;
|
||||||
|
|
||||||
typedef std::map<MWWorld::Ptr, Object*> ObjectMap;
|
typedef std::map<MWWorld::Ptr, Object*> ObjectMap;
|
||||||
ObjectMap mObjects;
|
ObjectMap mObjects;
|
||||||
|
|
|
@ -37,7 +37,7 @@ add_component_dir (vfs
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (resource
|
add_component_dir (resource
|
||||||
scenemanager texturemanager resourcesystem
|
scenemanager texturemanager resourcesystem bulletshapemanager bulletshape
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (sceneutil
|
add_component_dir (sceneutil
|
||||||
|
@ -55,7 +55,7 @@ add_component_dir (nifosg
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (nifbullet
|
add_component_dir (nifbullet
|
||||||
bulletnifloader bulletshapemanager
|
bulletnifloader
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (to_utf8
|
add_component_dir (to_utf8
|
||||||
|
|
|
@ -40,21 +40,6 @@ btVector3 getbtVector(const osg::Vec3f &v)
|
||||||
namespace NifBullet
|
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()
|
BulletNifLoader::BulletNifLoader()
|
||||||
: mCompoundShape(NULL)
|
: mCompoundShape(NULL)
|
||||||
, mStaticMesh(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;
|
mCompoundShape = NULL;
|
||||||
mStaticMesh = NULL;
|
mStaticMesh = NULL;
|
||||||
|
@ -126,11 +111,11 @@ osg::ref_ptr<BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr nif)
|
||||||
{
|
{
|
||||||
btTransform trans;
|
btTransform trans;
|
||||||
trans.setIdentity();
|
trans.setIdentity();
|
||||||
mCompoundShape->addChildShape(trans, new TriangleMeshShape(mStaticMesh,true));
|
mCompoundShape->addChildShape(trans, new Resource::TriangleMeshShape(mStaticMesh,true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mStaticMesh)
|
else if (mStaticMesh)
|
||||||
mShape->mCollisionShape = new TriangleMeshShape(mStaticMesh,true);
|
mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh,true);
|
||||||
|
|
||||||
return mShape;
|
return mShape;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +291,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags,
|
||||||
childMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3));
|
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;
|
float scale = shape->trafo.scale;
|
||||||
const Nif::Node* parent = shape;
|
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
|
} // namespace NifBullet
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <osg/Referenced>
|
#include <osg/Referenced>
|
||||||
|
|
||||||
#include <components/nif/niffile.hpp>
|
#include <components/nif/niffile.hpp>
|
||||||
|
#include <components/resource/bulletshape.hpp>
|
||||||
|
|
||||||
class btTriangleMesh;
|
class btTriangleMesh;
|
||||||
class btCompoundShape;
|
class btCompoundShape;
|
||||||
|
@ -28,48 +29,6 @@ namespace Nif
|
||||||
namespace NifBullet
|
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.
|
*Load bulletShape from NIF files.
|
||||||
*/
|
*/
|
||||||
|
@ -91,7 +50,7 @@ public:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<BulletShape> load(const Nif::NIFFilePtr file);
|
osg::ref_ptr<Resource::BulletShape> load(const Nif::NIFFilePtr file);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool findBoundingBox(const Nif::Node* node, int flags = 0);
|
bool findBoundingBox(const Nif::Node* node, int flags = 0);
|
||||||
|
@ -106,7 +65,7 @@ private:
|
||||||
|
|
||||||
btTriangleMesh* mStaticMesh;
|
btTriangleMesh* mStaticMesh;
|
||||||
|
|
||||||
osg::ref_ptr<BulletShape> mShape;
|
osg::ref_ptr<Resource::BulletShape> mShape;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
102
components/resource/bulletshape.cpp
Normal file
102
components/resource/bulletshape.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
78
components/resource/bulletshape.hpp
Normal file
78
components/resource/bulletshape.hpp
Normal file
|
@ -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>
|
#include <components/nifbullet/bulletnifloader.hpp>
|
||||||
|
|
||||||
namespace NifBullet
|
#include "bulletshape.hpp"
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
{
|
{
|
||||||
|
|
||||||
BulletShapeManager::BulletShapeManager(const VFS::Manager* vfs)
|
BulletShapeManager::BulletShapeManager(const VFS::Manager* vfs)
|
||||||
|
@ -38,7 +40,7 @@ osg::ref_ptr<BulletShapeInstance> BulletShapeManager::createInstance(const std::
|
||||||
if (ext != "nif")
|
if (ext != "nif")
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
BulletNifLoader loader;
|
NifBullet::BulletNifLoader loader;
|
||||||
// might be worth sharing NIFFiles with SceneManager in some way
|
// might be worth sharing NIFFiles with SceneManager in some way
|
||||||
shape = loader.load(Nif::NIFFilePtr(new Nif::NIFFile(file, normalized)));
|
shape = loader.load(Nif::NIFFilePtr(new Nif::NIFFile(file, normalized)));
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
#include "bulletshape.hpp"
|
||||||
|
|
||||||
namespace VFS
|
namespace VFS
|
||||||
{
|
{
|
||||||
class Manager;
|
class Manager;
|
||||||
|
@ -14,10 +16,6 @@ namespace VFS
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
class SceneManager;
|
class SceneManager;
|
||||||
}
|
|
||||||
|
|
||||||
namespace NifBullet
|
|
||||||
{
|
|
||||||
|
|
||||||
class BulletShape;
|
class BulletShape;
|
||||||
class BulletShapeInstance;
|
class BulletShapeInstance;
|
Loading…
Reference in a new issue