From 8cf57ef6ac1eaf4a0ba51c230f3ad4d222ba4fc0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 16 Nov 2015 23:30:10 +0100 Subject: [PATCH] Move BulletShapeManager and BulletShape to resource/ --- apps/openmw/mwphysics/actor.cpp | 4 +- apps/openmw/mwphysics/actor.hpp | 4 +- apps/openmw/mwphysics/physicssystem.cpp | 12 +- apps/openmw/mwphysics/physicssystem.hpp | 4 +- components/CMakeLists.txt | 4 +- components/nifbullet/bulletnifloader.cpp | 114 +----------------- components/nifbullet/bulletnifloader.hpp | 47 +------- components/resource/bulletshape.cpp | 102 ++++++++++++++++ components/resource/bulletshape.hpp | 78 ++++++++++++ .../bulletshapemanager.cpp | 6 +- .../bulletshapemanager.hpp | 6 +- 11 files changed, 208 insertions(+), 173 deletions(-) create mode 100644 components/resource/bulletshape.cpp create mode 100644 components/resource/bulletshape.hpp rename components/{nifbullet => resource}/bulletshapemanager.cpp (93%) rename components/{nifbullet => resource}/bulletshapemanager.hpp (96%) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 98ccefe71..8cd0dfeb9 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include "../mwworld/class.hpp" @@ -17,7 +17,7 @@ namespace MWPhysics { -Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr shape, btCollisionWorld* world) +Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr shape, btCollisionWorld* world) : mCanWaterWalk(false), mWalkingOnWater(false) , mCollisionObject(0), mForce(0.f, 0.f, 0.f), mOnGround(false) , mInternalCollisionMode(true) diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index bcbc256d0..3ea64840e 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -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 shape, btCollisionWorld* world); + Actor(const MWWorld::Ptr& ptr, osg::ref_ptr shape, btCollisionWorld* world); ~Actor(); /** diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index f5e9ce2fa..6960d2801 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -17,9 +17,9 @@ #include #include -#include #include #include +#include #include @@ -520,7 +520,7 @@ namespace MWPhysics class Object : public PtrHolder { public: - Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance) + Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance) : mShapeInstance(shapeInstance) { mPtr = ptr; @@ -599,13 +599,13 @@ namespace MWPhysics private: std::auto_ptr mCollisionObject; - osg::ref_ptr mShapeInstance; + osg::ref_ptr mShapeInstance; }; // --------------------------------------------------------------- PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr 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 shapeInstance = mShapeManager->createInstance(mesh); + osg::ref_ptr 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 shapeInstance = mShapeManager->createInstance(mesh); + osg::ref_ptr shapeInstance = mShapeManager->createInstance(mesh); if (!shapeInstance) return; diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 7c5be0b6e..283c85725 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -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 mShapeManager; + std::auto_ptr mShapeManager; typedef std::map ObjectMap; ObjectMap mObjects; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index f8f4c64ab..b7865cb8a 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -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 diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 2496c68cd..5de6d51ca 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -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 BulletNifLoader::load(const Nif::NIFFilePtr nif) +osg::ref_ptr BulletNifLoader::load(const Nif::NIFFilePtr nif) { - mShape = new BulletShape; + mShape = new Resource::BulletShape; mCompoundShape = NULL; mStaticMesh = NULL; @@ -126,11 +111,11 @@ osg::ref_ptr 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(shape); - int a = ms->getNumChildShapes(); - for(int i=0; i getChildShape(i)); - } - delete shape; - } -} - -btCollisionShape* BulletShape::duplicateCollisionShape(btCollisionShape *shape) const -{ - if(shape->isCompound()) - { - btCompoundShape *comp = static_cast(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(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(trishape->getMeshInterface()); - btTriangleMesh* newMesh = new btTriangleMesh(*oldMesh); - NifBullet::TriangleMeshShape* newShape = new NifBullet::TriangleMeshShape(newMesh, true); -#endif - return newShape; - } - - if (btBoxShape* boxshape = dynamic_cast(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 BulletShape::makeInstance() -{ - osg::ref_ptr instance (new BulletShapeInstance(this)); - return instance; -} - -BulletShapeInstance::BulletShapeInstance(osg::ref_ptr source) - : BulletShape() - , mSource(source) -{ - mCollisionBoxHalfExtents = source->mCollisionBoxHalfExtents; - mCollisionBoxTranslate = source->mCollisionBoxTranslate; - - mAnimatedShapes = source->mAnimatedShapes; - - if (source->mCollisionShape) - mCollisionShape = duplicateCollisionShape(source->mCollisionShape); -} - } // namespace NifBullet diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index 52428cc74..a30bf8fdf 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -13,6 +13,7 @@ #include #include +#include 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 mAnimatedShapes; - - osg::ref_ptr 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 source); - -private: - osg::ref_ptr mSource; -}; - /** *Load bulletShape from NIF files. */ @@ -91,7 +50,7 @@ public: abort(); } - osg::ref_ptr load(const Nif::NIFFilePtr file); + osg::ref_ptr 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 mShape; + osg::ref_ptr mShape; }; } diff --git a/components/resource/bulletshape.cpp b/components/resource/bulletshape.cpp new file mode 100644 index 000000000..00bcb9e04 --- /dev/null +++ b/components/resource/bulletshape.cpp @@ -0,0 +1,102 @@ +#include "bulletshape.hpp" + +#include + +#include +#include +#include +#include + +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(shape); + int a = ms->getNumChildShapes(); + for(int i=0; i getChildShape(i)); + } + delete shape; + } +} + +btCollisionShape* BulletShape::duplicateCollisionShape(btCollisionShape *shape) const +{ + if(shape->isCompound()) + { + btCompoundShape *comp = static_cast(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(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(trishape->getMeshInterface()); + btTriangleMesh* newMesh = new btTriangleMesh(*oldMesh); + TriangleMeshShape* newShape = new TriangleMeshShape(newMesh, true); +#endif + return newShape; + } + + if (btBoxShape* boxshape = dynamic_cast(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 BulletShape::makeInstance() +{ + osg::ref_ptr instance (new BulletShapeInstance(this)); + return instance; +} + +BulletShapeInstance::BulletShapeInstance(osg::ref_ptr source) + : BulletShape() + , mSource(source) +{ + mCollisionBoxHalfExtents = source->mCollisionBoxHalfExtents; + mCollisionBoxTranslate = source->mCollisionBoxTranslate; + + mAnimatedShapes = source->mAnimatedShapes; + + if (source->mCollisionShape) + mCollisionShape = duplicateCollisionShape(source->mCollisionShape); +} + +} diff --git a/components/resource/bulletshape.hpp b/components/resource/bulletshape.hpp new file mode 100644 index 000000000..78e509db7 --- /dev/null +++ b/components/resource/bulletshape.hpp @@ -0,0 +1,78 @@ +#ifndef OPENMW_COMPONENTS_RESOURCE_BULLETSHAPE_H +#define OPENMW_COMPONENTS_RESOURCE_BULLETSHAPE_H + +#include + +#include +#include +#include + +#include + +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 mAnimatedShapes; + + osg::ref_ptr 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 source); + + private: + osg::ref_ptr 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 diff --git a/components/nifbullet/bulletshapemanager.cpp b/components/resource/bulletshapemanager.cpp similarity index 93% rename from components/nifbullet/bulletshapemanager.cpp rename to components/resource/bulletshapemanager.cpp index 23b461953..3254a5c97 100644 --- a/components/nifbullet/bulletshapemanager.cpp +++ b/components/resource/bulletshapemanager.cpp @@ -4,7 +4,9 @@ #include -namespace NifBullet +#include "bulletshape.hpp" + +namespace Resource { BulletShapeManager::BulletShapeManager(const VFS::Manager* vfs) @@ -38,7 +40,7 @@ osg::ref_ptr 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))); diff --git a/components/nifbullet/bulletshapemanager.hpp b/components/resource/bulletshapemanager.hpp similarity index 96% rename from components/nifbullet/bulletshapemanager.hpp rename to components/resource/bulletshapemanager.hpp index 6b9ec60de..3e1f05ce5 100644 --- a/components/nifbullet/bulletshapemanager.hpp +++ b/components/resource/bulletshapemanager.hpp @@ -6,6 +6,8 @@ #include +#include "bulletshape.hpp" + namespace VFS { class Manager; @@ -14,10 +16,6 @@ namespace VFS namespace Resource { class SceneManager; -} - -namespace NifBullet -{ class BulletShape; class BulletShapeInstance;