From 25b3cf935967beb5011419b6d3911fca05863743 Mon Sep 17 00:00:00 2001 From: gugus Date: Fri, 18 Mar 2011 13:24:47 +0100 Subject: [PATCH] OEngine doesn't rely anymore on OpenMW+ some change for the toggleCollisionMode function. --- bullet/BulletShapeLoader.cpp | 124 +++++++++++++++++++++++++++++++ bullet/BulletShapeLoader.h | 138 +++++++++++++++++++++++++++++++++++ bullet/physic.cpp | 29 +++++--- bullet/physic.hpp | 17 +++-- 4 files changed, 291 insertions(+), 17 deletions(-) create mode 100644 bullet/BulletShapeLoader.cpp create mode 100644 bullet/BulletShapeLoader.h diff --git a/bullet/BulletShapeLoader.cpp b/bullet/BulletShapeLoader.cpp new file mode 100644 index 000000000..927ec6a27 --- /dev/null +++ b/bullet/BulletShapeLoader.cpp @@ -0,0 +1,124 @@ +#include "BulletShapeLoader.h" + + + +BulletShape::BulletShape(Ogre::ResourceManager* creator, const Ogre::String &name, + Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual, + Ogre::ManualResourceLoader *loader) : +Ogre::Resource(creator, name, handle, group, isManual, loader) +{ + /* If you were storing a pointer to an object, then you would set that pointer to NULL here. + */ + + /* For consistency with StringInterface, but we don't add any parameters here + That's because the Resource implementation of StringInterface is to + list all the options that need to be set before loading, of which + we have none as such. Full details can be set through scripts. + */ + Shape = NULL; + collide = true; + createParamDictionary("BulletShape"); +} + +BulletShape::~BulletShape() +{ +} + +// farm out to BulletShapeLoader +void BulletShape::loadImpl() +{ + mLoader->loadResource(this); +} + +void BulletShape::deleteShape(btCollisionShape* mShape) +{ + if(mShape!=NULL) + { + if(mShape->isCompound()) + { + btCompoundShape* ms = static_cast(Shape); + int a = ms->getNumChildShapes(); + for(int i=0; i getChildShape(i)); + } + } + delete mShape; + } + mShape = NULL; +} + +void BulletShape::unloadImpl() +{ + deleteShape(Shape); +} + +//TODO:change this? +size_t BulletShape::calculateSize() const +{ + return 1; +} + + + +//============================================================================================================= +template<> BulletShapeManager *Ogre::Singleton::ms_Singleton = 0; + +BulletShapeManager *BulletShapeManager::getSingletonPtr() +{ + return ms_Singleton; +} + +BulletShapeManager &BulletShapeManager::getSingleton() +{ + assert(ms_Singleton); + return(*ms_Singleton); +} + +BulletShapeManager::BulletShapeManager() +{ + mResourceType = "BulletShape"; + + // low, because it will likely reference other resources + mLoadOrder = 30.0f; + + // this is how we register the ResourceManager with OGRE + Ogre::ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); +} + +BulletShapeManager::~BulletShapeManager() +{ + // and this is how we unregister it + Ogre::ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); +} + +BulletShapePtr BulletShapeManager::load(const Ogre::String &name, const Ogre::String &group) +{ + BulletShapePtr textf = getByName(name); + + if (textf.isNull()) + textf = create(name, group); + + textf->load(); + return textf; +} + +Ogre::Resource *BulletShapeManager::createImpl(const Ogre::String &name, Ogre::ResourceHandle handle, + const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader, + const Ogre::NameValuePairList *createParams) +{ + BulletShape* res = new BulletShape(this, name, handle, group, isManual, loader); + //if(isManual) + //{ + //loader->loadResource(res); + //} + return res; +} + + +//==================================================================== +void BulletShapeLoader::loadResource(Ogre::Resource *resource) +{} + +void BulletShapeLoader::load(const std::string &name,const std::string &group) +{} \ No newline at end of file diff --git a/bullet/BulletShapeLoader.h b/bullet/BulletShapeLoader.h new file mode 100644 index 000000000..e28a7175e --- /dev/null +++ b/bullet/BulletShapeLoader.h @@ -0,0 +1,138 @@ +#ifndef _BULLET_SHAPE_LOADER_H_ +#define _BULLET_SHAPE_LOADER_H_ + +#include +#include +#include + +//For some reason, Ogre Singleton cannot be used in another namespace, that's why there is no namespace here. +//But the risk of name collision seems pretty low here. + +/** +*Define a new resource which describe a Shape usable by bullet.See BulletShapeManager for how to get/use them. +*/ +class BulletShape : public Ogre::Resource +{ + Ogre::String mString; + +protected: + void loadImpl(); + void unloadImpl(); + size_t calculateSize() const; + + void deleteShape(btCollisionShape* mShape); + +public: + + BulletShape(Ogre::ResourceManager *creator, const Ogre::String &name, + Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual = false, + Ogre::ManualResourceLoader *loader = 0); + + virtual ~BulletShape(); + + btCollisionShape* Shape; + //this flag indicate if the shape is used for collision or if it's for raycasting only. + bool collide; +}; + +/** +* +*/ +class BulletShapePtr : public Ogre::SharedPtr +{ +public: + BulletShapePtr() : Ogre::SharedPtr() {} + explicit BulletShapePtr(BulletShape *rep) : Ogre::SharedPtr(rep) {} + BulletShapePtr(const BulletShapePtr &r) : Ogre::SharedPtr(r) {} + BulletShapePtr(const Ogre::ResourcePtr &r) : Ogre::SharedPtr() + { + if( r.isNull() ) + return; + // lock & copy other mutex pointer + OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) + OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) + pRep = static_cast(r.getPointer()); + pUseCount = r.useCountPointer(); + useFreeMethod = r.freeMethod(); + if (pUseCount) + { + ++(*pUseCount); + } + } + + /// Operator used to convert a ResourcePtr to a BulletShapePtr + BulletShapePtr& operator=(const Ogre::ResourcePtr& r) + { + if(pRep == static_cast(r.getPointer())) + return *this; + release(); + if( r.isNull() ) + return *this; // resource ptr is null, so the call to release above has done all we need to do. + // lock & copy other mutex pointer + OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) + OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) + pRep = static_cast(r.getPointer()); + pUseCount = r.useCountPointer(); + useFreeMethod = r.freeMethod(); + if (pUseCount) + { + ++(*pUseCount); + } + return *this; + } +}; + + + + +/** +*Hold any BulletShape that was created by the ManualBulletShapeLoader. +* +*To get a bulletShape, you must load it first. +*First, create a manualBulletShapeLoader. Then call ManualBulletShapeManager->load(). This create an "empty" resource. +*Then use BulletShapeManager->load(). This will fill the resource with the required info. +*To get the resource,use BulletShapeManager::getByName. +*When you use the resource no more, just use BulletShapeManager->unload(). It won't completly delete the resource, but it will +*"empty" it.This allow a better management of memory: when you are leaving a cell, just unload every useless shape. +* +*Alternatively, you can call BulletShape->load() in order to actually load the resource. +*When you are finished with it, just call BulletShape->unload(). +* +*IMO: prefere the first methode, i am not completly sure about the 2nd. +* +*Important Note: i have no idea of what happen if you try to load two time the same resource without unloading. +*It won't crash, but it might lead to memory leaks(I don't know how Ogre handle this). So don't do it! +*/ +class BulletShapeManager : public Ogre::ResourceManager, public Ogre::Singleton +{ +protected: + + // must implement this from ResourceManager's interface + Ogre::Resource *createImpl(const Ogre::String &name, Ogre::ResourceHandle handle, + const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader, + const Ogre::NameValuePairList *createParams); + +public: + + BulletShapeManager(); + virtual ~BulletShapeManager(); + + virtual BulletShapePtr load(const Ogre::String &name, const Ogre::String &group); + + static BulletShapeManager &getSingleton(); + static BulletShapeManager *getSingletonPtr(); +}; + +class BulletShapeLoader : public Ogre::ManualResourceLoader +{ +public: + + BulletShapeLoader(){}; + virtual ~BulletShapeLoader() {} + + virtual void loadResource(Ogre::Resource *resource); + + virtual void load(const std::string &name,const std::string &group); +}; + +#endif \ No newline at end of file diff --git a/bullet/physic.cpp b/bullet/physic.cpp index fe491f6c6..d0be072f3 100644 --- a/bullet/physic.cpp +++ b/bullet/physic.cpp @@ -83,6 +83,11 @@ namespace Physic mCharacter->mCollision = collision; } + bool PhysicActor::getCollisionMode() + { + return mCharacter->mCollision; + } + void PhysicActor::setWalkDirection(const btVector3& mvt) { mCharacter->setWalkDirection( mvt ); @@ -133,7 +138,7 @@ namespace Physic - PhysicEngine::PhysicEngine() + PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader) { // Set up the collision configuration and dispatcher collisionConfiguration = new btDefaultCollisionConfiguration(); @@ -157,7 +162,7 @@ namespace Physic new BulletShapeManager(); } //TODO:singleton? - ShapeLoader = new ManualBulletShapeLoader(); + mShapeLoader = shapeLoader; isDebugCreated = false; } @@ -178,14 +183,14 @@ namespace Physic } } - void PhysicEngine::setDebugRenderingMode(int mode) - { - if(!isDebugCreated) - { - createDebugRendering(); - } - mDebugDrawer->setDebugMode(mode); - } + void PhysicEngine::setDebugRenderingMode(int mode) + { + if(!isDebugCreated) + { + createDebugRendering(); + } + mDebugDrawer->setDebugMode(mode); + } PhysicEngine::~PhysicEngine() { @@ -194,13 +199,13 @@ namespace Physic delete collisionConfiguration; delete dispatcher; delete broadphase; - delete ShapeLoader; + delete mShapeLoader; } RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name) { //get the shape from the .nif - ShapeLoader->load(mesh,"General"); + mShapeLoader->load(mesh,"General"); BulletShapeManager::getSingletonPtr()->load(mesh,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General"); diff --git a/bullet/physic.hpp b/bullet/physic.hpp index 6115628fa..9178a5779 100644 --- a/bullet/physic.hpp +++ b/bullet/physic.hpp @@ -6,6 +6,7 @@ #include #include #include +#include "BulletShapeLoader.h" class btRigidBody; class btBroadphaseInterface; @@ -20,9 +21,6 @@ namespace BtOgre class DebugDrawer; } -class BulletShapeManager; -class ManualBulletShapeLoader; - namespace MWWorld { class World; @@ -72,6 +70,8 @@ namespace Physic void enableCollisions(bool collision); + bool getCollisionMode(); + btVector3 getPosition(void); btQuaternion getRotation(void); @@ -113,7 +113,14 @@ namespace Physic class PhysicEngine { public: - PhysicEngine(); + /** + *Note that the shapeLoader IS destroyed by the phyic Engine!! + */ + PhysicEngine(BulletShapeLoader* shapeLoader); + + /** + *It DOES destroy the shape loader! + */ ~PhysicEngine(); /** @@ -200,7 +207,7 @@ namespace Physic btDiscreteDynamicsWorld* dynamicsWorld; //the NIF file loader. - ManualBulletShapeLoader* ShapeLoader; + BulletShapeLoader* mShapeLoader; std::map RigidBodyMap; std::map PhysicActorMap;