From cb53e714f7c79eaf1eebf29f8c0d60cc79ebd7d4 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 24 Oct 2014 19:14:02 +1000 Subject: [PATCH] Convert PhysicsSystem to a singleton. --- apps/opencs/editor.cpp | 3 +- apps/opencs/editor.hpp | 2 + apps/opencs/view/render/cell.cpp | 10 ++- apps/opencs/view/render/cell.hpp | 9 +-- apps/opencs/view/render/object.cpp | 10 +-- apps/opencs/view/render/object.hpp | 9 +-- .../view/render/pagedworldspacewidget.cpp | 10 ++- apps/opencs/view/render/previewwidget.cpp | 2 +- apps/opencs/view/render/scenewidget.cpp | 9 +-- apps/opencs/view/render/scenewidget.hpp | 8 --- .../view/render/unpagedworldspacewidget.cpp | 4 +- apps/opencs/view/world/physicssystem.cpp | 64 +++++++++++++------ apps/opencs/view/world/physicssystem.hpp | 7 +- 13 files changed, 75 insertions(+), 72 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 982fc20d5b..beb50fceae 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -21,7 +21,7 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) : mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr), - mViewManager (mDocumentManager), + mViewManager (mDocumentManager), mPhysicsSystem (0), mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL) { std::pair > config = readConfig(); @@ -34,6 +34,7 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string()); mOverlaySystem.reset (new CSVRender::OverlaySystem); + mPhysicsSystem.reset (new CSVWorld::PhysicsSystem); Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true, mFsStrict); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index cd39d53a48..4d2fdc2eb1 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -28,6 +28,7 @@ #include "view/settings/dialog.hpp" #include "view/render/overlaysystem.hpp" +#include "view/world/physicssystem.hpp" namespace OgreInit { @@ -44,6 +45,7 @@ namespace CS Files::ConfigurationManager mCfgMgr; CSMSettings::UserSettings mUserSettings; std::auto_ptr mOverlaySystem; + std::auto_ptr mPhysicsSystem; CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 827e266530..9ff24780c3 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -10,8 +10,6 @@ #include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" -#include "../world/physicssystem.hpp" - #include "elements.hpp" #include "terrainstorage.hpp" @@ -51,7 +49,7 @@ bool CSVRender::Cell::addObjects (int start, int end) std::string id = Misc::StringUtils::lowerCase (references.data ( references.index (i, idColumn)).toString().toUtf8().constData()); - mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics))); + mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false))); modified = true; } } @@ -60,8 +58,8 @@ bool CSVRender::Cell::addObjects (int start, int end) } CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, - const std::string& id, CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin) -: mData (data), mId (Misc::StringUtils::lowerCase (id)), mPhysics(physics) + const std::string& id, const Ogre::Vector3& origin) +: mData (data), mId (Misc::StringUtils::lowerCase (id)) { mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode->setPosition (origin); @@ -180,7 +178,7 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, for (std::map::iterator iter (ids.begin()); iter!=ids.end(); ++iter) { mObjects.insert (std::make_pair ( - iter->first, new Object (mData, mCellNode, iter->first, false, mPhysics))); + iter->first, new Object (mData, mCellNode, iter->first, false))); modified = true; } diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 5872cc7521..98056c3549 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -23,11 +23,6 @@ namespace CSMWorld class Data; } -namespace CSVWorld -{ - class PhysicsSystem; -} - namespace CSVRender { class Cell @@ -37,7 +32,6 @@ namespace CSVRender Ogre::SceneNode *mCellNode; std::map mObjects; std::auto_ptr mTerrain; - CSVWorld::PhysicsSystem *mPhysics; /// Ignored if cell does not have an object with the given ID. /// @@ -52,8 +46,7 @@ namespace CSVRender public: Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, - const std::string& id, CSVWorld::PhysicsSystem *physics, - const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); + const std::string& id, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); ~Cell(); diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index c973bdeae7..13266473e9 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -78,7 +78,7 @@ void CSVRender::Object::update() mObject = NifOgre::Loader::createObjects (mBase, "Meshes\\" + model); mObject->setVisibilityFlags (Element_Reference); - if (mPhysics && !mReferenceId.empty()) + if (!mReferenceId.empty()) { const CSMWorld::CellRef& reference = getReference(); @@ -92,7 +92,8 @@ void CSVRender::Object::update() Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.rot[1]), Ogre::Vector3::UNIT_Y); Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.rot[2]), Ogre::Vector3::UNIT_Z); - mPhysics->addObject("meshes\\" + model, mBase->getName(), reference.mScale, position, xr*yr*zr); + CSVWorld::PhysicsSystem::instance()->addObject("meshes\\" + model, + mBase->getName(), reference.mScale, position, xr*yr*zr); } } } @@ -131,9 +132,8 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const } CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, - const std::string& id, bool referenceable, CSVWorld::PhysicsSystem* physics, - bool forceBaseToZero) -: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics) + const std::string& id, bool referenceable, bool forceBaseToZero) +: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero) { mBase = cellNode->createChildSceneNode(); diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index eba2dc8148..6a8a933e51 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -16,11 +16,6 @@ namespace CSMWorld class CellRef; } -namespace CSVWorld -{ - class PhysicsSystem; -} - namespace CSVRender { class Object @@ -31,7 +26,6 @@ namespace CSVRender Ogre::SceneNode *mBase; NifOgre::ObjectScenePtr mObject; bool mForceBaseToZero; - CSVWorld::PhysicsSystem *mPhysics; /// Not implemented Object (const Object&); @@ -57,8 +51,7 @@ namespace CSVRender public: Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, - const std::string& id, bool referenceable, - CSVWorld::PhysicsSystem *physics = NULL, bool forceBaseToZero = false); + const std::string& id, bool referenceable, bool forceBaseToZero = false); /// \param forceBaseToZero If this is a reference ignore the coordinates and place /// it at 0, 0, 0 instead. diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index d2cc74587f..b7d53b9e3e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -110,7 +110,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() mCells.find (*iter)==mCells.end()) { Cell *cell = new Cell (mDocument.getData(), getSceneManager(), - iter->getId (mWorldspace), getPhysics()); + iter->getId (mWorldspace)); mCells.insert (std::make_pair (*iter, cell)); float height = cell->getTerrainHeightAt(Ogre::Vector3( @@ -198,7 +198,9 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) float mouseX = (float) event->x()/viewportWidth; float mouseY = (float) event->y()/viewportHeight; - getPhysics()->castRay(mouseX, mouseY, NULL, NULL, getCamera()); + // Need to set each time in case there are multiple subviews + CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager()); + CSVWorld::PhysicsSystem::instance()->castRay(mouseX, mouseY, NULL, NULL, getCamera()); flagAsModified(); #if 0 std::cout << "geometry: " + std::to_string(width()) + ", " + std::to_string(height()) << std::endl; @@ -219,7 +221,9 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event { std::cout << "double clicked" << std::endl; - getPhysics()->toggleDebugRendering(); + // Need to set each time in case there are multiple subviews + CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager()); + CSVWorld::PhysicsSystem::instance()->toggleDebugRendering(); } } diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index f972c6361b..75b4e93967 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -10,7 +10,7 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget *parent) : SceneWidget (parent), mData (data), - mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, NULL, true) + mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, true) { setNavigation (&mOrbit); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index bb7102f34d..cf46e52522 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -66,8 +66,7 @@ namespace CSVRender mOverlaySystem = OverlaySystem::instance().get(); mSceneMgr->addRenderQueueListener(mOverlaySystem); - // FIXME: singleton probably needed - mPhysics = new CSVWorld::PhysicsSystem(mSceneMgr); + CSVWorld::PhysicsSystem::instance()->setSceneManager(mSceneMgr); QTimer *timer = new QTimer (this); @@ -176,7 +175,6 @@ namespace CSVRender if (mSceneMgr) Ogre::Root::getSingleton().destroySceneManager (mSceneMgr); - delete mPhysics; } void SceneWidget::setVisibilityMask (unsigned int mask) @@ -212,11 +210,6 @@ namespace CSVRender return mViewport; } - CSVWorld::PhysicsSystem *SceneWidget::getPhysics() - { - return mPhysics; - } - Ogre::SceneManager *SceneWidget::getSceneManager() { return mSceneMgr; diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index a3dd9cc805..1adbf3f173 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -25,11 +25,6 @@ namespace CSVWidget class SceneToolbar; } -namespace CSVWorld -{ - class PhysicsSystem; -} - namespace CSVRender { class Navigation; @@ -63,8 +58,6 @@ namespace CSVRender Ogre::Viewport *getViewport(); - CSVWorld::PhysicsSystem *getPhysics(); - Ogre::SceneManager *getSceneManager(); Ogre::Camera *getCamera(); @@ -105,7 +98,6 @@ namespace CSVRender Ogre::RenderWindow* mWindow; Ogre::Viewport *mViewport; Ogre::OverlaySystem *mOverlaySystem; - CSVWorld::PhysicsSystem *mPhysics; Navigation *mNavigation; Lighting *mLighting; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 8012b1b246..aab3791fce 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -56,7 +56,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& update(); - mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, getPhysics())); + mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId)); } void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, @@ -98,7 +98,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorgetId(); - mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getPhysics())); + mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId)); update(); emit cellChanged(*data.begin()); diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp index 331625c842..70531a5595 100644 --- a/apps/opencs/view/world/physicssystem.cpp +++ b/apps/opencs/view/world/physicssystem.cpp @@ -39,11 +39,48 @@ namespace namespace CSVWorld { + PhysicsSystem *PhysicsSystem::mPhysicsSystemInstance = 0; + PhysicsSystem::PhysicsSystem(Ogre::SceneManager *sceneMgr) : mSceneMgr(sceneMgr) { + assert(!mPhysicsSystemInstance); + mPhysicsSystemInstance = this; + // Create physics. shapeLoader is deleted by the physic engine NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); + } + + PhysicsSystem::~PhysicsSystem() + { + delete mEngine; + } + + PhysicsSystem *PhysicsSystem::instance() + { + assert(mPhysicsSystemInstance); + return mPhysicsSystemInstance; + } + + void PhysicsSystem::addObject(const std::string &mesh, + const std::string &name, + float scale, + const Ogre::Vector3 &position, + const Ogre::Quaternion &rotation, + bool placeable) + { + //mHandleToMesh[name] = mesh; + + mEngine->createAndAdjustRigidBody(mesh, name, scale, position, rotation, + 0, // scaledBoxTranslation + 0, // boxRotation + true, // raycasting + placeable); + } + + void PhysicsSystem::setSceneManager(Ogre::SceneManager *sceneMgr) + { + mSceneMgr = sceneMgr; mEngine->setSceneManager(sceneMgr); // needed for toggleDebugRendering() @@ -102,27 +139,6 @@ namespace CSVWorld } } - PhysicsSystem::~PhysicsSystem() - { - delete mEngine; - } - - void PhysicsSystem::addObject(const std::string &mesh, - const std::string &name, - float scale, - const Ogre::Vector3 &position, - const Ogre::Quaternion &rotation, - bool placeable) - { - //mHandleToMesh[name] = mesh; - - mEngine->createAndAdjustRigidBody(mesh, name, scale, position, rotation, - 0, // scaledBoxTranslation - 0, // boxRotation - true, // raycasting - placeable); - } - void PhysicsSystem::removeObject(const std::string& name) { mEngine->removeRigidBody(name); @@ -131,6 +147,9 @@ namespace CSVWorld void PhysicsSystem::toggleDebugRendering() { + if(!mSceneMgr) + return; // FIXME: add a warning message + mEngine->toggleDebugRendering(); mEngine->stepSimulation(0.0167); // FIXME: DebugDrawer::step() not accessible } @@ -138,6 +157,9 @@ namespace CSVWorld std::pair PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera) { + if(!mSceneMgr) + return std::make_pair(false, Ogre::Vector3()); // FIXME: add a warning message + // using a really small value seems to mess up with the projections float nearClipDistance = camera->getNearClipDistance(); camera->setNearClipDistance(10.0f); // arbitrary number diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp index ec0657ee24..ec4ae63e19 100644 --- a/apps/opencs/view/world/physicssystem.hpp +++ b/apps/opencs/view/world/physicssystem.hpp @@ -25,6 +25,7 @@ namespace CSVWorld { class PhysicsSystem { + static PhysicsSystem *mPhysicsSystemInstance; //std::map mHandleToMesh; OEngine::Physic::PhysicEngine* mEngine; Ogre::SceneManager *mSceneMgr; @@ -32,9 +33,13 @@ namespace CSVWorld public: - PhysicsSystem(Ogre::SceneManager *sceneMgr); + PhysicsSystem(Ogre::SceneManager *sceneMgr = NULL); ~PhysicsSystem(); + static PhysicsSystem *instance(); + + void setSceneManager(Ogre::SceneManager *sceneMgr); + void addObject(const std::string &mesh, const std::string &name, float scale,