diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 6976aec42..4f6b2a875 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -66,7 +66,7 @@ opencs_units (view/world opencs_units_noqt (view/world subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate - scripthighlighter idvalidator dialoguecreator physicssystem + scripthighlighter idvalidator dialoguecreator ) opencs_units (view/widget @@ -81,7 +81,7 @@ opencs_units (view/render opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight - lightingbright object cell terrainstorage textoverlay mousestate + lightingbright object cell terrainstorage textoverlay ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 2a5fa7746..7f3d98d0c 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -9,8 +9,6 @@ #include #endif -#include "../../view/world/physicssystem.hpp" - void CSMDoc::Document::addGmsts() { static const char *gmstFloats[] = @@ -2255,7 +2253,7 @@ CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationM mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), mSaving (*this, mProjectPath, encoding), - mRunner (mProjectPath), mPhysics(boost::shared_ptr()) + mRunner (mProjectPath) { if (mContentFiles.empty()) throw std::runtime_error ("Empty content file sequence"); @@ -2471,11 +2469,3 @@ void CSMDoc::Document::progress (int current, int max, int type) { emit progress (current, max, type, 1, this); } - -boost::shared_ptr CSMDoc::Document::getPhysics () -{ - if(!mPhysics) - mPhysics = boost::shared_ptr (new CSVWorld::PhysicsSystem()); - - return mPhysics; -} diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 2d42e9903..292b292df 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -46,11 +46,6 @@ namespace CSMWorld class ResourcesManager; } -namespace CSVWorld -{ - class PhysicsSystem; -} - namespace CSMDoc { class Document : public QObject @@ -70,7 +65,6 @@ namespace CSMDoc boost::filesystem::path mResDir; Blacklist mBlacklist; Runner mRunner; - boost::shared_ptr mPhysics; // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. @@ -145,8 +139,6 @@ namespace CSMDoc QTextDocument *getRunLog(); - boost::shared_ptr getPhysics(); - signals: void stateChanged (int state, CSMDoc::Document *document); diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 72ceb654a..28ce1dd6c 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -10,7 +10,6 @@ #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" -#include "../world/physicssystem.hpp" #include "elements.hpp" #include "terrainstorage.hpp" @@ -60,8 +59,8 @@ bool CSVRender::Cell::addObjects (int start, int end) } CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, - const std::string& id, boost::shared_ptr physics, const Ogre::Vector3& origin) -: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics), mX(0), mY(0) + const std::string& id, const Ogre::Vector3& origin) +: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mX(0), mY(0) { mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode->setPosition (origin); @@ -89,16 +88,16 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, float worldsize = ESM::Land::REAL_SIZE; mX = esmLand->mX; mY = esmLand->mY; - mPhysics->addHeightField(sceneManager, - esmLand->mLandData->mHeights, mX, mY, 0, worldsize / (verts-1), verts); + //mPhysics->addHeightField(sceneManager, + // esmLand->mLandData->mHeights, mX, mY, 0, worldsize / (verts-1), verts); } } } CSVRender::Cell::~Cell() { - if (mTerrain.get()) - mPhysics->removeHeightField(mSceneMgr, mX, mY); + //if (mTerrain.get()) + // mPhysics->removeHeightField(mSceneMgr, mX, mY); for (std::map::iterator iter (mObjects.begin()); iter!=mObjects.end(); ++iter) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 73d794948..8c7d7e23a 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -28,11 +28,6 @@ namespace CSMWorld class Data; } -namespace CSVWorld -{ - class PhysicsSystem; -} - namespace CSVRender { class Cell @@ -42,7 +37,6 @@ namespace CSVRender Ogre::SceneNode *mCellNode; std::map mObjects; std::auto_ptr mTerrain; - boost::shared_ptr mPhysics; Ogre::SceneManager *mSceneMgr; int mX; int mY; @@ -59,8 +53,7 @@ namespace CSVRender public: - Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id, - boost::shared_ptr physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); + Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); ~Cell(); diff --git a/apps/opencs/view/render/mousestate.cpp b/apps/opencs/view/render/mousestate.cpp deleted file mode 100644 index 8edd9d58f..000000000 --- a/apps/opencs/view/render/mousestate.cpp +++ /dev/null @@ -1,463 +0,0 @@ -#include "mousestate.hpp" - -#include -#include -#include -#include - -#include -#include -#include - -#include "../../model/settings/usersettings.hpp" -#include "../../model/world/commands.hpp" -#include "../../model/world/idtable.hpp" -#include "../../model/world/universalid.hpp" -#include "../world/physicssystem.hpp" - -#include "elements.hpp" -#include "worldspacewidget.hpp" - -namespace CSVRender -{ - // mouse picking - // FIXME: need to virtualise mouse buttons - // - // State machine: - // - // [default] mousePressEvent->check if the mouse is pointing at an object - // if yes, create collision planes then go to [grab] - // else check for terrain - // - // [grab] mouseReleaseEvent->if same button and new obj, go to [edit] - // mouseMoveEvent->if same button, go to [drag] - // other mouse events or buttons, go back to [default] (i.e. like 'cancel') - // - // [drag] mouseReleaseEvent->if same button, place the object at the new - // location, update the document then go to [edit] - // mouseMoveEvent->update position to the user based on ray to the collision - // planes and render the object at the new location, but do not update - // the document yet - // - // [edit] TODO, probably fine positional adjustments or rotations; clone/delete? - // - // - // press press (obj) - // [default] --------> [grab] <-------------------- [edit] - // ^ (obj) | | ------> [drag] -----> ^ - // | | | move ^ | release | - // | | | | | | - // | | | +-+ | - // | | | move | - // +----------------+ +--------------------------+ - // release release - // (same obj) (new obj) - // - // - - MouseState::MouseState(WorldspaceWidget *parent) - : mParent(parent), mPhysics(parent->mDocument.getPhysics()), mSceneManager(0/*parent->getSceneManager()*/) - , mCurrentObj(""), mMouseState(Mouse_Default), mOldPos(0,0), mMouseEventTimer(0), mPlane(0) - , mGrabbedSceneNode(""), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3()) - , mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f) - , mColIndexPosX(0), mColIndexPosY(0), mColIndexPosZ(0), mIdTableModel(0) - { - const CSMWorld::RefCollection& references = mParent->mDocument.getData().getReferences(); - - mColIndexPosX = references.findColumnIndex(CSMWorld::Columns::ColumnId_PositionXPos); - mColIndexPosY = references.findColumnIndex(CSMWorld::Columns::ColumnId_PositionYPos); - mColIndexPosZ = references.findColumnIndex(CSMWorld::Columns::ColumnId_PositionZPos); - - mIdTableModel = static_cast( - mParent->mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_Reference)); - - mMouseEventTimer = new QElapsedTimer(); - mMouseEventTimer->invalidate(); - - std::pair planeRes = planeAxis(); - mPlane = new Ogre::Plane(planeRes.first, 0); - Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createPlane("mouse", - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - *mPlane, - 300000,300000, // FIXME: use far clip dist? - 1,1, // segments - true, // normals - 1, // numTexCoordSets - 1,1, // uTile, vTile - planeRes.second // upVector - ); - } - - MouseState::~MouseState () - { - delete mMouseEventTimer; - delete mPlane; - } - - void MouseState::mouseMoveEvent (QMouseEvent *event) - { - switch(mMouseState) - { - case Mouse_Grab: - { - // check if min elapsed time to stop false detection of drag - if(!mMouseEventTimer->isValid() || !mMouseEventTimer->hasExpired(100)) // ms - break; - - mMouseEventTimer->invalidate(); - mMouseState = Mouse_Drag; - - /* FALL_THROUGH */ - } - case Mouse_Drag: - { - if(event->pos() != mOldPos) // TODO: maybe don't update less than a quantum? - { - mOldPos = event->pos(); - - // ray test against the plane to provide feedback to the user the - // relative movement of the object on the x-y plane - std::pair planeResult = mousePositionOnPlane(event->pos(), *mPlane); - if(planeResult.first) - { - if(mGrabbedSceneNode != "") - { - std::pair planeRes = planeAxis(); - Ogre::Vector3 pos = mOrigObjPos + planeRes.first*mOffset; - mSceneManager->getSceneNode(mGrabbedSceneNode)->setPosition(pos+planeResult.second-mOrigMousePos); - mCurrentMousePos = planeResult.second; - mPhysics->moveSceneNodes(mGrabbedSceneNode, pos+planeResult.second-mOrigMousePos); - updateSceneWidgets(); - } - } - } - break; - } - case Mouse_Edit: - case Mouse_Default: - { - break; // error event, ignore - } - /* NO_DEFAULT_CASE */ - } - } - - void MouseState::mousePressEvent (QMouseEvent *event) - { - switch(mMouseState) - { - case Mouse_Grab: - case Mouse_Drag: - { - break; - } - case Mouse_Edit: - case Mouse_Default: - { - if(event->buttons() & Qt::RightButton) - { - std::pair result = objectUnderCursor(event->x(), event->y()); - if(result.first == "") - break; - - mGrabbedSceneNode = result.first; - // ray test agaist the plane to get a starting position of the - // mouse in relation to the object position - std::pair planeRes = planeAxis(); - mPlane->redefine(planeRes.first, result.second); - std::pair planeResult = mousePositionOnPlane(event->pos(), *mPlane); - if(planeResult.first) - { - mOrigMousePos = planeResult.second; - mCurrentMousePos = planeResult.second; - mOffset = 0.0f; - } - - mOrigObjPos = mSceneManager->getSceneNode(mGrabbedSceneNode)->getPosition(); - mMouseEventTimer->start(); - - mMouseState = Mouse_Grab; - } - break; - } - /* NO_DEFAULT_CASE */ - } - } - - void MouseState::mouseReleaseEvent (QMouseEvent *event) - { - switch(mMouseState) - { - case Mouse_Grab: - { - std::pair result = objectUnderCursor(event->x(), event->y()); - if(result.first != "") - { - if(result.first == mCurrentObj) - { - // unselect object - mMouseState = Mouse_Default; - mCurrentObj = ""; - } - else - { - // select object - mMouseState = Mouse_Edit; - mCurrentObj = result.first; - - } - } - break; - } - case Mouse_Drag: - { - // final placement - std::pair planeResult = mousePositionOnPlane(event->pos(), *mPlane); - if(planeResult.first) - { - if(mGrabbedSceneNode != "") - { - std::pair planeRes = planeAxis(); - Ogre::Vector3 pos = mOrigObjPos+planeRes.first*mOffset+planeResult.second-mOrigMousePos; - // use the saved scene node name since the physics model has not moved yet - std::string referenceId = mPhysics->sceneNodeToRefId(mGrabbedSceneNode); - - mParent->mDocument.getUndoStack().beginMacro (QObject::tr("Move Object")); - mParent->mDocument.getUndoStack().push(new CSMWorld::ModifyCommand(*mIdTableModel, - mIdTableModel->getModelIndex(referenceId, mColIndexPosX), pos.x)); - mParent->mDocument.getUndoStack().push(new CSMWorld::ModifyCommand(*mIdTableModel, - mIdTableModel->getModelIndex(referenceId, mColIndexPosY), pos.y)); - mParent->mDocument.getUndoStack().push(new CSMWorld::ModifyCommand(*mIdTableModel, - mIdTableModel->getModelIndex(referenceId, mColIndexPosZ), pos.z)); - mParent->mDocument.getUndoStack().endMacro(); - - // FIXME: highlight current object? - //mCurrentObj = mGrabbedSceneNode; // FIXME: doesn't work? - mCurrentObj = ""; // whether the object is selected - - mMouseState = Mouse_Edit; - - // reset states - mCurrentMousePos = Ogre::Vector3(); // mouse pos to use in wheel event - mOrigMousePos = Ogre::Vector3(); // starting pos of mouse in world space - mOrigObjPos = Ogre::Vector3(); // starting pos of object in world space - mGrabbedSceneNode = ""; // id of the object - mOffset = 0.0f; // used for z-axis movement - mOldPos = QPoint(0, 0); // to calculate relative movement of mouse - } - } - break; - } - case Mouse_Edit: - case Mouse_Default: - { - // probably terrain, check - std::pair result = terrainUnderCursor(event->x(), event->y()); - if(result.first != "") - { - // FIXME: terrain editing goes here - } - break; - } - /* NO_DEFAULT_CASE */ - } - mMouseEventTimer->invalidate(); - } - - void MouseState::mouseDoubleClickEvent (QMouseEvent *event) - { - event->ignore(); - //mPhysics->toggleDebugRendering(mSceneManager); - //mParent->flagAsModified(); - } - - bool MouseState::wheelEvent (QWheelEvent *event) - { - switch(mMouseState) - { - case Mouse_Grab: - mMouseState = Mouse_Drag; - - /* FALL_THROUGH */ - case Mouse_Drag: - { - // move the object along the z axis during Mouse_Drag or Mouse_Grab - if (event->delta()) - { - // seems positive is up and negative is down - mOffset += (event->delta()/1); // FIXME: arbitrary number, make config option? - - std::pair planeRes = planeAxis(); - Ogre::Vector3 pos = mOrigObjPos + planeRes.first*mOffset; - mSceneManager->getSceneNode(mGrabbedSceneNode)->setPosition(pos+mCurrentMousePos-mOrigMousePos); - mPhysics->moveSceneNodes(mGrabbedSceneNode, pos+mCurrentMousePos-mOrigMousePos); - updateSceneWidgets(); - } - break; - } - case Mouse_Edit: - case Mouse_Default: - { - return false; - } - /* NO_DEFAULT_CASE */ - } - - return true; - } - - void MouseState::cancelDrag() - { - switch(mMouseState) - { - case Mouse_Grab: - case Mouse_Drag: - { - // cancel operation & return the object to the original position - mSceneManager->getSceneNode(mGrabbedSceneNode)->setPosition(mOrigObjPos); - // update all SceneWidgets and their SceneManagers - mPhysics->moveSceneNodes(mGrabbedSceneNode, mOrigObjPos); - updateSceneWidgets(); - - // reset states - mMouseState = Mouse_Default; - mCurrentMousePos = Ogre::Vector3(); - mOrigMousePos = Ogre::Vector3(); - mOrigObjPos = Ogre::Vector3(); - mGrabbedSceneNode = ""; - mCurrentObj = ""; - mOldPos = QPoint(0, 0); - mMouseEventTimer->invalidate(); - mOffset = 0.0f; - - break; - } - case Mouse_Edit: - case Mouse_Default: - { - break; - } - /* NO_DEFAULT_CASE */ - } - } - - //plane Z, upvector Y, mOffset z : x-y plane, wheel up/down - //plane Y, upvector X, mOffset y : y-z plane, wheel left/right - //plane X, upvector Y, mOffset x : x-z plane, wheel closer/further - std::pair MouseState::planeAxis() - { - const bool screenCoord = true; - Ogre::Vector3 dir = getCamera()->getDerivedDirection(); - - QString wheelDir = "Closer/Further"; - if(wheelDir == "Left/Right") - { - if(screenCoord) - return std::make_pair(getCamera()->getDerivedRight(), getCamera()->getDerivedUp()); - else - return std::make_pair(Ogre::Vector3::UNIT_Y, Ogre::Vector3::UNIT_Z); - } - else if(wheelDir == "Up/Down") - { - if(screenCoord) - return std::make_pair(getCamera()->getDerivedUp(), Ogre::Vector3(-dir.x, -dir.y, -dir.z)); - else - return std::make_pair(Ogre::Vector3::UNIT_Z, Ogre::Vector3::UNIT_X); - } - else - { - if(screenCoord) - return std::make_pair(Ogre::Vector3(-dir.x, -dir.y, -dir.z), getCamera()->getDerivedRight()); - else - return std::make_pair(Ogre::Vector3::UNIT_X, Ogre::Vector3::UNIT_Y); - } - } - - std::pair MouseState::mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane) - { - // using a really small value seems to mess up with the projections - float nearClipDistance = getCamera()->getNearClipDistance(); // save existing - getCamera()->setNearClipDistance(10.0f); // arbitrary number - Ogre::Ray mouseRay = getCamera()->getCameraToViewportRay( - (float) pos.x() / getViewport()->getActualWidth(), - (float) pos.y() / getViewport()->getActualHeight()); - getCamera()->setNearClipDistance(nearClipDistance); // restore - std::pair planeResult = mouseRay.intersects(plane); - - if(planeResult.first) - return std::make_pair(true, mouseRay.getPoint(planeResult.second)); - else - return std::make_pair(false, Ogre::Vector3()); // should only happen if the plane is too small - } - - std::pair MouseState::terrainUnderCursor(const int mouseX, const int mouseY) - { - if(!getViewport()) - return std::make_pair("", Ogre::Vector3()); - - float x = (float) mouseX / getViewport()->getActualWidth(); - float y = (float) mouseY / getViewport()->getActualHeight(); - - std::pair result = mPhysics->castRay(x, y, mSceneManager, getCamera()); - if(result.first != "") - { - // FIXME: is there a better way to distinguish terrain from objects? - QString name = QString(result.first.c_str()); - if(name.contains(QRegExp("^HeightField"))) - { - return result; - } - } - - return std::make_pair("", Ogre::Vector3()); - } - - std::pair MouseState::objectUnderCursor(const int mouseX, const int mouseY) - { - if(!getViewport()) - return std::make_pair("", Ogre::Vector3()); - - float x = (float) mouseX / getViewport()->getActualWidth(); - float y = (float) mouseY / getViewport()->getActualHeight(); - - std::pair result = mPhysics->castRay(x, y, mSceneManager, getCamera()); - if(result.first != "") - { - // NOTE: anything not terrain is assumed to be an object - QString name = QString(result.first.c_str()); - if(!name.contains(QRegExp("^HeightField"))) - { - uint32_t visibilityMask = getViewport()->getVisibilityMask(); - bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference); - - if(!ignoreObjects && mSceneManager->hasSceneNode(result.first)) - { - return result; - } - } - } - - return std::make_pair("", Ogre::Vector3()); - } - - void MouseState::updateSceneWidgets() - { - std::map sceneWidgets = mPhysics->sceneWidgets(); - - std::map::iterator iter = sceneWidgets.begin(); - for(; iter != sceneWidgets.end(); ++iter) - { - //(*iter).second->updateScene(); - } - } - - Ogre::Camera *MouseState::getCamera() - { - return 0;//mParent->getCamera(); - } - - Ogre::Viewport *MouseState::getViewport() - { - return 0;//mParent->getCamera()->getViewport(); - } -} diff --git a/apps/opencs/view/render/mousestate.hpp b/apps/opencs/view/render/mousestate.hpp deleted file mode 100644 index 70e18427f..000000000 --- a/apps/opencs/view/render/mousestate.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef OPENCS_VIEW_MOUSESTATE_H -#define OPENCS_VIEW_MOUSESTATE_H - -#include -#include -#include -#include - -class QElapsedTimer; -class QMouseEvent; -class QWheelEvent; - -namespace Ogre -{ - class Plane; - class SceneManager; - class Camera; - class Viewport; -} - -namespace CSVWorld -{ - class PhysicsSystem; -} - -namespace CSMWorld -{ - class IdTable; -} - -namespace CSVRender -{ - class WorldspaceWidget; - - class MouseState - { - enum MouseStates - { - Mouse_Grab, - Mouse_Drag, - Mouse_Edit, - Mouse_Default - }; - MouseStates mMouseState; - - WorldspaceWidget *mParent; - boost::shared_ptr mPhysics; - Ogre::SceneManager *mSceneManager; // local copy - - QPoint mOldPos; - std::string mCurrentObj; - std::string mGrabbedSceneNode; - QElapsedTimer *mMouseEventTimer; - Ogre::Plane *mPlane; - Ogre::Vector3 mOrigObjPos; - Ogre::Vector3 mOrigMousePos; - Ogre::Vector3 mCurrentMousePos; - float mOffset; - - CSMWorld::IdTable *mIdTableModel; - int mColIndexPosX; - int mColIndexPosY; - int mColIndexPosZ; - - public: - - MouseState(WorldspaceWidget *parent); - ~MouseState(); - - void mouseMoveEvent (QMouseEvent *event); - void mousePressEvent (QMouseEvent *event); - void mouseReleaseEvent (QMouseEvent *event); - void mouseDoubleClickEvent (QMouseEvent *event); - bool wheelEvent (QWheelEvent *event); - - void cancelDrag(); - - private: - - std::pair mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane); - std::pair terrainUnderCursor(const int mouseX, const int mouseY); - std::pair objectUnderCursor(const int mouseX, const int mouseY); - std::pair planeAxis(); - void updateSceneWidgets(); - - Ogre::Camera *getCamera(); // friend access - Ogre::Viewport *getViewport(); // friend access - }; -} - -#endif // OPENCS_VIEW_MOUSESTATE_H diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index bd44ba577..9bc7aa260 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -6,8 +6,6 @@ #include "../../model/world/ref.hpp" #include "../../model/world/refidcollection.hpp" -#include "../world/physicssystem.hpp" - #include #include "elements.hpp" @@ -63,25 +61,6 @@ void CSVRender::Object::update() mBaseNode->addChild(loader.load(file)); //mObject->setVisibilityFlags (Element_Reference); - - /* - if (mPhysics && !mReferenceId.empty()) - { - const CSMWorld::CellRef& reference = getReference(); - - // position - Ogre::Vector3 position; - if (!mForceBaseToZero) - position = Ogre::Vector3(reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]); - - // orientation - Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.rot[0]), Ogre::Vector3::UNIT_X); - 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(), mReferenceId, reference.mScale, position, xr*yr*zr); - } - */ } } @@ -121,9 +100,8 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const } CSVRender::Object::Object (const VFS::Manager* vfs, const CSMWorld::Data& data, osg::Group* parentNode, - const std::string& id, bool referenceable, boost::shared_ptr physics, - bool forceBaseToZero) -: mVFS(vfs), mData (data), mBaseNode(0), mParentNode(parentNode), mForceBaseToZero (forceBaseToZero), mPhysics(physics) + const std::string& id, bool referenceable, bool forceBaseToZero) +: mVFS(vfs), mData (data), mBaseNode(0), mParentNode(parentNode), mForceBaseToZero (forceBaseToZero) { mBaseNode = new osg::Group; parentNode->addChild(mBaseNode); diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 8e9598bbf..431867d6b 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -40,7 +40,6 @@ namespace CSVRender osg::Group* mParentNode; const VFS::Manager* mVFS; bool mForceBaseToZero; - boost::shared_ptr mPhysics; /// Not implemented Object (const Object&); @@ -64,7 +63,6 @@ namespace CSVRender Object (const VFS::Manager* vfs, const CSMWorld::Data& data, osg::Group *cellNode, const std::string& id, bool referenceable, - boost::shared_ptr physics = boost::shared_ptr (), 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 84a5a5665..ca4678d49 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -112,7 +112,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() { #if 0 Cell *cell = new Cell (mDocument.getData(), getSceneManager(), - iter->getId (mWorldspace), mDocument.getPhysics()); + iter->getId (mWorldspace)); mCells.insert (std::make_pair (*iter, cell)); float height = cell->getTerrainHeightAt(Ogre::Vector3( diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 3be791f23..fd63567c7 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -49,7 +49,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& update(); - //mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, document.getPhysics())); + //mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId)); } void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, @@ -91,7 +91,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorgetId(); - //mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getDocument().getPhysics())); + //mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId)); update(); emit cellChanged(*data.begin()); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 5ae5c8177..68a3acdb9 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -16,13 +16,11 @@ #include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetoolrun.hpp" -#include "../world/physicssystem.hpp" - #include "elements.hpp" #include "editmode.hpp" CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) -: SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0), mPhysics(boost::shared_ptr()), mMouse(0), +: SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0), mMouse(0), mInteractionMask (0) { setAcceptDrops(true); @@ -55,15 +53,12 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int))); - mPhysics = document.getPhysics(); // create physics if one doesn't exist - //mPhysics->addSceneManager(getSceneManager(), this); - mMouse = new MouseState(this); + //mMouse = new MouseState(this); } CSVRender::WorldspaceWidget::~WorldspaceWidget () { - delete mMouse; - //mPhysics->removeSceneManager(getSceneManager()); + //delete mMouse; } void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) @@ -370,7 +365,7 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) { if(event->buttons() & Qt::RightButton) { - mMouse->mouseMoveEvent(event); + //mMouse->mouseMoveEvent(event); } SceneWidget::mouseMoveEvent(event); } @@ -379,7 +374,7 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) { if(event->buttons() & Qt::RightButton) { - mMouse->mousePressEvent(event); + //mMouse->mousePressEvent(event); } //SceneWidget::mousePressEvent(event); } @@ -395,7 +390,7 @@ void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) return; } */ - mMouse->mouseReleaseEvent(event); + //mMouse->mouseReleaseEvent(event); } SceneWidget::mouseReleaseEvent(event); } @@ -404,14 +399,14 @@ void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event) { if(event->button() == Qt::RightButton) { - mMouse->mouseDoubleClickEvent(event); + //mMouse->mouseDoubleClickEvent(event); } //SceneWidget::mouseDoubleClickEvent(event); } void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) { - if(!mMouse->wheelEvent(event)) + //if(!mMouse->wheelEvent(event)) SceneWidget::wheelEvent(event); } @@ -419,7 +414,7 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) { if(event->key() == Qt::Key_Escape) { - mMouse->cancelDrag(); + //mMouse->cancelDrag(); } else SceneWidget::keyPressEvent(event); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index b19197e36..ea344f04a 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -4,7 +4,6 @@ #include #include "scenewidget.hpp" -#include "mousestate.hpp" #include "navigation1st.hpp" #include "navigationfree.hpp" @@ -25,13 +24,10 @@ namespace CSVWidget class SceneToolRun; } -namespace CSVWorld -{ - class PhysicsSystem; -} - namespace CSVRender { + class MouseState; + class WorldspaceWidget : public SceneWidget { Q_OBJECT @@ -42,7 +38,6 @@ namespace CSVRender CSVWidget::SceneToolToggle2 *mSceneElements; CSVWidget::SceneToolRun *mRun; CSMDoc::Document& mDocument; - boost::shared_ptr mPhysics; MouseState *mMouse; unsigned int mInteractionMask; diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp deleted file mode 100644 index 4e23c185a..000000000 --- a/apps/opencs/view/world/physicssystem.cpp +++ /dev/null @@ -1,325 +0,0 @@ -#include "physicssystem.hpp" - -#include - -#include -#include -#include - -#include -#include -#include "../../model/settings/usersettings.hpp" -#include "../render/elements.hpp" - -namespace CSVWorld -{ - PhysicsSystem::PhysicsSystem() - { - // Create physics. shapeLoader is deleted by the physic engine - //NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(true); - //mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); - mEngine = 0; - } - - PhysicsSystem::~PhysicsSystem() - { - delete mEngine; - } - - // looks up the scene manager based on the scene node name (inefficient) - // NOTE: referenceId is assumed to be unique per document - // NOTE: searching is done here rather than after rayTest, hence slower to load but - // faster to find (guessing, not verified w/ perf test) - void PhysicsSystem::addObject(const std::string &mesh, - const std::string &sceneNodeName, const std::string &referenceId, float scale, - const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, bool placeable) - { - Ogre::SceneManager *sceneManager = findSceneManager(sceneNodeName); - if(sceneManager) - { - // update maps (NOTE: sometimes replaced) - mSceneNodeToRefId[sceneNodeName] = referenceId; - mSceneNodeToMesh[sceneNodeName] = mesh; - mRefIdToSceneNode[referenceId][sceneManager] = sceneNodeName; - } - else - { - std::cerr << "Attempt to add an object without a corresponding SceneManager: " - + referenceId + " : " + sceneNodeName << std::endl; - return; - } - - // update physics, only one physics model per referenceId - if(mEngine->getRigidBody(referenceId, true) == NULL) - { - mEngine->createAndAdjustRigidBody(mesh, - referenceId, scale, position, rotation, - 0, // scaledBoxTranslation - 0, // boxRotation - true, // raycasting - placeable); - } - } - - // normal delete (e.g closing a scene subview or ~Object()) - // the scene node is destroyed so the mappings should be removed - // - // TODO: should think about using some kind of reference counting within RigidBody - void PhysicsSystem::removeObject(const std::string &sceneNodeName) - { - std::string referenceId = mSceneNodeToRefId[sceneNodeName]; - - if(referenceId != "") - { - mSceneNodeToRefId.erase(sceneNodeName); - mSceneNodeToMesh.erase(sceneNodeName); - - // find which SceneManager has this object - Ogre::SceneManager *sceneManager = findSceneManager(sceneNodeName); - if(!sceneManager) - { - std::cerr << "Attempt to remove an object without a corresponding SceneManager: " - + sceneNodeName << std::endl; - return; - } - - // illustration: erase the object "K" from the object map - // - // RidigBody SubView Ogre - // --------------- -------------- ------------- - // ReferenceId "A" (SceneManager X SceneNode "J") - // (SceneManager Y SceneNode "K") <--- erase - // (SceneManager Z SceneNode "L") - // - // ReferenceId "B" (SceneManager X SceneNode "M") - // (SceneManager Y SceneNode "N") <--- notice not deleted - // (SceneManager Z SceneNode "O") - std::map >::iterator itRef = - mRefIdToSceneNode.begin(); - for(; itRef != mRefIdToSceneNode.end(); ++itRef) - { - if((*itRef).second.find(sceneManager) != (*itRef).second.end()) - { - (*itRef).second.erase(sceneManager); - break; - } - } - - // check whether the physics model should be deleted - if(mRefIdToSceneNode.find(referenceId) == mRefIdToSceneNode.end()) - { - mEngine->removeRigidBody(referenceId); - mEngine->deleteRigidBody(referenceId); - } - } - } - - // Object::clear() is called when reference data is changed. It clears all - // contents of the SceneNode and removes the physics object - // - // A new physics object will be created and assigned to this sceneNodeName by - // Object::update() - void PhysicsSystem::removePhysicsObject(const std::string &sceneNodeName) - { - std::string referenceId = mSceneNodeToRefId[sceneNodeName]; - - if(referenceId != "") - { - mEngine->removeRigidBody(referenceId); - mEngine->deleteRigidBody(referenceId); - } - } - - void PhysicsSystem::replaceObject(const std::string &sceneNodeName, float scale, - const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, bool placeable) - { - std::string referenceId = mSceneNodeToRefId[sceneNodeName]; - std::string mesh = mSceneNodeToMesh[sceneNodeName]; - - if(referenceId != "") - { - // delete the physics object - mEngine->removeRigidBody(referenceId); - mEngine->deleteRigidBody(referenceId); - - // create a new physics object - mEngine->createAndAdjustRigidBody(mesh, referenceId, scale, position, rotation, - 0, 0, true, placeable); - - // update other scene managers if they have the referenceId - // FIXME: rotation or scale not updated - moveSceneNodeImpl(sceneNodeName, referenceId, position); - } - } - - // FIXME: adjustRigidBody() seems to lose objects, work around by deleting and recreating objects - void PhysicsSystem::moveObject(const std::string &sceneNodeName, - const Ogre::Vector3 &position, const Ogre::Quaternion &rotation) - { - mEngine->adjustRigidBody(mEngine->getRigidBody(sceneNodeName, true /*raycasting*/), - position, rotation); - } - - void PhysicsSystem::moveSceneNodeImpl(const std::string sceneNodeName, - const std::string referenceId, const Ogre::Vector3 &position) - { - std::map::const_iterator iter = mSceneWidgets.begin(); - for(; iter != mSceneWidgets.end(); ++iter) - { - std::string name = refIdToSceneNode(referenceId, (*iter).first); - if(name != sceneNodeName && (*iter).first->hasSceneNode(name)) - { - (*iter).first->getSceneNode(name)->setPosition(position); - } - } - } - - void PhysicsSystem::moveSceneNodes(const std::string sceneNodeName, const Ogre::Vector3 &position) - { - moveSceneNodeImpl(sceneNodeName, sceneNodeToRefId(sceneNodeName), position); - } - - void PhysicsSystem::addHeightField(Ogre::SceneManager *sceneManager, - float* heights, int x, int y, float yoffset, float triSize, float sqrtVerts) - { - std::string name = "HeightField_" - + QString::number(x).toStdString() + "_" + QString::number(y).toStdString(); - - if(mTerrain.find(name) == mTerrain.end()) - mEngine->addHeightField(heights, x, y, yoffset, triSize, sqrtVerts); - - mTerrain.insert(std::pair(name, sceneManager)); - } - - void PhysicsSystem::removeHeightField(Ogre::SceneManager *sceneManager, int x, int y) - { - std::string name = "HeightField_" - + QString::number(x).toStdString() + "_" + QString::number(y).toStdString(); - - if(mTerrain.count(name) == 1) - mEngine->removeHeightField(x, y); - - std::multimap::iterator iter = mTerrain.begin(); - for(; iter != mTerrain.end(); ++iter) - { - if((*iter).second == sceneManager) - { - mTerrain.erase(iter); - break; - } - } - } - - // sceneMgr: to lookup the scene node name from the object's referenceId - // camera: primarily used to get the visibility mask for the viewport - // - // returns the found object's scene node name and its position in the world space - // - // WARNING: far clip distance is a global setting, if it changes in future - // this method will need to be updated - std::pair PhysicsSystem::castRay(float mouseX, - float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera) - { - // NOTE: there could be more than one camera for the scene manager - // TODO: check whether camera belongs to sceneMgr - if(!sceneMgr || !camera || !camera->getViewport()) - return std::make_pair("", Ogre::Vector3(0,0,0)); // FIXME: this should be an exception - - // using a really small value seems to mess up with the projections - float nearClipDistance = camera->getNearClipDistance(); // save existing - camera->setNearClipDistance(10.0f); // arbitrary number - Ogre::Ray ray = camera->getCameraToViewportRay(mouseX, mouseY); - camera->setNearClipDistance(nearClipDistance); // restore - - Ogre::Vector3 from = ray.getOrigin(); - CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); - float farClipDist = userSettings.setting("Scene/far clip distance", QString("300000")).toFloat(); - Ogre::Vector3 to = ray.getPoint(farClipDist); - - btVector3 _from, _to; - _from = btVector3(from.x, from.y, from.z); - _to = btVector3(to.x, to.y, to.z); - - uint32_t visibilityMask = camera->getViewport()->getVisibilityMask(); - bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain); - bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference); - - Ogre::Vector3 norm; // not used - std::pair result = - mEngine->rayTest(_from, _to, !ignoreObjects, ignoreHeightMap, &norm); - - // result.first is the object's referenceId - if(result.first == "") - return std::make_pair("", Ogre::Vector3(0,0,0)); - else - { - std::string name = refIdToSceneNode(result.first, sceneMgr); - if(name == "") - name = result.first; - else - name = refIdToSceneNode(result.first, sceneMgr); - - return std::make_pair(name, ray.getPoint(farClipDist*result.second)); - } - } - - std::string PhysicsSystem::refIdToSceneNode(std::string referenceId, Ogre::SceneManager *sceneMgr) - { - return mRefIdToSceneNode[referenceId][sceneMgr]; - } - - std::string PhysicsSystem::sceneNodeToRefId(std::string sceneNodeName) - { - return mSceneNodeToRefId[sceneNodeName]; - } - - void PhysicsSystem::addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget *sceneWidget) - { - mSceneWidgets[sceneMgr] = sceneWidget; - - mEngine->createDebugDraw(sceneMgr); - } - - std::map PhysicsSystem::sceneWidgets() - { - return mSceneWidgets; - } - - void PhysicsSystem::removeSceneManager(Ogre::SceneManager *sceneMgr) - { - mEngine->removeDebugDraw(sceneMgr); - - mSceneWidgets.erase(sceneMgr); - } - - Ogre::SceneManager *PhysicsSystem::findSceneManager(std::string sceneNodeName) - { - std::map::const_iterator iter = mSceneWidgets.begin(); - for(; iter != mSceneWidgets.end(); ++iter) - { - if((*iter).first->hasSceneNode(sceneNodeName)) - { - return (*iter).first; - } - } - - return NULL; - } - - void PhysicsSystem::toggleDebugRendering(Ogre::SceneManager *sceneMgr) - { - // FIXME: should check if sceneMgr is in the list - if(!sceneMgr) - return; - - CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); - if(!(userSettings.setting("debug/mouse-picking", QString("false")) == "true" ? true : false)) - { - std::cerr << "Turn on mouse-picking debug option to see collision shapes." << std::endl; - return; - } - - mEngine->toggleDebugRendering(sceneMgr); - mEngine->stepDebug(sceneMgr); - } -} diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp deleted file mode 100644 index 0036bf769..000000000 --- a/apps/opencs/view/world/physicssystem.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef CSV_WORLD_PHYSICSSYSTEM_H -#define CSV_WORLD_PHYSICSSYSTEM_H - -#include -#include - -namespace Ogre -{ - class Vector3; - class Quaternion; - class SceneManager; - class Camera; -} - -namespace OEngine -{ - namespace Physic - { - class PhysicEngine; - } -} - -namespace CSVRender -{ - class SceneWidget; -} - -namespace CSVWorld -{ - class PhysicsSystem - { - std::map mSceneNodeToRefId; - std::map > mRefIdToSceneNode; - std::map mSceneNodeToMesh; - std::map mSceneWidgets; - OEngine::Physic::PhysicEngine* mEngine; - std::multimap mTerrain; - - public: - - PhysicsSystem(); - ~PhysicsSystem(); - - void addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget * scene); - - void removeSceneManager(Ogre::SceneManager *sceneMgr); - - void addObject(const std::string &mesh, - const std::string &sceneNodeName, const std::string &referenceId, float scale, - const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, - bool placeable=false); - - void removeObject(const std::string &sceneNodeName); - void removePhysicsObject(const std::string &sceneNodeName); - - void replaceObject(const std::string &sceneNodeName, - float scale, const Ogre::Vector3 &position, - const Ogre::Quaternion &rotation, bool placeable=false); - - void moveObject(const std::string &sceneNodeName, - const Ogre::Vector3 &position, const Ogre::Quaternion &rotation); - - void moveSceneNodes(const std::string sceneNodeName, const Ogre::Vector3 &position); - - void addHeightField(Ogre::SceneManager *sceneManager, - float* heights, int x, int y, float yoffset, float triSize, float sqrtVerts); - - void removeHeightField(Ogre::SceneManager *sceneManager, int x, int y); - - void toggleDebugRendering(Ogre::SceneManager *sceneMgr); - - // return the object's SceneNode name and position for the given SceneManager - std::pair castRay(float mouseX, - float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera); - - std::string sceneNodeToRefId(std::string sceneNodeName); - - // for multi-scene manager per physics engine - std::map sceneWidgets(); - - private: - - void moveSceneNodeImpl(const std::string sceneNodeName, - const std::string referenceId, const Ogre::Vector3 &position); - - void updateSelectionHighlight(std::string sceneNode, const Ogre::Vector3 &position); - - std::string refIdToSceneNode(std::string referenceId, Ogre::SceneManager *sceneMgr); - - Ogre::SceneManager *findSceneManager(std::string sceneNodeName); - }; -} - -#endif // CSV_WORLD_PHYSICSSYSTEM_H