From ebe131b3268b7d4a301e010234639763caab6eec Mon Sep 17 00:00:00 2001 From: Michael Mc Donnell Date: Tue, 14 Aug 2012 14:45:16 -0400 Subject: [PATCH 01/30] Use debug dlls when debugging in vs2010 Using the Debug build in vs2010 is not working because the debug dlls are not loaded when debugging. The reason they are not loaded is that CMAKE_BUILD_TYPE is not defined when doing multiple builds. This in turns causes OGRE_PLUGIN_DEBUG_SUFFIX not to be set. This patch makes sure that OGRE_PLUGIN_DEBUG_SUFFIX is always set but only used when debugging. There are still other bugs that have broken Debug mode in vs2010 but those will be addressed in other patches. --- CMakeLists.txt | 8 ++++---- components/files/ogreplugin.cpp | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 543d9cb98..e3cc8df3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,11 +259,11 @@ endif (APPLE) # Set up Ogre plugin folder & debug suffix -# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) -if (DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE) - add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") -else() +if (APPLE) + # Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") +else () + add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") endif() add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}") diff --git a/components/files/ogreplugin.cpp b/components/files/ogreplugin.cpp index c434114b3..85fe661de 100644 --- a/components/files/ogreplugin.cpp +++ b/components/files/ogreplugin.cpp @@ -6,7 +6,11 @@ namespace Files { bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) { + // Append plugin suffix if debugging. +#if defined(DEBUG) || defined(_DEBUG) pluginName = pluginName + OGRE_PLUGIN_DEBUG_SUFFIX; +#endif + #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE std::ostringstream verStream; verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH; From d57698501905a8e2dc987343de6d38f199a27991 Mon Sep 17 00:00:00 2001 From: Edmondo Tommasina Date: Thu, 16 Aug 2012 20:52:08 +0200 Subject: [PATCH 02/30] credits.txt: fix name --- credits.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/credits.txt b/credits.txt index ca0ff7323..c7ec4936e 100644 --- a/credits.txt +++ b/credits.txt @@ -35,7 +35,7 @@ Sylvain T. (Garvek) Packagers: Alexander Olofsson (Ace) - Windows BrotherBrick - Ubuntu Linux -edmundo - Gentoo Linux +Edmondo Tommasina - Gentoo Linux Kenny Armstrong (artorius) - Fedora Linux Nikolay Kasyanov (corristo) - Mac OS X Sandy Carter (bwrsandman) - Arch Linux From 2a11a28e81e4a9bded90f5132a6b837b068a8701 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Aug 2012 10:05:29 +0200 Subject: [PATCH 03/30] Revert "Use debug dlls when debugging in vs2010" This reverts commit ebe131b3268b7d4a301e010234639763caab6eec. --- CMakeLists.txt | 8 ++++---- components/files/ogreplugin.cpp | 4 ---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3cc8df3b..543d9cb98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,11 +259,11 @@ endif (APPLE) # Set up Ogre plugin folder & debug suffix -if (APPLE) - # Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) - add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") -else () +# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) +if (DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE) add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") +else() + add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") endif() add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}") diff --git a/components/files/ogreplugin.cpp b/components/files/ogreplugin.cpp index 85fe661de..c434114b3 100644 --- a/components/files/ogreplugin.cpp +++ b/components/files/ogreplugin.cpp @@ -6,11 +6,7 @@ namespace Files { bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) { - // Append plugin suffix if debugging. -#if defined(DEBUG) || defined(_DEBUG) pluginName = pluginName + OGRE_PLUGIN_DEBUG_SUFFIX; -#endif - #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE std::ostringstream verStream; verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH; From c46eeaa100687d9af473c83a638df1dd87966fda Mon Sep 17 00:00:00 2001 From: greye Date: Sun, 12 Aug 2012 15:50:37 +0400 Subject: [PATCH 04/30] initial 3d-person camera support --- apps/openmw/engine.cpp | 2 +- apps/openmw/mwbase/world.hpp | 2 + apps/openmw/mwinput/inputmanagerimp.cpp | 31 +++- apps/openmw/mwinput/inputmanagerimp.hpp | 2 +- apps/openmw/mwrender/player.cpp | 168 +++++++++++++++------- apps/openmw/mwrender/player.hpp | 32 +++-- apps/openmw/mwrender/renderingmanager.cpp | 14 +- apps/openmw/mwrender/renderingmanager.hpp | 4 + apps/openmw/mwworld/worldimp.cpp | 1 - apps/openmw/mwworld/worldimp.hpp | 3 + 10 files changed, 182 insertions(+), 77 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 75835120f..b8421cc62 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -67,7 +67,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) mEnvironment.setFrameDuration (evt.timeSinceLastFrame); // update input - MWBase::Environment::get().getInputManager()->update(); + MWBase::Environment::get().getInputManager()->update(evt.timeSinceLastFrame); // sound if (mUseSound) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 8b809d399..c2db2acf1 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -248,6 +248,8 @@ namespace MWBase virtual bool isSwimming(const MWWorld::Ptr &object) = 0; virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; + + virtual void togglePOV() = 0; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 8def5c74d..6bdd87d2a 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -62,6 +62,7 @@ namespace MWInput A_ToggleSneak, //Toggles Sneak, add Push-Sneak later A_ToggleWalk, //Toggle Walking/Running A_Crouch, + A_TogglePOV, A_QuickSave, A_QuickLoad, @@ -90,6 +91,8 @@ namespace MWInput std::map mControlSwitch; + float mPreviewPOVDelay; + /* InputImpl Methods */ public: void adjustMouseRegion(int width, int height) @@ -340,6 +343,8 @@ private: poller.bind(A_Jump, KC_E); poller.bind(A_Crouch, KC_LCONTROL); + + poller.bind(A_TogglePOV, KC_TAB); } void setDragDrop(bool dragDrop) @@ -348,7 +353,7 @@ private: } //NOTE: Used to check for movement keys - void update () + void update (float duration) { // Tell OIS to handle all input events input.capture(); @@ -400,6 +405,21 @@ private: player.setUpDown (-1); else player.setUpDown (0); + + if (poller.isDown(A_TogglePOV)) { + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += duration) > 0.5) + { + // enable preview mode + } + } else { + if (mPreviewPOVDelay > 0.5) { + //disable preview mode + } else if (mPreviewPOVDelay > 0.f) { + togglePOV(); + } + mPreviewPOVDelay = 0.f; + } } } @@ -452,6 +472,11 @@ private: mControlSwitch[sw] = value; } + void togglePOV() + { + MWBase::Environment::get().getWorld()->togglePOV(); + } + }; /***CONSTRUCTOR***/ @@ -470,9 +495,9 @@ private: delete impl; } - void MWInputManager::update() + void MWInputManager::update(float duration) { - impl->update(); + impl->update(duration); } void MWInputManager::setDragDrop(bool dragDrop) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 5092198da..70436e207 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -52,7 +52,7 @@ namespace MWInput OMW::Engine& engine); virtual ~MWInputManager(); - virtual void update(); + void update(float duration); virtual void changeInputMode(bool guiMode); diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 94a3f71c8..a99d69945 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" @@ -12,82 +13,119 @@ namespace MWRender { Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) - : mCamera (camera), - mNode (node), + : mCamera(camera), + mPlayerNode(node), + mCameraNode(mPlayerNode->createChildSceneNode()), mFirstPersonView(true), - mVanityModeEnabled(false) - {} - - bool Player::setRotation(const Ogre::Vector3 &rot) + mVanityMode(false), + mPreviewMode(false) { - Ogre::SceneNode *sceneNode = mNode; - Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); - Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); - - // we are only interested in X and Y rotation - - // Rotate around X axis - Ogre::Radian radx(rot.x); - if (radx.valueDegrees() > 89.5f) { - radx = Ogre::Degree(89.5f); - } else if (radx.valueDegrees() < -89.5f) { - radx = Ogre::Degree(-89.5f); - } - Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X); - - // Rotate around Y axis - Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y); + Ogre::SceneNode *pitchNode = mCameraNode->createChildSceneNode(); + pitchNode->attachObject(mCamera); + } + + bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) + { + bool force = !mVanityMode && !mPreviewMode; + Ogre::Vector3 newRot = rot; - pitchNode->setOrientation(xr); - yawNode->setOrientation(yr); + rotateCamera(newRot, adjust); + if (!force || !mFirstPersonView) { + moveCamera(400.f, 1600.f); + } updateListener(); - return !mVanityModeEnabled; + return force; } - std::string Player::getHandle() const + void Player::rotateCamera(Ogre::Vector3 &rot, bool adjust) { - return mNode->getName(); - } + Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); + Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); - void Player::attachTo(const MWWorld::Ptr &ptr) - { - ptr.getRefData().setBaseNode(mNode); + if (adjust) { + float f = + limitPitchAngle(89.5f, Ogre::Radian(rot.x).valueDegrees()); + + if (f != 0.0) { + pitchNode->pitch(Ogre::Degree(f)); + } + yawNode->yaw(Ogre::Radian(-rot.z)); + } else { + Ogre::Radian radx(rot.x); + if (radx.valueDegrees() > 89.5f) { + radx = Ogre::Degree(89.5f); + } else if (radx.valueDegrees() < -89.5f) { + radx = Ogre::Degree(-89.5f); + } + Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X); + Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y); + + pitchNode->setOrientation(xr); + yawNode->setOrientation(yr); + } } - bool Player::adjustRotation(const Ogre::Vector3 &rot) + void Player::moveCamera(float rsq, float hsq) { - Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); - Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); +/* + Ogre::Quaternion orient = + mCamera->getParentSceneNode()->getOrientation(); - float f = controlFlip(Ogre::Radian(rot.x).valueDegrees()); - if (f != 0.0) { - pitchNode->pitch(Ogre::Degree(f)); - } - yawNode->yaw(Ogre::Radian(-rot.z)); + float pitchAngle = + (2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees()); - updateListener(); + orient = mCameraNode->getOrientation(); + float yawAngle = + (2 * Ogre::Degree(Ogre::Math::ASin(orient.y)).valueDegrees()); + + float tana = Ogre::Math::Tan(Ogre::Degree(pitchAngle)); + float tansq = tana * tana; + + float r1 = hsq * rsq / (hsq + rsq * tansq); + float zsq = r1 * tansq; + r1 = Ogre::Math::Sqrt(r1); + + Ogre::Vector3 pos; + pos.y = -Ogre::Math::Sqrt(zsq); + pos.z = r1 * Ogre::Math::Sin(Ogre::Degree(yawAngle).valueDegrees()); + pos.x = r1 * Ogre::Math::Cos(Ogre::Degree(yawAngle).valueDegrees()); +*/ + Ogre::Vector3 dir = mCamera->getRealDirection(); + dir.x = -dir.x, dir.y = -dir.y, dir.z = -dir.z; + + Ogre::Ray ray(Ogre::Vector3(0, 0, 0), dir); - return !mVanityModeEnabled; + mCameraNode->setPosition(ray.getPoint(800.f)); } - float Player::controlFlip(float shift) + std::string Player::getHandle() const { - Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); - Ogre::Quaternion orient = pitchNode->getOrientation(); + return mPlayerNode->getName(); + } + + void Player::attachTo(const MWWorld::Ptr &ptr) + { + ptr.getRefData().setBaseNode(mPlayerNode); + } + + float Player::limitPitchAngle(float limitAbs, float shift) + { + Ogre::Quaternion orient = + mCamera->getParentSceneNode()->getOrientation(); float pitchAngle = (2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees()); - if (pitchAngle + shift < 89.5f && pitchAngle + shift > -89.5f) { + if (pitchAngle + shift < limitAbs && pitchAngle + shift > -limitAbs) { return shift; } if (pitchAngle > 0) { - float f = 89.5f - pitchAngle - shift; + float f = limitAbs - pitchAngle - shift; return (f > 0.f) ? f : 0.f; } else if (pitchAngle < 0) { - float f = -89.5 - pitchAngle - shift; + float f = -limitAbs - pitchAngle - shift; return (f < 0.f) ? f : 0.f; } return 0.f; @@ -104,4 +142,38 @@ namespace MWRender MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir); } + + void Player::update(float duration) + { + if (mFirstPersonView && !mVanityMode) { + return; + } + if (mVanityMode) { + /// \todo adjust rotation constantly + } else { + /// \todo move camera closer or change view mode if needed + } + } + + void Player::toggleViewMode() + { + mFirstPersonView = !mFirstPersonView; + if (mFirstPersonView) { + mCameraNode->setPosition(0.f, 0.f, 0.f); + } else { + moveCamera(400.f, 1600.f); + } + } + + void Player::toggleVanityMode() + { + /// \todo move camera + mVanityMode = !mVanityMode; + } + + void Player::togglePreviewMode() + { + /// \todo move camera + mPreviewMode = !mPreviewMode; + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 981ecfe0b..739b4cd8b 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -22,16 +22,24 @@ namespace MWRender class Player { Ogre::Camera *mCamera; - Ogre::SceneNode* mNode; + + Ogre::SceneNode *mPlayerNode; + Ogre::SceneNode *mCameraNode; bool mFirstPersonView; - bool mVanityModeEnabled; + bool mVanityMode; + bool mPreviewMode; + + float mTimeIdle; - float controlFlip(float shift = 0.f); + float limitPitchAngle(float limitAbs, float shift = 0.f); /// Updates sound manager listener data void updateListener(); + void rotateCamera(Ogre::Vector3 &rot, bool adjust); + void moveCamera(float r, float h); + public: Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); @@ -39,11 +47,7 @@ namespace MWRender /// Set where the player is looking at. Uses Morrowind (euler) angles /// \param rot Rotation angles in radians /// \return true if player object needs to bo rotated physically - bool setRotation(const Ogre::Vector3 &rot); - - /// \param rot Rotation angles in radians - /// \return true if player object needs to bo rotated physically - bool adjustRotation(const Ogre::Vector3 &rot); + bool rotate(const Ogre::Vector3 &rot, bool adjust); std::string getHandle() const; @@ -52,13 +56,13 @@ namespace MWRender /// several different objects void attachTo(const MWWorld::Ptr &); - void toggleViewMode() { - mFirstPersonView = !mFirstPersonView; - } + void toggleViewMode(); + + void toggleVanityMode(); + + void togglePreviewMode(); - void toggleVanityMode() { - mVanityModeEnabled = !mVanityModeEnabled; - } + void update(float duration); }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index d0019c6b8..91d83caf3 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -133,11 +133,10 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mObjects.setMwRoot(mMwRoot); mActors.setMwRoot(mMwRoot); + Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player"); playerNode->pitch(Degree(90)); - Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode(); - Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode(); - cameraPitchNode->attachObject(mRendering.getCamera()); + mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mShadows = new Shadows(&mRendering); @@ -147,7 +146,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); - mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mSun = 0; mDebugging = new Debugging(mMwRoot, engine); @@ -259,11 +257,7 @@ RenderingManager::rotateObject( bool force = true; if (isPlayer) { - if (adjust) { - force = mPlayer->adjustRotation(rot); - } else { - force = mPlayer->setRotation(rot); - } + force = mPlayer->rotate(rot, adjust); } MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); @@ -329,6 +323,8 @@ void RenderingManager::update (float duration){ ); mWater->update(duration); } + + mPlayer->update(duration); } void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index ef6f18a75..f100fdd59 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -56,6 +56,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine); virtual ~RenderingManager(); + void togglePOV() { + mPlayer->toggleViewMode(); + } + void attachCameraTo(const MWWorld::Ptr &ptr); SkyManager* getSkyManager(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8ace54378..20706438d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1151,5 +1151,4 @@ namespace MWWorld } return pos.z < cell.water; } - } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 4031a180a..2e5f73702 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -277,6 +277,9 @@ namespace MWWorld virtual bool isSwimming(const MWWorld::Ptr &object); virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos); + virtual void togglePOV() { + mRendering->togglePOV(); + } }; } From a7aeda9a3b78d8939745a07fb55c7adb0f5b38cd Mon Sep 17 00:00:00 2001 From: greye Date: Sun, 12 Aug 2012 18:35:35 +0400 Subject: [PATCH 05/30] initial vanity mode support --- apps/openmw/mwrender/player.cpp | 83 +++++++++++++++++++---- apps/openmw/mwrender/player.hpp | 12 +++- apps/openmw/mwrender/renderingmanager.cpp | 13 +++- 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index a99d69945..53642d615 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -24,19 +24,29 @@ namespace MWRender pitchNode->attachObject(mCamera); } + void Player::rotateImpl(Ogre::Vector3 &rot, bool adjust, float r) + { + rotateCamera(rot, adjust); + + if (mVanityMode || mPreviewMode || !mFirstPersonView) { + moveCamera(r); + } + updateListener(); + } + bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) { - bool force = !mVanityMode && !mPreviewMode; - Ogre::Vector3 newRot = rot; + Ogre::Vector3 _rot = rot; + rotateImpl(_rot, adjust, 400.f); - rotateCamera(newRot, adjust); + mUpdates = 0; + mTimeIdle = 0.f; - if (!force || !mFirstPersonView) { - moveCamera(400.f, 1600.f); + if (mVanityMode) { + toggleVanityMode(); } - updateListener(); - return force; + return !mVanityMode && !mPreviewMode; } void Player::rotateCamera(Ogre::Vector3 &rot, bool adjust) @@ -67,7 +77,7 @@ namespace MWRender } } - void Player::moveCamera(float rsq, float hsq) + void Player::moveCamera(float r) { /* Ogre::Quaternion orient = @@ -97,7 +107,7 @@ namespace MWRender Ogre::Ray ray(Ogre::Vector3(0, 0, 0), dir); - mCameraNode->setPosition(ray.getPoint(800.f)); + mCameraNode->setPosition(ray.getPoint(r)); } std::string Player::getHandle() const @@ -145,13 +155,20 @@ namespace MWRender void Player::update(float duration) { + if (!mVanityMode) { + ++mUpdates; + mTimeIdle += duration; + if (mTimeIdle > 30.f) { + toggleVanityMode(); + } + } if (mFirstPersonView && !mVanityMode) { return; } if (mVanityMode) { - /// \todo adjust rotation constantly - } else { - /// \todo move camera closer or change view mode if needed + Ogre::Vector3 rot(0.f, 0.f, 0.f); + rot.z = Ogre::Degree(3.f * duration).valueRadians(); + rotateImpl(rot, true, 300.f); } } @@ -161,14 +178,28 @@ namespace MWRender if (mFirstPersonView) { mCameraNode->setPosition(0.f, 0.f, 0.f); } else { - moveCamera(400.f, 1600.f); + moveCamera(400.f); } } void Player::toggleVanityMode() { - /// \todo move camera mVanityMode = !mVanityMode; + + float r = 400.f; + Ogre::Vector3 rot(0.f, 0.f, 0.f); + if (mVanityMode) { + mPitch = getPitchAngle(); + mYaw = getYawAngle(); + + rot.x = Ogre::Degree(-30.f).valueRadians(); + rot.z = 0; + r = 300.f; + } else { + rot.x = Ogre::Degree(mPitch).valueRadians(); + rot.z = Ogre::Degree(mYaw).valueRadians(); + } + rotateImpl(rot, false, r); } void Player::togglePreviewMode() @@ -176,4 +207,28 @@ namespace MWRender /// \todo move camera mPreviewMode = !mPreviewMode; } + + float Player::getPitchAngle() + { + Ogre::Quaternion orient + = mCamera->getParentSceneNode()->getOrientation(); + + float angle = + (2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees()); + + return angle; + } + + float Player::getYawAngle() + { + Ogre::Quaternion orient + = mCameraNode->getOrientation(); + + float angle = + (2 * Ogre::Degree(Ogre::Math::ASin(orient.y)).valueDegrees()); + if (orient.w < 0) { + angle = -angle; + } + return -angle; + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 739b4cd8b..d4c0eab5d 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -3,9 +3,8 @@ #include - namespace Ogre -{ +{ class Vector3; class Camera; class SceneNode; @@ -30,15 +29,22 @@ namespace MWRender bool mVanityMode; bool mPreviewMode; + float mPitch, mYaw; + float mTimeIdle; + int mUpdates; float limitPitchAngle(float limitAbs, float shift = 0.f); /// Updates sound manager listener data void updateListener(); + void rotateImpl(Ogre::Vector3 &rot, bool adjust, float r); void rotateCamera(Ogre::Vector3 &rot, bool adjust); - void moveCamera(float r, float h); + void moveCamera(float r); + + float getYawAngle(); + float getPitchAngle(); public: diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 91d83caf3..d5e28e439 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -309,7 +309,17 @@ void RenderingManager::update (float duration){ mRendering.update(duration); - mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); + float *fpos = + MWBase::Environment::get() + .getWorld() + ->getPlayer() + .getPlayer() + .getRefData() + .getPosition() + .pos; + Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]); + + mLocalMap->updatePlayer(pos, mRendering.getCamera()->getRealOrientation() ); if (mWater) { Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); @@ -323,7 +333,6 @@ void RenderingManager::update (float duration){ ); mWater->update(duration); } - mPlayer->update(duration); } From db94018865bef15fe5e3df7f06abbf18edceaf3a Mon Sep 17 00:00:00 2001 From: greye Date: Mon, 13 Aug 2012 08:37:32 +0400 Subject: [PATCH 06/30] far better camera movement --- apps/openmw/mwrender/player.cpp | 66 ++++++--------------------------- apps/openmw/mwrender/player.hpp | 6 +-- 2 files changed, 14 insertions(+), 58 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 53642d615..8753d7c5d 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -24,20 +24,9 @@ namespace MWRender pitchNode->attachObject(mCamera); } - void Player::rotateImpl(Ogre::Vector3 &rot, bool adjust, float r) - { - rotateCamera(rot, adjust); - - if (mVanityMode || mPreviewMode || !mFirstPersonView) { - moveCamera(r); - } - updateListener(); - } - bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) { - Ogre::Vector3 _rot = rot; - rotateImpl(_rot, adjust, 400.f); + rotateCamera(rot, adjust); mUpdates = 0; mTimeIdle = 0.f; @@ -49,7 +38,7 @@ namespace MWRender return !mVanityMode && !mPreviewMode; } - void Player::rotateCamera(Ogre::Vector3 &rot, bool adjust) + void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) { Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); @@ -75,39 +64,7 @@ namespace MWRender pitchNode->setOrientation(xr); yawNode->setOrientation(yr); } - } - - void Player::moveCamera(float r) - { -/* - Ogre::Quaternion orient = - mCamera->getParentSceneNode()->getOrientation(); - - float pitchAngle = - (2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees()); - - orient = mCameraNode->getOrientation(); - float yawAngle = - (2 * Ogre::Degree(Ogre::Math::ASin(orient.y)).valueDegrees()); - - float tana = Ogre::Math::Tan(Ogre::Degree(pitchAngle)); - float tansq = tana * tana; - - float r1 = hsq * rsq / (hsq + rsq * tansq); - float zsq = r1 * tansq; - r1 = Ogre::Math::Sqrt(r1); - - Ogre::Vector3 pos; - pos.y = -Ogre::Math::Sqrt(zsq); - pos.z = r1 * Ogre::Math::Sin(Ogre::Degree(yawAngle).valueDegrees()); - pos.x = r1 * Ogre::Math::Cos(Ogre::Degree(yawAngle).valueDegrees()); -*/ - Ogre::Vector3 dir = mCamera->getRealDirection(); - dir.x = -dir.x, dir.y = -dir.y, dir.z = -dir.z; - - Ogre::Ray ray(Ogre::Vector3(0, 0, 0), dir); - - mCameraNode->setPosition(ray.getPoint(r)); + updateListener(); } std::string Player::getHandle() const @@ -168,7 +125,7 @@ namespace MWRender if (mVanityMode) { Ogre::Vector3 rot(0.f, 0.f, 0.f); rot.z = Ogre::Degree(3.f * duration).valueRadians(); - rotateImpl(rot, true, 300.f); + rotateCamera(rot, true); } } @@ -176,9 +133,9 @@ namespace MWRender { mFirstPersonView = !mFirstPersonView; if (mFirstPersonView) { - mCameraNode->setPosition(0.f, 0.f, 0.f); + mCamera->setPosition(0.f, 0.f, 0.f); } else { - moveCamera(400.f); + mCamera->setPosition(0.f, 0.f, 400.f); } } @@ -186,20 +143,21 @@ namespace MWRender { mVanityMode = !mVanityMode; - float r = 400.f; + float offset = 300.f; Ogre::Vector3 rot(0.f, 0.f, 0.f); if (mVanityMode) { - mPitch = getPitchAngle(); mYaw = getYawAngle(); + mPitch = getPitchAngle(); + mOffset = mCamera->getPosition().z; rot.x = Ogre::Degree(-30.f).valueRadians(); - rot.z = 0; - r = 300.f; } else { rot.x = Ogre::Degree(mPitch).valueRadians(); rot.z = Ogre::Degree(mYaw).valueRadians(); + offset = mOffset; } - rotateImpl(rot, false, r); + mCamera->setPosition(0.f, 0.f, offset); + rotateCamera(rot, false); } void Player::togglePreviewMode() diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index d4c0eab5d..ed4923817 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -29,7 +29,7 @@ namespace MWRender bool mVanityMode; bool mPreviewMode; - float mPitch, mYaw; + float mPitch, mYaw, mOffset; float mTimeIdle; int mUpdates; @@ -39,9 +39,7 @@ namespace MWRender /// Updates sound manager listener data void updateListener(); - void rotateImpl(Ogre::Vector3 &rot, bool adjust, float r); - void rotateCamera(Ogre::Vector3 &rot, bool adjust); - void moveCamera(float r); + void rotateCamera(const Ogre::Vector3 &rot, bool adjust); float getYawAngle(); float getPitchAngle(); From fe1a9ac3c575306ec2ef8a5ab866792d228f61e5 Mon Sep 17 00:00:00 2001 From: greye Date: Tue, 14 Aug 2012 02:36:18 +0400 Subject: [PATCH 07/30] poor camera with some fixes --- apps/openmw/mwinput/mouselookevent.cpp | 2 +- apps/openmw/mwrender/localmap.cpp | 2 +- apps/openmw/mwrender/player.cpp | 147 +++++++++++----------- apps/openmw/mwrender/player.hpp | 21 ++-- apps/openmw/mwrender/renderingmanager.cpp | 19 +-- apps/openmw/mwworld/physicssystem.cpp | 42 +++---- 6 files changed, 121 insertions(+), 112 deletions(-) diff --git a/apps/openmw/mwinput/mouselookevent.cpp b/apps/openmw/mwinput/mouselookevent.cpp index f318ce666..4138c481c 100644 --- a/apps/openmw/mwinput/mouselookevent.cpp +++ b/apps/openmw/mwinput/mouselookevent.cpp @@ -24,5 +24,5 @@ void MouseLookEvent::event(Type type, int index, const void *p) float y = arg->state.Y.rel * sensY; MWBase::World *world = MWBase::Environment::get().getWorld(); - world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); + world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, -x, true); } diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 704a10cfe..0e85d32e0 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -290,7 +290,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni } - Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); + Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 8753d7c5d..5b74b9903 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -16,12 +16,16 @@ namespace MWRender : mCamera(camera), mPlayerNode(node), mCameraNode(mPlayerNode->createChildSceneNode()), + mVanityNode(mPlayerNode->createChildSceneNode()), mFirstPersonView(true), mVanityMode(false), - mPreviewMode(false) + mPreviewMode(false), + mHeight(40.f) { - Ogre::SceneNode *pitchNode = mCameraNode->createChildSceneNode(); - pitchNode->attachObject(mCamera); + mCameraNode->attachObject(mCamera); + mCameraNode->setPosition(0.f, 0.f, mHeight); + + mPreviewCam.yaw = 0.f; } bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) @@ -32,7 +36,7 @@ namespace MWRender mTimeIdle = 0.f; if (mVanityMode) { - toggleVanityMode(); + toggleVanityMode(false); } return !mVanityMode && !mPreviewMode; @@ -44,26 +48,21 @@ namespace MWRender Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); if (adjust) { - float f = - limitPitchAngle(89.5f, Ogre::Radian(rot.x).valueDegrees()); - - if (f != 0.0) { - pitchNode->pitch(Ogre::Degree(f)); - } - yawNode->yaw(Ogre::Radian(-rot.z)); + setYaw(getYaw() + rot.z); + setPitch(getPitch() + rot.x); } else { - Ogre::Radian radx(rot.x); - if (radx.valueDegrees() > 89.5f) { - radx = Ogre::Degree(89.5f); - } else if (radx.valueDegrees() < -89.5f) { - radx = Ogre::Degree(-89.5f); - } - Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X); - Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y); - - pitchNode->setOrientation(xr); - yawNode->setOrientation(yr); + setYaw(rot.z); + setPitch(rot.x); } + Ogre::Quaternion xr( + Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), + Ogre::Vector3::UNIT_X + ); + Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::UNIT_Z); + + pitchNode->setOrientation(xr); + yawNode->setOrientation(zr); + updateListener(); } @@ -77,27 +76,6 @@ namespace MWRender ptr.getRefData().setBaseNode(mPlayerNode); } - float Player::limitPitchAngle(float limitAbs, float shift) - { - Ogre::Quaternion orient = - mCamera->getParentSceneNode()->getOrientation(); - - float pitchAngle = - (2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees()); - - if (pitchAngle + shift < limitAbs && pitchAngle + shift > -limitAbs) { - return shift; - } - if (pitchAngle > 0) { - float f = limitAbs - pitchAngle - shift; - return (f > 0.f) ? f : 0.f; - } else if (pitchAngle < 0) { - float f = -limitAbs - pitchAngle - shift; - return (f < 0.f) ? f : 0.f; - } - return 0.f; - } - void Player::updateListener() { Ogre::Vector3 pos = mCamera->getRealPosition(); @@ -116,7 +94,7 @@ namespace MWRender ++mUpdates; mTimeIdle += duration; if (mTimeIdle > 30.f) { - toggleVanityMode(); + toggleVanityMode(true); } } if (mFirstPersonView && !mVanityMode) { @@ -139,54 +117,83 @@ namespace MWRender } } - void Player::toggleVanityMode() + void Player::toggleVanityMode(bool enable, bool force) { - mVanityMode = !mVanityMode; + if (mVanityMode == enable) { + return; + } + mVanityMode = enable; float offset = 300.f; Ogre::Vector3 rot(0.f, 0.f, 0.f); if (mVanityMode) { - mYaw = getYawAngle(); - mPitch = getPitchAngle(); - mOffset = mCamera->getPosition().z; - rot.x = Ogre::Degree(-30.f).valueRadians(); + mMainCam.offset = mCamera->getPosition().z; + + mPlayerNode->removeChild(mCameraNode); + mVanityNode->addChild(mCameraNode); } else { - rot.x = Ogre::Degree(mPitch).valueRadians(); - rot.z = Ogre::Degree(mYaw).valueRadians(); - offset = mOffset; + rot.x = getPitch(); + offset = mMainCam.offset; + + mVanityNode->removeChild(mCameraNode); + mPlayerNode->addChild(mCameraNode); } + rot.z = getYaw(); mCamera->setPosition(0.f, 0.f, offset); rotateCamera(rot, false); } - void Player::togglePreviewMode() + void Player::togglePreviewMode(bool enable) { /// \todo move camera - mPreviewMode = !mPreviewMode; + if (mPreviewMode == enable) { + return; + } + mPreviewMode = enable; } - float Player::getPitchAngle() + float Player::getYaw() { - Ogre::Quaternion orient - = mCamera->getParentSceneNode()->getOrientation(); - - float angle = - (2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees()); + if (mVanityMode || mPreviewMode) { + return mPreviewCam.yaw; + } + return mMainCam.yaw; + } - return angle; + void Player::setYaw(float angle) + { + if (angle > Ogre::Math::PI) { + angle -= Ogre::Math::TWO_PI; + } else if (angle < -Ogre::Math::PI) { + angle += Ogre::Math::TWO_PI; + } + if (mVanityMode || mPreviewMode) { + mPreviewCam.yaw = angle; + } else { + mMainCam.yaw = angle; + } } - float Player::getYawAngle() + float Player::getPitch() { - Ogre::Quaternion orient - = mCameraNode->getOrientation(); + if (mVanityMode || mPreviewMode) { + return mPreviewCam.pitch; + } + return mMainCam.pitch; + } - float angle = - (2 * Ogre::Degree(Ogre::Math::ASin(orient.y)).valueDegrees()); - if (orient.w < 0) { - angle = -angle; + void Player::setPitch(float angle) + { + if (angle > Ogre::Math::HALF_PI) { + angle = Ogre::Math::HALF_PI - 0.01; + } else if (angle < -Ogre::Math::HALF_PI) { + angle = -Ogre::Math::HALF_PI + 0.01; + } + if (mVanityMode || mPreviewMode) { + mPreviewCam.pitch = angle; + } else { + mMainCam.pitch = angle; } - return -angle; } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index ed4923817..060d62fa0 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -20,29 +20,36 @@ namespace MWRender /// \brief Player character rendering and camera control class Player { + struct CamData { + float pitch, yaw, offset; + }; + Ogre::Camera *mCamera; Ogre::SceneNode *mPlayerNode; Ogre::SceneNode *mCameraNode; + Ogre::SceneNode *mVanityNode; bool mFirstPersonView; bool mVanityMode; bool mPreviewMode; - float mPitch, mYaw, mOffset; + float mHeight; + CamData mMainCam, mPreviewCam; float mTimeIdle; int mUpdates; - float limitPitchAngle(float limitAbs, float shift = 0.f); - /// Updates sound manager listener data void updateListener(); void rotateCamera(const Ogre::Vector3 &rot, bool adjust); - float getYawAngle(); - float getPitchAngle(); + float getYaw(); + void setYaw(float angle); + + float getPitch(); + void setPitch(float angle); public: @@ -62,9 +69,9 @@ namespace MWRender void toggleViewMode(); - void toggleVanityMode(); + void toggleVanityMode(bool enable, bool force = false); - void togglePreviewMode(); + void togglePreviewMode(bool enable); void update(float duration); }; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index d5e28e439..cc08eae91 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -135,7 +135,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player"); - playerNode->pitch(Degree(90)); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mShadows = new Shadows(&mRendering); @@ -309,17 +308,23 @@ void RenderingManager::update (float duration){ mRendering.update(duration); - float *fpos = + MWWorld::RefData &data = MWBase::Environment::get() .getWorld() ->getPlayer() .getPlayer() - .getRefData() - .getPosition() - .pos; - Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]); + .getRefData(); - mLocalMap->updatePlayer(pos, mRendering.getCamera()->getRealOrientation() ); + float *fpos = data.getPosition().pos; + + /// \note only for LocalMap::updatePlayer() + Ogre::Vector3 pos(fpos[0], -fpos[2], fpos[1]); + + Ogre::SceneNode *node = data.getBaseNode(); + Ogre::Quaternion orient = + node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); + + mLocalMap->updatePlayer(mRendering.getCamera()->getRealPosition(), orient); if (mWater) { Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 45cfdd123..1bbfe33fd 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -11,7 +11,7 @@ #include -#include "../mwbase/world.hpp" // FIXME +//#include "../mwbase/world.hpp" // FIXME #include "ptr.hpp" #include "class.hpp" @@ -172,7 +172,7 @@ namespace MWWorld OEngine::Physic::PhysicActor* act = it->second; act->setWalkDirection(btVector3(0,0,0)); } - playerMove::playercmd& pm_ref = playerphysics->cmd; + playerMove::playercmd& pm_ref = playerphysics->cmd; pm_ref.rightmove = 0; pm_ref.forwardmove = 0; @@ -183,35 +183,25 @@ namespace MWWorld iter!=actors.end(); ++iter) { //dirty stuff to get the camera orientation. Must be changed! + Ogre::Quaternion orient = + mRender.getScene()->getSceneNode(iter->first)->getOrientation(); - Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first); - Ogre::Vector3 dir; - Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); - Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); - Ogre::Quaternion yawQuat = yawNode->getOrientation(); - Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); - - - - playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); - - playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90; - - - Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); - - pm_ref.rightmove = -iter->second.x; - pm_ref.forwardmove = -iter->second.y; - pm_ref.upmove = iter->second.z; + float yaw = orient.getRoll().valueDegrees(); + float pitch = 0.f; + if (iter->first == "player") { + /// \fixme should not rely on player camera, real pitch needed + Ogre::SceneNode *node = mRender.getCamera()->getParentSceneNode(); + pitch = node->getOrientation().getPitch().valueDegrees(); + playerphysics->ps.viewangles.x = pitch - 90; + playerphysics->ps.viewangles.y = -yaw + 90; + pm_ref.rightmove = -iter->second.x; + pm_ref.forwardmove = -iter->second.y; + pm_ref.upmove = iter->second.z; + } } - - - - - mEngine->stepSimulation(dt); } From 6f87c0c36d912de51b943e7989d6c4117d568760 Mon Sep 17 00:00:00 2001 From: greye Date: Tue, 14 Aug 2012 14:37:48 +0400 Subject: [PATCH 08/30] preview mode, advanced vanity support --- apps/openmw/mwbase/world.hpp | 3 + apps/openmw/mwinput/inputmanagerimp.cpp | 27 ++-- apps/openmw/mwrender/player.cpp | 143 +++++++++++++++++----- apps/openmw/mwrender/player.hpp | 14 ++- apps/openmw/mwrender/renderingmanager.cpp | 4 +- apps/openmw/mwrender/renderingmanager.hpp | 12 ++ apps/openmw/mwworld/worldimp.hpp | 12 ++ 7 files changed, 168 insertions(+), 47 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index c2db2acf1..819a242ec 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -250,6 +250,9 @@ namespace MWBase virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; virtual void togglePOV() = 0; + virtual void togglePreviewMode(bool enable) = 0; + virtual bool toggleVanityMode(bool enable, bool force) = 0; + virtual void allowVanityMode(bool allow) = 0; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 6bdd87d2a..f0ca510ea 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -406,19 +406,22 @@ private: else player.setUpDown (0); - if (poller.isDown(A_TogglePOV)) { - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += duration) > 0.5) - { - // enable preview mode + if (mControlSwitch["playerviewswitch"]) { + if (poller.isDown(A_TogglePOV)) { + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += duration) > 0.5) + { + MWBase::Environment::get().getWorld()->togglePreviewMode(true); + } + } else { + if (mPreviewPOVDelay > 0.5) { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + } else if (mPreviewPOVDelay > 0.f) { + togglePOV(); + } + mPreviewPOVDelay = 0.f; } - } else { - if (mPreviewPOVDelay > 0.5) { - //disable preview mode - } else if (mPreviewPOVDelay > 0.f) { - togglePOV(); - } - mPreviewPOVDelay = 0.f; } } } diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 5b74b9903..2a1feacad 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -18,28 +18,49 @@ namespace MWRender mCameraNode(mPlayerNode->createChildSceneNode()), mVanityNode(mPlayerNode->createChildSceneNode()), mFirstPersonView(true), - mVanityMode(false), mPreviewMode(false), - mHeight(40.f) + mHeight(40.f), + mCameraDistance(400.f) { + mVanity.enabled = false; + mVanity.allowed = true; + mVanity.forced = false; + mCameraNode->attachObject(mCamera); mCameraNode->setPosition(0.f, 0.f, mHeight); mPreviewCam.yaw = 0.f; + mPreviewCam.offset = 600.f; } bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) { - rotateCamera(rot, adjust); - mUpdates = 0; mTimeIdle = 0.f; - if (mVanityMode) { + if (mVanity.enabled) { toggleVanityMode(false); } - return !mVanityMode && !mPreviewMode; + Ogre::Vector3 trueRot = rot; + + /// \note rotate player on forced vanity + if (mVanity.forced) { + moveCameraNode(mPlayerNode); + mVanity.enabled = false; + + rotateCamera(rot, adjust); + + moveCameraNode(mVanityNode); + mVanity.enabled = true; + + trueRot.z = 0.f; + } + + rotateCamera(trueRot, adjust); + + /// \note if vanity mode is forced by TVM then rotate player + return (!mVanity.enabled && !mPreviewMode) || mVanity.forced; } void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) @@ -90,19 +111,19 @@ namespace MWRender void Player::update(float duration) { - if (!mVanityMode) { + if (!mVanity.enabled) { ++mUpdates; mTimeIdle += duration; if (mTimeIdle > 30.f) { toggleVanityMode(true); } } - if (mFirstPersonView && !mVanityMode) { + if (mFirstPersonView && !mVanity.enabled) { return; } - if (mVanityMode) { + if (mVanity.enabled) { Ogre::Vector3 rot(0.f, 0.f, 0.f); - rot.z = Ogre::Degree(3.f * duration).valueRadians(); + rot.z = Ogre::Degree(-3.f * duration).valueRadians(); rotateCamera(rot, true); } } @@ -113,49 +134,75 @@ namespace MWRender if (mFirstPersonView) { mCamera->setPosition(0.f, 0.f, 0.f); } else { - mCamera->setPosition(0.f, 0.f, 400.f); + mCamera->setPosition(0.f, 0.f, mCameraDistance); } } + + void Player::allowVanityMode(bool allow) + { + if (!allow && mVanity.enabled && !mVanity.forced) { + toggleVanityMode(false); + } + mVanity.allowed = allow; + } - void Player::toggleVanityMode(bool enable, bool force) + bool Player::toggleVanityMode(bool enable, bool force) { - if (mVanityMode == enable) { - return; + if ((mVanity.forced && !force) || + (!mVanity.allowed && (force || enable))) + { + return false; + } else if (mVanity.enabled == enable) { + return true; } - mVanityMode = enable; + mVanity.enabled = enable; + mVanity.forced = force && enable; float offset = 300.f; Ogre::Vector3 rot(0.f, 0.f, 0.f); - if (mVanityMode) { + if (mVanity.enabled) { rot.x = Ogre::Degree(-30.f).valueRadians(); mMainCam.offset = mCamera->getPosition().z; - mPlayerNode->removeChild(mCameraNode); - mVanityNode->addChild(mCameraNode); + moveCameraNode(mVanityNode); } else { rot.x = getPitch(); offset = mMainCam.offset; - mVanityNode->removeChild(mCameraNode); - mPlayerNode->addChild(mCameraNode); + moveCameraNode(mPlayerNode); } rot.z = getYaw(); mCamera->setPosition(0.f, 0.f, offset); rotateCamera(rot, false); + + return true; } void Player::togglePreviewMode(bool enable) { - /// \todo move camera if (mPreviewMode == enable) { return; } mPreviewMode = enable; + float offset = mCamera->getPosition().z; + if (mPreviewMode) { + mMainCam.offset = offset; + offset = mPreviewCam.offset; + + moveCameraNode(mVanityNode); + } else { + mPreviewCam.offset = offset; + offset = mMainCam.offset; + + moveCameraNode(mPlayerNode); + } + mCamera->setPosition(0.f, 0.f, mPreviewCam.offset); + rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); } float Player::getYaw() { - if (mVanityMode || mPreviewMode) { + if (mVanity.enabled || mPreviewMode) { return mPreviewCam.yaw; } return mMainCam.yaw; @@ -168,7 +215,7 @@ namespace MWRender } else if (angle < -Ogre::Math::PI) { angle += Ogre::Math::TWO_PI; } - if (mVanityMode || mPreviewMode) { + if (mVanity.enabled || mPreviewMode) { mPreviewCam.yaw = angle; } else { mMainCam.yaw = angle; @@ -177,23 +224,59 @@ namespace MWRender float Player::getPitch() { - if (mVanityMode || mPreviewMode) { + if (mVanity.enabled || mPreviewMode) { return mPreviewCam.pitch; } return mMainCam.pitch; } void Player::setPitch(float angle) - { - if (angle > Ogre::Math::HALF_PI) { - angle = Ogre::Math::HALF_PI - 0.01; - } else if (angle < -Ogre::Math::HALF_PI) { - angle = -Ogre::Math::HALF_PI + 0.01; + { + float limit = Ogre::Math::HALF_PI; + if (mVanity.forced || mPreviewMode) { + limit /= 2; } - if (mVanityMode || mPreviewMode) { + if (angle > limit) { + angle = limit - 0.01; + } else if (angle < -limit) { + angle = -limit + 0.01; + } + if (mVanity.enabled || mPreviewMode) { mPreviewCam.pitch = angle; } else { mMainCam.pitch = angle; } } + + void Player::moveCameraNode(Ogre::SceneNode *node) + { + mCameraNode->getParentSceneNode()->removeChild(mCameraNode); + node->addChild(mCameraNode); + } + + void Player::setCameraDistance(float dist, bool adjust) + { + /// \note non-Morrowind feature: allow to change camera distance + /// int 3d-person mode + /// \todo review and simplify condition if possible + if (mPreviewMode || + mVanity.forced || + (!mVanity.enabled && !mFirstPersonView)) + { + Ogre::Vector3 v(0.f, 0.f, dist); + if (adjust) { + v += mCamera->getPosition(); + } + if (v.z > 800.f) { + v.z = 800.f; + } else if (v.z < 100.f) { + v.z = 100.f; + } + mCamera->setPosition(v); + + if (!mVanity.enabled && !mFirstPersonView) { + mCameraDistance = v.z; + } + } + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 060d62fa0..1ca9bfc21 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -31,10 +31,13 @@ namespace MWRender Ogre::SceneNode *mVanityNode; bool mFirstPersonView; - bool mVanityMode; bool mPreviewMode; - float mHeight; + struct { + bool enabled, allowed, forced; + } mVanity; + + float mHeight, mCameraDistance; CamData mMainCam, mPreviewCam; float mTimeIdle; @@ -51,6 +54,8 @@ namespace MWRender float getPitch(); void setPitch(float angle); + void moveCameraNode(Ogre::SceneNode *node); + public: Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); @@ -69,11 +74,14 @@ namespace MWRender void toggleViewMode(); - void toggleVanityMode(bool enable, bool force = false); + bool toggleVanityMode(bool enable, bool force = false); + void allowVanityMode(bool allow); void togglePreviewMode(bool enable); void update(float duration); + + void setCameraDistance(float dist, bool adjust = false); }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index cc08eae91..05902d662 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -318,13 +318,13 @@ void RenderingManager::update (float duration){ float *fpos = data.getPosition().pos; /// \note only for LocalMap::updatePlayer() - Ogre::Vector3 pos(fpos[0], -fpos[2], fpos[1]); + Ogre::Vector3 pos(fpos[0], -fpos[2], -fpos[1]); Ogre::SceneNode *node = data.getBaseNode(); Ogre::Quaternion orient = node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); - mLocalMap->updatePlayer(mRendering.getCamera()->getRealPosition(), orient); + mLocalMap->updatePlayer(pos, orient); if (mWater) { Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index f100fdd59..741ccc559 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -60,6 +60,18 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList mPlayer->toggleViewMode(); } + void togglePreviewMode(bool enable) { + mPlayer->togglePreviewMode(enable); + } + + virtual bool toggleVanityMode(bool enable, bool force) { + return mPlayer->toggleVanityMode(enable, force); + } + + virtual void allowVanityMode(bool allow) { + mPlayer->allowVanityMode(allow); + } + void attachCameraTo(const MWWorld::Ptr &ptr); SkyManager* getSkyManager(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 2e5f73702..26824e763 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -280,6 +280,18 @@ namespace MWWorld virtual void togglePOV() { mRendering->togglePOV(); } + + virtual void togglePreviewMode(bool enable) { + mRendering->togglePreviewMode(enable); + } + + virtual bool toggleVanityMode(bool enable, bool force) { + return mRendering->toggleVanityMode(enable, force); + } + + virtual void allowVanityMode(bool allow) { + mRendering->allowVanityMode(allow); + } }; } From 392e6efcb52e5de6f0acadcf9861f48f77c26590 Mon Sep 17 00:00:00 2001 From: greye Date: Tue, 14 Aug 2012 20:33:29 +0400 Subject: [PATCH 09/30] initial player rendering --- apps/openmw/engine.cpp | 2 ++ apps/openmw/mwbase/world.hpp | 2 ++ apps/openmw/mwinput/inputmanagerimp.cpp | 1 + apps/openmw/mwrender/player.cpp | 21 ++++++++++++++++++++- apps/openmw/mwrender/player.hpp | 10 ++++++++++ apps/openmw/mwrender/renderingmanager.cpp | 12 ++++++++++++ apps/openmw/mwrender/renderingmanager.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 5 +++++ apps/openmw/mwworld/worldimp.hpp | 2 ++ 9 files changed, 55 insertions(+), 1 deletion(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index b8421cc62..b818477e6 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -352,6 +352,8 @@ void OMW::Engine::go() pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.pos[2] = 0; + mEnvironment.getWorld()->renderPlayer(); + if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) { MWBase::Environment::get().getWorld()->indexToPosition (exterior->data.gridX, exterior->data.gridY, diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 819a242ec..fbc57b487 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -253,6 +253,8 @@ namespace MWBase virtual void togglePreviewMode(bool enable) = 0; virtual bool toggleVanityMode(bool enable, bool force) = 0; virtual void allowVanityMode(bool allow) = 0; + + virtual void renderPlayer() = 0; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index f0ca510ea..9295233de 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -411,6 +411,7 @@ private: if (mPreviewPOVDelay <= 0.5 && (mPreviewPOVDelay += duration) > 0.5) { + mPreviewPOVDelay = 1.f; MWBase::Environment::get().getWorld()->togglePreviewMode(true); } } else { diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 2a1feacad..c20ffad55 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -10,6 +10,8 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/refdata.hpp" +#include "npcanimation.hpp" + namespace MWRender { Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) @@ -19,7 +21,7 @@ namespace MWRender mVanityNode(mPlayerNode->createChildSceneNode()), mFirstPersonView(true), mPreviewMode(false), - mHeight(40.f), + mHeight(128.f), mCameraDistance(400.f) { mVanity.enabled = false; @@ -111,6 +113,7 @@ namespace MWRender void Player::update(float duration) { + Ogre::Vector3 pos = mPlayerNode->getPosition(); if (!mVanity.enabled) { ++mUpdates; mTimeIdle += duration; @@ -118,6 +121,9 @@ namespace MWRender toggleVanityMode(true); } } + if (mAnimation) { + mAnimation->runAnimation(duration); + } if (mFirstPersonView && !mVanity.enabled) { return; } @@ -133,8 +139,10 @@ namespace MWRender mFirstPersonView = !mFirstPersonView; if (mFirstPersonView) { mCamera->setPosition(0.f, 0.f, 0.f); + mCameraNode->setPosition(0.f, 0.f, 128.f); } else { mCamera->setPosition(0.f, 0.f, mCameraDistance); + mCameraNode->setPosition(0.f, 0.f, 104.f); } } @@ -279,4 +287,15 @@ namespace MWRender } } } + + void Player::setHeight(float height) + { + mHeight = height; + mCameraNode->setPosition(0.f, 0.f, mHeight); + } + + float Player::getHeight() + { + return mHeight; + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 1ca9bfc21..82af243bc 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -17,6 +17,7 @@ namespace MWWorld namespace MWRender { + class NpcAnimation; /// \brief Player character rendering and camera control class Player { @@ -30,6 +31,8 @@ namespace MWRender Ogre::SceneNode *mCameraNode; Ogre::SceneNode *mVanityNode; + NpcAnimation *mAnimation; + bool mFirstPersonView; bool mPreviewMode; @@ -82,6 +85,13 @@ namespace MWRender void update(float duration); void setCameraDistance(float dist, bool adjust = false); + + void setAnimation(MWRender::NpcAnimation *anim) { + mAnimation = anim; + } + + void setHeight(float height); + float getHeight(); }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 05902d662..8b6f483ca 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -33,6 +33,7 @@ #include "localmap.hpp" #include "water.hpp" #include "compositors.hpp" +#include "npcanimation.hpp" using namespace MWRender; using namespace Ogre; @@ -830,4 +831,15 @@ void RenderingManager::attachCameraTo(const MWWorld::Ptr &ptr) mPlayer->attachTo(ptr); } +void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) +{ + MWRender::NpcAnimation *anim = + new MWRender::NpcAnimation( + ptr, + mRendering, + MWWorld::Class::get(ptr).getInventoryStore(ptr) + ); + mPlayer->setAnimation(anim); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 741ccc559..aa07bbc22 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -73,6 +73,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList } void attachCameraTo(const MWWorld::Ptr &ptr); + void renderPlayer(const MWWorld::Ptr &ptr); SkyManager* getSkyManager(); Compositors* getCompositors(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 20706438d..7a8f73034 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1151,4 +1151,9 @@ namespace MWWorld } return pos.z < cell.water; } + + void World::renderPlayer() + { + mRendering->renderPlayer(mPlayer->getPlayer()); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 26824e763..717c43cfa 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -292,6 +292,8 @@ namespace MWWorld virtual void allowVanityMode(bool allow) { mRendering->allowVanityMode(allow); } + + virtual void renderPlayer(); }; } From 783e81afc3fcd296c8f9366a4ab3812479216c04 Mon Sep 17 00:00:00 2001 From: greye Date: Tue, 14 Aug 2012 22:39:42 +0400 Subject: [PATCH 10/30] fix 1st/preview/1st change; 1st invisible model --- apps/openmw/mwrender/player.cpp | 14 +++++++++++++- apps/openmw/mwrender/renderingmanager.cpp | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index c20ffad55..4a6ce0370 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -31,6 +31,8 @@ namespace MWRender mCameraNode->attachObject(mCamera); mCameraNode->setPosition(0.f, 0.f, mHeight); + mPlayerNode->setVisible(false); + mPreviewCam.yaw = 0.f; mPreviewCam.offset = 600.f; } @@ -140,9 +142,11 @@ namespace MWRender if (mFirstPersonView) { mCamera->setPosition(0.f, 0.f, 0.f); mCameraNode->setPosition(0.f, 0.f, 128.f); + mPlayerNode->setVisible(false); } else { mCamera->setPosition(0.f, 0.f, mCameraDistance); mCameraNode->setPosition(0.f, 0.f, 104.f); + mPlayerNode->setVisible(true); } } @@ -169,6 +173,7 @@ namespace MWRender float offset = 300.f; Ogre::Vector3 rot(0.f, 0.f, 0.f); if (mVanity.enabled) { + mPlayerNode->setVisible(true); rot.x = Ogre::Degree(-30.f).valueRadians(); mMainCam.offset = mCamera->getPosition().z; @@ -179,6 +184,9 @@ namespace MWRender moveCameraNode(mPlayerNode); } + if (offset == 0.f) { + mPlayerNode->setVisible(false); + } rot.z = getYaw(); mCamera->setPosition(0.f, 0.f, offset); rotateCamera(rot, false); @@ -194,6 +202,7 @@ namespace MWRender mPreviewMode = enable; float offset = mCamera->getPosition().z; if (mPreviewMode) { + mPlayerNode->setVisible(true); mMainCam.offset = offset; offset = mPreviewCam.offset; @@ -204,7 +213,10 @@ namespace MWRender moveCameraNode(mPlayerNode); } - mCamera->setPosition(0.f, 0.f, mPreviewCam.offset); + if (offset == 0.f) { + mPlayerNode->setVisible(false); + } + mCamera->setPosition(0.f, 0.f, offset); rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 8b6f483ca..87faba3e7 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -131,10 +131,10 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const SceneNode *rt = mRendering.getScene()->getRootSceneNode(); mMwRoot = rt->createChildSceneNode(); mMwRoot->pitch(Degree(-90)); + mObjects.setMwRoot(mMwRoot); mActors.setMwRoot(mMwRoot); - Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player"); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); From 575244bd35898c146c2e9cf81879504f8f8a4937 Mon Sep 17 00:00:00 2001 From: greye Date: Wed, 15 Aug 2012 15:17:35 +0400 Subject: [PATCH 11/30] fix SkaManager issue --- apps/openmw/mwrender/player.cpp | 23 +++++++++++------------ apps/openmw/mwrender/player.hpp | 4 +--- apps/openmw/mwrender/sky.cpp | 2 ++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 4a6ce0370..6e0012d43 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -31,8 +31,6 @@ namespace MWRender mCameraNode->attachObject(mCamera); mCameraNode->setPosition(0.f, 0.f, mHeight); - mPlayerNode->setVisible(false); - mPreviewCam.yaw = 0.f; mPreviewCam.offset = 600.f; } @@ -142,12 +140,11 @@ namespace MWRender if (mFirstPersonView) { mCamera->setPosition(0.f, 0.f, 0.f); mCameraNode->setPosition(0.f, 0.f, 128.f); - mPlayerNode->setVisible(false); } else { mCamera->setPosition(0.f, 0.f, mCameraDistance); mCameraNode->setPosition(0.f, 0.f, 104.f); - mPlayerNode->setVisible(true); } + mPlayerNode->setVisible(!mFirstPersonView, false); } void Player::allowVanityMode(bool allow) @@ -173,7 +170,7 @@ namespace MWRender float offset = 300.f; Ogre::Vector3 rot(0.f, 0.f, 0.f); if (mVanity.enabled) { - mPlayerNode->setVisible(true); + mPlayerNode->setVisible(true, false); rot.x = Ogre::Degree(-30.f).valueRadians(); mMainCam.offset = mCamera->getPosition().z; @@ -183,9 +180,7 @@ namespace MWRender offset = mMainCam.offset; moveCameraNode(mPlayerNode); - } - if (offset == 0.f) { - mPlayerNode->setVisible(false); + mPlayerNode->setVisible(!mFirstPersonView, false); } rot.z = getYaw(); mCamera->setPosition(0.f, 0.f, offset); @@ -202,7 +197,7 @@ namespace MWRender mPreviewMode = enable; float offset = mCamera->getPosition().z; if (mPreviewMode) { - mPlayerNode->setVisible(true); + mPlayerNode->setVisible(true, false); mMainCam.offset = offset; offset = mPreviewCam.offset; @@ -212,9 +207,7 @@ namespace MWRender offset = mMainCam.offset; moveCameraNode(mPlayerNode); - } - if (offset == 0.f) { - mPlayerNode->setVisible(false); + mPlayerNode->setVisible(!mFirstPersonView, false); } mCamera->setPosition(0.f, 0.f, offset); rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); @@ -300,6 +293,12 @@ namespace MWRender } } + void Player::setAnimation(NpcAnimation *anim) + { + mAnimation = anim; + mPlayerNode->setVisible(!mFirstPersonView, false); + } + void Player::setHeight(float height) { mHeight = height; diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 82af243bc..8c1b3ed9f 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -86,9 +86,7 @@ namespace MWRender void setCameraDistance(float dist, bool adjust = false); - void setAnimation(MWRender::NpcAnimation *anim) { - mAnimation = anim; - } + void setAnimation(MWRender::NpcAnimation *anim); void setHeight(float height); float getHeight(); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 9e551ba2a..3eb42a05e 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -405,6 +405,8 @@ void SkyManager::update(float duration) { if (!mEnabled) return; + mRootNode->setPosition(mCamera->getPosition()); + // UV Scroll the clouds mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer", From b97b3d7b71b07538657edd924976e5b294c4bf01 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Aug 2012 17:56:24 +0200 Subject: [PATCH 12/30] fix sky position when reflection is enabled, fix delay in sky reflection --- apps/openmw/mwrender/sky.cpp | 10 ++++++---- apps/openmw/mwrender/water.cpp | 4 +--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 3eb42a05e..eba605d0c 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -280,7 +280,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) , mMoonRed(false) { mSceneMgr = pMwRoot->getCreator(); - mRootNode = mCamera->getParentSceneNode()->createChildSceneNode(); + mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates mRootNode->setInheritOrientation(false); } @@ -405,7 +405,8 @@ void SkyManager::update(float duration) { if (!mEnabled) return; - mRootNode->setPosition(mCamera->getPosition()); + mCamera->getParentSceneNode ()->needUpdate (); + mRootNode->setPosition(mCamera->getDerivedPosition()); // UV Scroll the clouds mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); @@ -668,12 +669,13 @@ Ogre::SceneNode* SkyManager::getSunNode() void SkyManager::setSkyPosition(const Ogre::Vector3& position) { - mRootNode->_setDerivedPosition(position); + mRootNode->setPosition(position); } void SkyManager::resetSkyPosition() { - mRootNode->setPosition(0,0,0); + mCamera->getParentSceneNode ()->needUpdate (); + mRootNode->setPosition(mCamera->getDerivedPosition()); } void SkyManager::scaleSky(float scale) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index d5b93b7cb..46678f2bc 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -207,6 +207,7 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) { if (evt.source == mReflectionTarget) { + mCamera->getParentSceneNode ()->needUpdate (); mReflectionCamera->setOrientation(mCamera->getDerivedOrientation()); mReflectionCamera->setPosition(mCamera->getDerivedPosition()); mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance()); @@ -215,11 +216,9 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) mReflectionCamera->setFOVy(mCamera->getFOVy()); mReflectionRenderActive = true; - /// \todo the reflection render (and probably all renderingmanager-updates) lag behind 1 camera frame for some reason Vector3 pos = mCamera->getRealPosition(); pos.y = mTop*2 - pos.y; mSky->setSkyPosition(pos); - mSky->scaleSky(mCamera->getFarClipDistance() / 50.f); mReflectionCamera->enableReflection(mWaterPlane); } } @@ -229,7 +228,6 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) if (evt.source == mReflectionTarget) { mSky->resetSkyPosition(); - mSky->scaleSky(1); mReflectionCamera->disableReflection(); mReflectionCamera->disableCustomNearClipPlane(); mReflectionRenderActive = false; From 34f796c38e01d7701706179588d502c74326d998 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 Aug 2012 18:29:21 +0200 Subject: [PATCH 13/30] removed the far clip distance hack which is not needed anymore --- apps/openmw/mwrender/water.cpp | 16 ---------------- apps/openmw/mwrender/water.hpp | 3 --- 2 files changed, 19 deletions(-) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 46678f2bc..e79f308cd 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -32,7 +32,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel mIsUnderwater(false), mVisibilityFlags(0), mReflectionTarget(0), mActive(1), mToggled(1), mReflectionRenderActive(false), mRendering(rend), - mOldFarClip(0), mOldFarClip2(0), mWaterTimer(0.f) { mSky = rend->getSkyManager(); @@ -267,34 +266,19 @@ void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &in // We don't want the sky to get clipped by custom near clip plane (the water plane) if (queueGroupId < 20 && mReflectionRenderActive) { - mOldFarClip = mReflectionCamera->getFarClipDistance (); mReflectionCamera->disableCustomNearClipPlane(); - mReflectionCamera->setFarClipDistance (1000000000); Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); } - else if (queueGroupId == RQG_UnderWater) - {/* - mOldFarClip2 = mCamera->getFarClipDistance (); - mCamera->setFarClipDistance (1000000000); - Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); - */} } void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) { if (queueGroupId < 20 && mReflectionRenderActive) { - mReflectionCamera->setFarClipDistance (mOldFarClip); if (!mIsUnderwater) mReflectionCamera->enableCustomNearClipPlane(mErrorPlane); Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); } - if (queueGroupId == RQG_UnderWater) - { - /* - mCamera->setFarClipDistance (mOldFarClip2); - Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); - */} } void Water::update(float dt) diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index f56ba7410..dcb76533b 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -50,9 +50,6 @@ namespace MWRender { bool mToggled; int mTop; - int mOldFarClip; - int mOldFarClip2; - float mWaterTimer; bool mReflectionRenderActive; From a453a7f035fbd4e21a5790258fce123415309966 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 16 Aug 2012 13:15:38 +0400 Subject: [PATCH 14/30] camera adjustment, fix view mode on start --- apps/openmw/mwinput/inputmanagerimp.cpp | 3 +- apps/openmw/mwrender/player.cpp | 70 +++++++++++++++-------- apps/openmw/mwrender/player.hpp | 15 ++++- apps/openmw/mwrender/renderingmanager.cpp | 20 ++++++- 4 files changed, 80 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 9295233de..51c77e68e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -242,7 +242,8 @@ private: player(_player), windows(_windows), mEngine (engine), - mDragDrop(false) + mDragDrop(false), + mPreviewPOVDelay(0.f) { using namespace OEngine::Input; using namespace OEngine::Render; diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 6e0012d43..68def64e8 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -22,7 +22,8 @@ namespace MWRender mFirstPersonView(true), mPreviewMode(false), mHeight(128.f), - mCameraDistance(400.f) + mCameraDistance(300.f), + mDistanceAdjusted(false) { mVanity.enabled = false; mVanity.allowed = true; @@ -32,7 +33,7 @@ namespace MWRender mCameraNode->setPosition(0.f, 0.f, mHeight); mPreviewCam.yaw = 0.f; - mPreviewCam.offset = 600.f; + mPreviewCam.offset = 400.f; } bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) @@ -167,7 +168,7 @@ namespace MWRender mVanity.enabled = enable; mVanity.forced = force && enable; - float offset = 300.f; + float offset = mPreviewCam.offset; Ogre::Vector3 rot(0.f, 0.f, 0.f); if (mVanity.enabled) { mPlayerNode->setVisible(true, false); @@ -267,32 +268,45 @@ namespace MWRender node->addChild(mCameraNode); } - void Player::setCameraDistance(float dist, bool adjust) + void Player::setCameraDistance(float dist, bool adjust, bool override) { - /// \note non-Morrowind feature: allow to change camera distance - /// int 3d-person mode - /// \todo review and simplify condition if possible - if (mPreviewMode || - mVanity.forced || - (!mVanity.enabled && !mFirstPersonView)) - { - Ogre::Vector3 v(0.f, 0.f, dist); - if (adjust) { - v += mCamera->getPosition(); - } - if (v.z > 800.f) { - v.z = 800.f; - } else if (v.z < 100.f) { - v.z = 100.f; - } - mCamera->setPosition(v); + if (mFirstPersonView && !mPreviewMode && !mVanity.enabled) { + return; + } + Ogre::Vector3 v(0.f, 0.f, dist); + if (adjust) { + v += mCamera->getPosition(); + } + if (v.z > 800.f) { + v.z = 800.f; + } else if (v.z < 10.f) { + v.z = 10.f; + } + mCamera->setPosition(v); - if (!mVanity.enabled && !mFirstPersonView) { + if (override) { + if (mVanity.enabled || mPreviewMode) { + mPreviewCam.offset = v.z; + } else if (!mFirstPersonView) { mCameraDistance = v.z; } + } else { + mDistanceAdjusted = true; } } + void Player::setCameraDistance() + { + if (mDistanceAdjusted) { + if (mVanity.enabled || mPreviewMode) { + mCamera->setPosition(0, 0, mPreviewCam.offset); + } else if (!mFirstPersonView) { + mCamera->setPosition(0, 0, mCameraDistance); + } + } + mDistanceAdjusted = false; + } + void Player::setAnimation(NpcAnimation *anim) { mAnimation = anim; @@ -307,6 +321,16 @@ namespace MWRender float Player::getHeight() { - return mHeight; + return mHeight * mPlayerNode->getScale().z; + } + + bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera) + { + float xch; + camera = mCamera->getRealPosition(); + xch = camera.z, camera.z = camera.y, camera.y = -xch; + player = mPlayerNode->getPosition(); + + return mFirstPersonView && !mVanity.enabled && !mPreviewMode; } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 8c1b3ed9f..c3585db9d 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -43,6 +43,8 @@ namespace MWRender float mHeight, mCameraDistance; CamData mMainCam, mPreviewCam; + bool mDistanceAdjusted; + float mTimeIdle; int mUpdates; @@ -84,12 +86,23 @@ namespace MWRender void update(float duration); - void setCameraDistance(float dist, bool adjust = false); + /// Set camera distance for current mode. Don't work on 1st person view. + /// \param adjust Indicates should distance be adjusted or set. + /// \param override If true new distance will be used as default. + /// If false, default distance can be restored with setCameraDistance(). + void setCameraDistance(float dist, bool adjust = false, bool override = true); + + /// Restore default camera distance for current mode. + void setCameraDistance(); void setAnimation(MWRender::NpcAnimation *anim); void setHeight(float height); float getHeight(); + + /// Stores player and camera world positions in passed arguments + /// \return true if camera at the eye-place + bool getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera); }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 87faba3e7..f1d2029bb 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -41,7 +41,7 @@ using namespace Ogre; namespace MWRender { RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine) - :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) + :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine) { // select best shader mode bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); @@ -296,7 +296,22 @@ RenderingManager::moveObjectToCell( child->setPosition(pos); } -void RenderingManager::update (float duration){ +void RenderingManager::update (float duration) +{ + Ogre::Vector3 orig, dest; + mPlayer->setCameraDistance(); + if (!mPlayer->getPosition(orig, dest)) { + orig.z += mPlayer->getHeight() * mMwRoot->getScale().z; + + btVector3 btOrig(orig.x, orig.y, orig.z); + btVector3 btDest(dest.x, dest.y, dest.z); + std::pair test = + mPhysicsEngine->rayTest(btOrig, btDest); + if (!test.first.empty()) { + mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false); + } + } + mPlayer->update(duration); mActors.update (duration); mObjects.update (duration); @@ -339,7 +354,6 @@ void RenderingManager::update (float duration){ ); mWater->update(duration); } - mPlayer->update(duration); } void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ From 40c7a850bf2e7e889d7d17b5733705f27494bbf9 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 16 Aug 2012 15:42:03 +0400 Subject: [PATCH 15/30] fix pmove BB shape origin --- libs/openengine/bullet/trace.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 2d18aaa4d..89d654e6a 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -97,8 +97,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& - const btVector3 btstart(start.x, start.y, start.z); - const btVector3 btend(end.x, end.y, end.z); + const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.z); + const btVector3 btend(end.x, end.y, end.z + BBHalfExtents.z); const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); From e8fc942bef4b530e31e02a631717097478a04da0 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 16 Aug 2012 16:24:59 +0400 Subject: [PATCH 16/30] reverse Z-axis rotation to make doors happy --- apps/openmw/mwinput/mouselookevent.cpp | 2 +- apps/openmw/mwrender/player.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwinput/mouselookevent.cpp b/apps/openmw/mwinput/mouselookevent.cpp index 4138c481c..f318ce666 100644 --- a/apps/openmw/mwinput/mouselookevent.cpp +++ b/apps/openmw/mwinput/mouselookevent.cpp @@ -24,5 +24,5 @@ void MouseLookEvent::event(Type type, int index, const void *p) float y = arg->state.Y.rel * sensY; MWBase::World *world = MWBase::Environment::get().getWorld(); - world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, -x, true); + world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); } diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 68def64e8..8ad7e04b0 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -82,7 +82,7 @@ namespace MWRender Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X ); - Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::UNIT_Z); + Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z); pitchNode->setOrientation(xr); yawNode->setOrientation(zr); @@ -130,7 +130,7 @@ namespace MWRender } if (mVanity.enabled) { Ogre::Vector3 rot(0.f, 0.f, 0.f); - rot.z = Ogre::Degree(-3.f * duration).valueRadians(); + rot.z = Ogre::Degree(3.f * duration).valueRadians(); rotateCamera(rot, true); } } From 6961830efb5f4141d9ed97256672330d0a82109a Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 10:10:37 +0400 Subject: [PATCH 17/30] using real player eye direction when moving --- apps/openmw/mwrender/player.cpp | 12 ++++++++++++ apps/openmw/mwrender/player.hpp | 3 +++ apps/openmw/mwrender/renderingmanager.cpp | 7 +++++++ apps/openmw/mwrender/renderingmanager.hpp | 2 ++ apps/openmw/mwworld/physicssystem.cpp | 24 ++++++++++++++--------- apps/openmw/mwworld/physicssystem.hpp | 8 +++++++- apps/openmw/mwworld/worldimp.cpp | 5 +++++ 7 files changed, 51 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 8ad7e04b0..c9db96ead 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -11,6 +11,7 @@ #include "../mwworld/refdata.hpp" #include "npcanimation.hpp" +#include namespace MWRender { @@ -333,4 +334,15 @@ namespace MWRender return mFirstPersonView && !mVanity.enabled && !mPreviewMode; } + + Ogre::Vector3 Player::getPosition() + { + return mPlayerNode->getPosition(); + } + + void Player::getSightAngles(float &pitch, float &yaw) + { + pitch = mMainCam.pitch; + yaw = mMainCam.yaw; + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index c3585db9d..cc0fcac77 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -103,6 +103,9 @@ namespace MWRender /// Stores player and camera world positions in passed arguments /// \return true if camera at the eye-place bool getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera); + Ogre::Vector3 getPosition(); + + void getSightAngles(float &pitch, float &yaw); }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index f1d2029bb..2d29e8f55 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -856,4 +856,11 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) mPlayer->setAnimation(anim); } +void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) +{ + eyepos = mPlayer->getPosition(); + eyepos.z += mPlayer->getHeight(); + mPlayer->getSightAngles(pitch, yaw); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index aa07bbc22..170083556 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -72,6 +72,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList mPlayer->allowVanityMode(allow); } + void getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw); + void attachCameraTo(const MWWorld::Ptr &ptr); void renderPlayer(const MWWorld::Ptr &ptr); diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 1bbfe33fd..24e2cdbb1 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -16,6 +16,8 @@ #include "ptr.hpp" #include "class.hpp" +#include + using namespace Ogre; namespace MWWorld { @@ -42,10 +44,8 @@ namespace MWWorld return mEngine; } - std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world) - { - std::string handle = ""; - + std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world) + { //get a ray pointing to the center of the viewport Ray centerRay = mRender.getCamera()->getCameraToViewportRay( mRender.getViewport()->getWidth()/2, @@ -190,12 +190,11 @@ namespace MWWorld float pitch = 0.f; if (iter->first == "player") { - /// \fixme should not rely on player camera, real pitch needed - Ogre::SceneNode *node = mRender.getCamera()->getParentSceneNode(); - pitch = node->getOrientation().getPitch().valueDegrees(); + playerphysics->ps.viewangles.x = + Ogre::Radian(mPlayerData.pitch).valueDegrees(); - playerphysics->ps.viewangles.x = pitch - 90; - playerphysics->ps.viewangles.y = -yaw + 90; + playerphysics->ps.viewangles.y = + Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90; pm_ref.rightmove = -iter->second.x; pm_ref.forwardmove = -iter->second.y; @@ -392,4 +391,11 @@ namespace MWWorld return true; } + + void PhysicsSystem::updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw) + { + mPlayerData.eyepos = eyepos; + mPlayerData.pitch = pitch; + mPlayerData.yaw = yaw; + } } diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index e42fa536b..c6b8199fa 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -70,7 +70,14 @@ namespace MWWorld bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max); + void updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw); + private: + struct { + Ogre::Vector3 eyepos; + float pitch, yaw; + } mPlayerData; + OEngine::Render::OgreRenderer &mRender; OEngine::Physic::PhysicEngine* mEngine; bool mFreeFly; @@ -80,7 +87,6 @@ namespace MWWorld PhysicsSystem (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&); }; - } #endif diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 7a8f73034..655397c1f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -806,6 +806,11 @@ namespace MWWorld /// \todo split this function up into subfunctions mWorldScene->update (duration); + + float pitch, yaw; + Ogre::Vector3 eyepos; + mRendering->getPlayerData(eyepos, pitch, yaw); + mPhysics->updatePlayerData(eyepos, pitch, yaw); mWeatherManager->update (duration); From 60fb1e8df6dd3117ee6f0102d08e195b14c4c8ba Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 12:08:31 +0400 Subject: [PATCH 18/30] fix sky in preview mode movement --- apps/openmw/mwrender/player.cpp | 50 ++++++++++++++++++--------------- apps/openmw/mwrender/player.hpp | 2 +- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index c9db96ead..f85e949d0 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -19,7 +19,6 @@ namespace MWRender : mCamera(camera), mPlayerNode(node), mCameraNode(mPlayerNode->createChildSceneNode()), - mVanityNode(mPlayerNode->createChildSceneNode()), mFirstPersonView(true), mPreviewMode(false), mHeight(128.f), @@ -50,14 +49,14 @@ namespace MWRender /// \note rotate player on forced vanity if (mVanity.forced) { - moveCameraNode(mPlayerNode); - mVanity.enabled = false; + float diff = (adjust) ? rot.z : mMainCam.yaw - rot.z; + mVanity.enabled = false; rotateCamera(rot, adjust); - - moveCameraNode(mVanityNode); mVanity.enabled = true; + compensateYaw(diff); + trueRot.z = 0.f; } @@ -69,9 +68,6 @@ namespace MWRender void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) { - Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); - Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); - if (adjust) { setYaw(getYaw() + rot.z); setPitch(getPitch() + rot.x); @@ -83,11 +79,16 @@ namespace MWRender Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X ); - Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z); - - pitchNode->setOrientation(xr); - yawNode->setOrientation(zr); - + Ogre::Quaternion zr( + Ogre::Radian(getYaw()), + Ogre::Vector3::NEGATIVE_UNIT_Z + ); + if (!mVanity.enabled && !mPreviewMode) { + mPlayerNode->setOrientation(zr); + mCameraNode->setOrientation(xr); + } else { + mCameraNode->setOrientation(zr * xr); + } updateListener(); } @@ -176,12 +177,10 @@ namespace MWRender rot.x = Ogre::Degree(-30.f).valueRadians(); mMainCam.offset = mCamera->getPosition().z; - moveCameraNode(mVanityNode); } else { rot.x = getPitch(); offset = mMainCam.offset; - moveCameraNode(mPlayerNode); mPlayerNode->setVisible(!mFirstPersonView, false); } rot.z = getYaw(); @@ -203,12 +202,10 @@ namespace MWRender mMainCam.offset = offset; offset = mPreviewCam.offset; - moveCameraNode(mVanityNode); } else { mPreviewCam.offset = offset; offset = mMainCam.offset; - moveCameraNode(mPlayerNode); mPlayerNode->setVisible(!mFirstPersonView, false); } mCamera->setPosition(0.f, 0.f, offset); @@ -263,12 +260,6 @@ namespace MWRender } } - void Player::moveCameraNode(Ogre::SceneNode *node) - { - mCameraNode->getParentSceneNode()->removeChild(mCameraNode); - node->addChild(mCameraNode); - } - void Player::setCameraDistance(float dist, bool adjust, bool override) { if (mFirstPersonView && !mPreviewMode && !mVanity.enabled) { @@ -345,4 +336,17 @@ namespace MWRender pitch = mMainCam.pitch; yaw = mMainCam.yaw; } + + void Player::compensateYaw(float diff) + { + mPreviewCam.yaw -= diff; + Ogre::Quaternion zr( + Ogre::Radian(mPreviewCam.yaw), + Ogre::Vector3::NEGATIVE_UNIT_Z + ); + Ogre::Quaternion xr( + Ogre::Radian(mPreviewCam.pitch), + Ogre::Vector3::UNIT_X); + mCameraNode->setOrientation(zr * xr); + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index cc0fcac77..3f419889a 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -59,7 +59,7 @@ namespace MWRender float getPitch(); void setPitch(float angle); - void moveCameraNode(Ogre::SceneNode *node); + void compensateYaw(float diff); public: From 0e6e141fd484609ea95c748661e5342ee5dfc8a5 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 13:23:02 +0400 Subject: [PATCH 19/30] camera control related script instructions --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwinput/inputmanagerimp.cpp | 23 +++++++++++++--------- apps/openmw/mwinput/inputmanagerimp.hpp | 3 ++- apps/openmw/mwrender/player.cpp | 24 +++++++++++++++-------- apps/openmw/mwrender/player.hpp | 4 +++- apps/openmw/mwrender/renderingmanager.hpp | 4 ++++ apps/openmw/mwworld/worldimp.hpp | 4 ++++ 7 files changed, 44 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index fbc57b487..9c801cbff 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -253,6 +253,7 @@ namespace MWBase virtual void togglePreviewMode(bool enable) = 0; virtual bool toggleVanityMode(bool enable, bool force) = 0; virtual void allowVanityMode(bool allow) = 0; + virtual void togglePlayerLooking(bool enable) = 0; virtual void renderPlayer() = 0; }; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 51c77e68e..df0a42996 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -443,10 +443,7 @@ private: } else { - // Start mouse-looking again if allowed. - if (mControlSwitch["playerlooking"]) { - mouse->enable(); - } + mouse->enable(); // Disable GUI events guiEvents->enabled = false; @@ -467,16 +464,19 @@ private: } else if (sw == "playerjumping" && !value) { /// \fixme maybe crouching at this time player.setUpDown(0); + } else if (sw == "vanitymode") { + MWBase::Environment::get().getWorld()->allowVanityMode(value); } else if (sw == "playerlooking") { - if (value) { - mouse->enable(); - } else { - mouse->disable(); - } + MWBase::Environment::get().getWorld()->togglePlayerLooking(value); } mControlSwitch[sw] = value; } + bool getControlSwitch(std::string sw) + { + return mControlSwitch[sw]; + } + void togglePOV() { MWBase::Environment::get().getWorld()->togglePOV(); @@ -535,4 +535,9 @@ private: { impl->toggleControlSwitch(sw, value); } + + bool MWInputManager::getControlSwitch(std::string sw) + { + return impl->getControlSwitch(sw); + } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 70436e207..eff2236d4 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -60,7 +60,8 @@ namespace MWInput virtual void setDragDrop(bool dragDrop); - virtual void toggleControlSwitch (const std::string& sw, bool value); + void toggleControlSwitch(std::string sw, bool value); + bool getControlSwitch(std::string sw); }; } #endif diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index f85e949d0..3bbb56907 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -11,7 +11,6 @@ #include "../mwworld/refdata.hpp" #include "npcanimation.hpp" -#include namespace MWRender { @@ -21,6 +20,7 @@ namespace MWRender mCameraNode(mPlayerNode->createChildSceneNode()), mFirstPersonView(true), mPreviewMode(false), + mFreeLook(true), mHeight(128.f), mCameraDistance(300.f), mDistanceAdjusted(false) @@ -49,18 +49,21 @@ namespace MWRender /// \note rotate player on forced vanity if (mVanity.forced) { - float diff = (adjust) ? rot.z : mMainCam.yaw - rot.z; + if (mFreeLook) { + float diff = (adjust) ? rot.z : mMainCam.yaw - rot.z; - mVanity.enabled = false; - rotateCamera(rot, adjust); - mVanity.enabled = true; - - compensateYaw(diff); + mVanity.enabled = false; + rotateCamera(rot, adjust); + mVanity.enabled = true; + compensateYaw(diff); + } trueRot.z = 0.f; } - rotateCamera(trueRot, adjust); + if (mFreeLook || mVanity.enabled || mPreviewMode) { + rotateCamera(trueRot, adjust); + } /// \note if vanity mode is forced by TVM then rotate player return (!mVanity.enabled && !mPreviewMode) || mVanity.forced; @@ -349,4 +352,9 @@ namespace MWRender Ogre::Vector3::UNIT_X); mCameraNode->setOrientation(zr * xr); } + + void Player::togglePlayerLooking(bool enable) + { + mFreeLook = enable; + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 3f419889a..5bc32fffe 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -29,12 +29,12 @@ namespace MWRender Ogre::SceneNode *mPlayerNode; Ogre::SceneNode *mCameraNode; - Ogre::SceneNode *mVanityNode; NpcAnimation *mAnimation; bool mFirstPersonView; bool mPreviewMode; + bool mFreeLook; struct { bool enabled, allowed, forced; @@ -106,6 +106,8 @@ namespace MWRender Ogre::Vector3 getPosition(); void getSightAngles(float &pitch, float &yaw); + + void togglePlayerLooking(bool enable); }; } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 170083556..17a4d5280 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -72,6 +72,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList mPlayer->allowVanityMode(allow); } + virtual void togglePlayerLooking(bool enable) { + mPlayer->togglePlayerLooking(enable); + } + void getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw); void attachCameraTo(const MWWorld::Ptr &ptr); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 717c43cfa..51216e3a5 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -293,6 +293,10 @@ namespace MWWorld mRendering->allowVanityMode(allow); } + virtual void togglePlayerLooking(bool enable) { + mRendering->togglePlayerLooking(enable); + } + virtual void renderPlayer(); }; } From 4f10138a04d966e3fc579288f42e9e7d4d7c1fd7 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 15:07:12 +0400 Subject: [PATCH 20/30] using real player sight angles on ray cast --- apps/openmw/mwworld/physicssystem.cpp | 46 +++++++++++++++------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 24e2cdbb1..dfba26589 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -16,8 +16,6 @@ #include "ptr.hpp" #include "class.hpp" -#include - using namespace Ogre; namespace MWWorld { @@ -46,28 +44,36 @@ namespace MWWorld std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world) { - //get a ray pointing to the center of the viewport - Ray centerRay = mRender.getCamera()->getCameraToViewportRay( - mRender.getViewport()->getWidth()/2, - mRender.getViewport()->getHeight()/2); - //let's avoid the capsule shape of the player. - centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection()); - btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y); - btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y); - - return mEngine->rayTest(from,to); + btVector3 dir(0, 1, 0); + dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); + dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw); + dir.setX(-dir.x()); + + btVector3 origin( + mPlayerData.eyepos.x, + mPlayerData.eyepos.y, + mPlayerData.eyepos.z); + origin += dir * 5; + + btVector3 dest = origin + dir * 500; + return mEngine->rayTest(origin, dest); } std::vector < std::pair > PhysicsSystem::getFacedObjects () { - //get a ray pointing to the center of the viewport - Ray centerRay = mRender.getCamera()->getCameraToViewportRay( - mRender.getViewport()->getWidth()/2, - mRender.getViewport()->getHeight()/2); - btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y); - btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y); - - return mEngine->rayTest2(from,to); + btVector3 dir(0, 1, 0); + dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); + dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw); + dir.setX(-dir.x()); + + btVector3 origin( + mPlayerData.eyepos.x, + mPlayerData.eyepos.y, + mPlayerData.eyepos.z); + origin += dir * 5; + + btVector3 dest = origin + dir * 500; + return mEngine->rayTest2(origin, dest); } std::vector < std::pair > PhysicsSystem::getFacedObjects (float mouseX, float mouseY) From 7303d595dd0e342bab0bf567147918d4b336b5a1 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 15:36:51 +0400 Subject: [PATCH 21/30] resolving conflicts --- apps/openmw/mwbase/inputmanager.hpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 6 +++--- apps/openmw/mwinput/inputmanagerimp.hpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index d865bfb0e..fdbab9fac 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -22,7 +22,7 @@ namespace MWBase virtual ~InputManager() {} - virtual void update() = 0; + virtual void update(float duration) = 0; virtual void changeInputMode(bool guiMode) = 0; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index df0a42996..0945842b2 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -450,7 +450,7 @@ private: } } - void toggleControlSwitch(std::string sw, bool value) + void toggleControlSwitch(const std::string &sw, bool value) { if (mControlSwitch[sw] == value) { return; @@ -472,7 +472,7 @@ private: mControlSwitch[sw] = value; } - bool getControlSwitch(std::string sw) + bool getControlSwitch(const std::string &sw) { return mControlSwitch[sw]; } @@ -536,7 +536,7 @@ private: impl->toggleControlSwitch(sw, value); } - bool MWInputManager::getControlSwitch(std::string sw) + bool MWInputManager::getControlSwitch(const std::string &sw) { return impl->getControlSwitch(sw); } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index eff2236d4..d4ca32d2f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -60,8 +60,8 @@ namespace MWInput virtual void setDragDrop(bool dragDrop); - void toggleControlSwitch(std::string sw, bool value); - bool getControlSwitch(std::string sw); + void toggleControlSwitch(const std::string &sw, bool value); + bool getControlSwitch(const std::string &sw); }; } #endif From 1da56e28325d1371648b1e46fcd27fd3f4095b8f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Aug 2012 15:37:14 +0200 Subject: [PATCH 22/30] removed some unused variables --- apps/openmw/mwrender/player.cpp | 1 - apps/openmw/mwworld/physicssystem.cpp | 6 ------ components/nifogre/ogre_nif_loader.cpp | 4 ++-- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 3bbb56907..953543d99 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -119,7 +119,6 @@ namespace MWRender void Player::update(float duration) { - Ogre::Vector3 pos = mPlayerNode->getPosition(); if (!mVanity.enabled) { ++mUpdates; mTimeIdle += duration; diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index dfba26589..b7cb2778d 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -189,12 +189,6 @@ namespace MWWorld iter!=actors.end(); ++iter) { //dirty stuff to get the camera orientation. Must be changed! - Ogre::Quaternion orient = - mRender.getScene()->getSceneNode(iter->first)->getOrientation(); - - float yaw = orient.getRoll().valueDegrees(); - float pitch = 0.f; - if (iter->first == "player") { playerphysics->ps.viewangles.x = Ogre::Radian(mPlayerData.pitch).valueDegrees(); diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 4393749fb..0fdeaae3d 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -471,7 +471,7 @@ static Ogre::String getMaterial(const NiTriShape *shape, const Ogre::String &nam float glossiness = 0.0f; float alpha = 1.0f; int alphaFlags = -1; - ubyte alphaTest = 0; +// ubyte alphaTest = 0; Ogre::String texName; bool vertexColour = (shape->data->colors.size() != 0); @@ -523,7 +523,7 @@ static Ogre::String getMaterial(const NiTriShape *shape, const Ogre::String &nam if (a) { alphaFlags = a->flags; - alphaTest = a->data.threshold; +// alphaTest = a->data.threshold; } // Material From 3112bfb54f105a4d571f790f06f1499b99e7142d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Aug 2012 15:37:54 +0200 Subject: [PATCH 23/30] incremented version number --- CMakeLists.txt | 2 +- readme.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 543d9cb98..77efa186c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ include (OpenMWMacros) # Version set (OPENMW_VERSION_MAJOR 0) -set (OPENMW_VERSION_MINOR 16) +set (OPENMW_VERSION_MINOR 17) set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") diff --git a/readme.txt b/readme.txt index ce3d115e3..f146de71b 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. -Version: 0.16.0 +Version: 0.17.0 License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org From 296b61f476188925e19620c0add7e38809d66ecd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Aug 2012 15:40:46 +0200 Subject: [PATCH 24/30] updated changelog --- readme.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/readme.txt b/readme.txt index f146de71b..10a0a6f5d 100644 --- a/readme.txt +++ b/readme.txt @@ -97,6 +97,37 @@ Allowed options: CHANGELOG +0.17.0 + +Bug #225: Valgrind reports about 40MB of leaked memory +Bug #241: Some physics meshes still don't match +Bug #248: Some textures are too dark +Bug #300: Dependency on proprietary CG toolkit +Bug #302: Some objects don't collide although they should +Bug #308: Freeze in Balmora, Meldor: Armorer +Bug #313: openmw without a ~/.config/openmw folder segfault. +Bug #317: adding non-existing spell via console locks game +Bug #318: Wrong character normals +Bug #341: Building with Ogre Debug libraries does not use debug version of plugins +Bug #347: Crash when running openmw with --start="XYZ" +Bug #353: FindMyGUI.cmake breaks path on Windows +Bug #359: WindowManager throws exception at destruction +Feature #33: Allow objects to cross cell-borders +Feature #59: Dropping Items (replaced stopgap implementation with a proper one) +Feature #93: Main Menu +Feature #96/329/330/331/332/333: Player Control +Feature #180: Object rotation and scaling. +Feature #272: Incorrect NIF material sharing +Feature #314: Potion usage +Feature #324: Skill Gain +Feature #342: Drain/fortify dynamic stats/attributes magic effects +Feature #350: Allow console only script instructions +Feature #352: Run scripts in console on startup +Task #107: Refactor mw*-subsystems +Task #325: Make CreatureStats into a class +Task #345: Use Ogre's animation system +Task #351: Rewrite Action class to support automatic sound playing + 0.16.0 Bug #250: OpenMW launcher erratic behaviour From 7952d38e6cb154e02203a61cedf178e49374065e Mon Sep 17 00:00:00 2001 From: Michael Mc Donnell Date: Tue, 14 Aug 2012 14:45:16 -0400 Subject: [PATCH 25/30] Use debug dlls when debugging in vs2010 (try 2) Using the Debug build in vs2010 is not working because the debug dlls are not loaded when debugging. The reason they are not loaded is that CMAKE_BUILD_TYPE is not defined when doing multiple builds. This in turns causes OGRE_PLUGIN_DEBUG_SUFFIX not to be set. This patch makes sure that OGRE_PLUGIN_DEBUG_SUFFIX is always set but only used when debugging. It also defines DEBUG to make it easier turn things on and off when debugging. There are still other bugs that have broken Debug mode in vs2010 but those will be addressed in other patches. --- CMakeLists.txt | 10 ++++++---- components/files/ogreplugin.cpp | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 543d9cb98..d611e53d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,13 +257,15 @@ if (APPLE) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) endif (APPLE) +# Set up DEBUG define +set_directory_properties(PROPERTIES COMPILE_DEFINITIONS_DEBUG DEBUG=1) # Set up Ogre plugin folder & debug suffix -# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) -if (DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE) - add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") -else() +if (APPLE) + # Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") +else () + add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") endif() add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}") diff --git a/components/files/ogreplugin.cpp b/components/files/ogreplugin.cpp index c434114b3..ca90fd30e 100644 --- a/components/files/ogreplugin.cpp +++ b/components/files/ogreplugin.cpp @@ -6,7 +6,11 @@ namespace Files { bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) { + // Append plugin suffix if debugging. +#if defined(DEBUG) pluginName = pluginName + OGRE_PLUGIN_DEBUG_SUFFIX; +#endif + #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE std::ostringstream verStream; verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH; From 8817a9634ccbab8bae0241b064a646304f24b115 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Aug 2012 16:55:21 +0200 Subject: [PATCH 26/30] don't switch to vanity mode as a result of idle time when the gui is opened (e.g. when talking to someone) --- apps/openmw/mwrender/player.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 953543d99..fb8109a1d 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -5,6 +5,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" @@ -119,7 +120,8 @@ namespace MWRender void Player::update(float duration) { - if (!mVanity.enabled) { + bool isGuiMode = MWBase::Environment::get().getWindowManager ()->isGuiMode(); + if (!mVanity.enabled && !isGuiMode) { ++mUpdates; mTimeIdle += duration; if (mTimeIdle > 30.f) { From b6954a4e8d251c7152ddc6278407f4d9c204fd18 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 22:08:16 +0400 Subject: [PATCH 27/30] use the same height on non-1st person modes --- apps/openmw/mwrender/player.cpp | 32 +++++++++++++++++--------------- apps/openmw/mwrender/player.hpp | 5 ++--- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 3bbb56907..98cb1695e 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -2,7 +2,6 @@ #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" @@ -38,9 +37,6 @@ namespace MWRender bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) { - mUpdates = 0; - mTimeIdle = 0.f; - if (mVanity.enabled) { toggleVanityMode(false); } @@ -120,13 +116,6 @@ namespace MWRender void Player::update(float duration) { Ogre::Vector3 pos = mPlayerNode->getPosition(); - if (!mVanity.enabled) { - ++mUpdates; - mTimeIdle += duration; - if (mTimeIdle > 30.f) { - toggleVanityMode(true); - } - } if (mAnimation) { mAnimation->runAnimation(duration); } @@ -145,10 +134,10 @@ namespace MWRender mFirstPersonView = !mFirstPersonView; if (mFirstPersonView) { mCamera->setPosition(0.f, 0.f, 0.f); - mCameraNode->setPosition(0.f, 0.f, 128.f); + setLowHeight(false); } else { mCamera->setPosition(0.f, 0.f, mCameraDistance); - mCameraNode->setPosition(0.f, 0.f, 104.f); + setLowHeight(true); } mPlayerNode->setVisible(!mFirstPersonView, false); } @@ -176,15 +165,17 @@ namespace MWRender float offset = mPreviewCam.offset; Ogre::Vector3 rot(0.f, 0.f, 0.f); if (mVanity.enabled) { - mPlayerNode->setVisible(true, false); rot.x = Ogre::Degree(-30.f).valueRadians(); mMainCam.offset = mCamera->getPosition().z; + mPlayerNode->setVisible(true, false); + setLowHeight(true); } else { rot.x = getPitch(); offset = mMainCam.offset; mPlayerNode->setVisible(!mFirstPersonView, false); + setLowHeight(!mFirstPersonView); } rot.z = getYaw(); mCamera->setPosition(0.f, 0.f, offset); @@ -201,15 +192,17 @@ namespace MWRender mPreviewMode = enable; float offset = mCamera->getPosition().z; if (mPreviewMode) { - mPlayerNode->setVisible(true, false); mMainCam.offset = offset; offset = mPreviewCam.offset; + mPlayerNode->setVisible(true, false); + setLowHeight(true); } else { mPreviewCam.offset = offset; offset = mMainCam.offset; mPlayerNode->setVisible(!mFirstPersonView, false); + setLowHeight(!mFirstPersonView); } mCamera->setPosition(0.f, 0.f, offset); rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); @@ -357,4 +350,13 @@ namespace MWRender { mFreeLook = enable; } + + void Player::setLowHeight(bool low) + { + if (low) { + mCameraNode->setPosition(0.f, 0.f, mHeight * 0.85); + } else { + mCameraNode->setPosition(0.f, 0.f, mHeight); + } + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 5bc32fffe..8dd313b7f 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -45,9 +45,6 @@ namespace MWRender bool mDistanceAdjusted; - float mTimeIdle; - int mUpdates; - /// Updates sound manager listener data void updateListener(); @@ -61,6 +58,8 @@ namespace MWRender void compensateYaw(float diff); + void setLowHeight(bool low = true); + public: Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); From d2b451eb7d7d9374f36c160e043776808205d2c0 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 23:25:29 +0400 Subject: [PATCH 28/30] entering vanity mode --- apps/openmw/mwbase/inputmanager.hpp | 2 + apps/openmw/mwinput/inputmanagerimp.cpp | 59 +++++++++++++++++++++---- apps/openmw/mwinput/inputmanagerimp.hpp | 3 +- apps/openmw/mwinput/mouselookevent.cpp | 2 + 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index fdbab9fac..00d7c8125 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -31,6 +31,8 @@ namespace MWBase virtual void setDragDrop(bool dragDrop) = 0; virtual void toggleControlSwitch (const std::string& sw, bool value) = 0; + + virtual void resetIdleTime() = 0; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 0945842b2..c78643f59 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -92,6 +92,7 @@ namespace MWInput std::map mControlSwitch; float mPreviewPOVDelay; + float mTimeIdle; /* InputImpl Methods */ public: @@ -99,11 +100,34 @@ public: { input.adjustMouseClippingSize(width, height); } + + void resetIdleTime() + { + if (mTimeIdle < 0) { + MWBase::Environment::get().getWorld()->toggleVanityMode(false, false); + } + mTimeIdle = 0.f; + } + private: + + void updateIdleTime(float dt) + { + if (mTimeIdle >= 0.f) { + mTimeIdle += dt; + } + if (mTimeIdle > 30.f) { + MWBase::Environment::get().getWorld()->toggleVanityMode(true, false); + mTimeIdle = -1.f; + } + } + void toggleSpell() { if (windows.isGuiMode()) return; + resetIdleTime(); + MWMechanics::DrawState_ state = player.getDrawState(); if (state == MWMechanics::DrawState_Weapon || state == MWMechanics::DrawState_Nothing) { @@ -121,6 +145,8 @@ private: { if (windows.isGuiMode()) return; + resetIdleTime(); + MWMechanics::DrawState_ state = player.getDrawState(); if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) { @@ -200,18 +226,26 @@ private: void activate() { + resetIdleTime(); + mEngine.activate(); } void toggleAutoMove() { if (windows.isGuiMode()) return; + + resetIdleTime(); + player.setAutoMove (!player.getAutoMove()); } void toggleWalking() { if (windows.isGuiMode()) return; + + resetIdleTime(); + player.toggleRunning(); } @@ -243,7 +277,8 @@ private: windows(_windows), mEngine (engine), mDragDrop(false), - mPreviewPOVDelay(0.f) + mPreviewPOVDelay(0.f), + mTimeIdle(0.f) { using namespace OEngine::Input; using namespace OEngine::Render; @@ -426,6 +461,19 @@ private: } } } + // Idle time update despite of control switches + if (poller.isDown(A_MoveLeft) || + poller.isDown(A_MoveRight) || + poller.isDown(A_MoveForward) || + poller.isDown(A_MoveBackward) || + poller.isDown(A_Jump) || + poller.isDown(A_Crouch) || + poller.isDown(A_TogglePOV)) + { + resetIdleTime(); + } else { + updateIdleTime(duration); + } } // Switch between gui modes. Besides controlling the Gui windows @@ -472,11 +520,6 @@ private: mControlSwitch[sw] = value; } - bool getControlSwitch(const std::string &sw) - { - return mControlSwitch[sw]; - } - void togglePOV() { MWBase::Environment::get().getWorld()->togglePOV(); @@ -536,8 +579,8 @@ private: impl->toggleControlSwitch(sw, value); } - bool MWInputManager::getControlSwitch(const std::string &sw) + void MWInputManager::resetIdleTime() { - return impl->getControlSwitch(sw); + impl->resetIdleTime(); } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index d4ca32d2f..868565dbb 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -61,7 +61,8 @@ namespace MWInput virtual void setDragDrop(bool dragDrop); void toggleControlSwitch(const std::string &sw, bool value); - bool getControlSwitch(const std::string &sw); + + void resetIdleTime(); }; } #endif diff --git a/apps/openmw/mwinput/mouselookevent.cpp b/apps/openmw/mwinput/mouselookevent.cpp index f318ce666..e6852d923 100644 --- a/apps/openmw/mwinput/mouselookevent.cpp +++ b/apps/openmw/mwinput/mouselookevent.cpp @@ -1,6 +1,7 @@ #include "mouselookevent.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/player.hpp" @@ -17,6 +18,7 @@ void MouseLookEvent::event(Type type, int index, const void *p) if (type != EV_MouseMove || mDisabled) { return; } + MWBase::Environment::get().getInputManager()->resetIdleTime(); MouseEvent *arg = (MouseEvent*)(p); From 3f3972eb3b0e73417de662245a07315b2dc18c19 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 17 Aug 2012 23:44:28 +0400 Subject: [PATCH 29/30] no vanity in gui mode (thanks scrawl) --- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index c78643f59..638bc6047 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -116,7 +116,7 @@ private: if (mTimeIdle >= 0.f) { mTimeIdle += dt; } - if (mTimeIdle > 30.f) { + if (mTimeIdle > 30.f && !windows.isGuiMode()) { MWBase::Environment::get().getWorld()->toggleVanityMode(true, false); mTimeIdle = -1.f; } From 5b2b378f25f4c94d7885879899508cea70df140e Mon Sep 17 00:00:00 2001 From: greye Date: Sat, 18 Aug 2012 18:05:10 +0400 Subject: [PATCH 30/30] tvm script instruction --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwrender/player.hpp | 4 ++++ apps/openmw/mwrender/renderingmanager.hpp | 10 ++++++--- apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/miscextensions.cpp | 27 +++++++++++++++++++++++ apps/openmw/mwworld/worldimp.hpp | 4 ++++ 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 9c801cbff..5e97b4922 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -254,6 +254,7 @@ namespace MWBase virtual bool toggleVanityMode(bool enable, bool force) = 0; virtual void allowVanityMode(bool allow) = 0; virtual void togglePlayerLooking(bool enable) = 0; + virtual bool isVanityEnabled() = 0; virtual void renderPlayer() = 0; }; diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 8dd313b7f..e56abc17d 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -107,6 +107,10 @@ namespace MWRender void getSightAngles(float &pitch, float &yaw); void togglePlayerLooking(bool enable); + + bool isVanityEnabled() { + return mVanity.enabled; + } }; } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 17a4d5280..003a61a39 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -64,15 +64,19 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList mPlayer->togglePreviewMode(enable); } - virtual bool toggleVanityMode(bool enable, bool force) { + bool toggleVanityMode(bool enable, bool force) { return mPlayer->toggleVanityMode(enable, force); } - virtual void allowVanityMode(bool allow) { + bool isVanityEnabled() { + return mPlayer->isVanityEnabled(); + } + + void allowVanityMode(bool allow) { mPlayer->allowVanityMode(allow); } - virtual void togglePlayerLooking(bool enable) { + void togglePlayerLooking(bool enable) { mPlayer->togglePlayerLooking(enable); } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 1ea5f8e3e..dbc8159d1 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -181,4 +181,5 @@ op 0x2000170: user4, explicit reference (console only, requires --script-console op 0x2000171: user4 (implicit reference, console only, requires --script-console switch) op 0x2000172: GetStartingAngle op 0x2000173: GetStartingAngle, explicit reference -opcodes 0x2000174-0x3ffffff unused +op 0x2000174: ToggleVanityMode +opcodes 0x2000175-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 0c328e0da..e9e29bdae 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -207,6 +207,29 @@ namespace MWScript } }; + class OpToggleVanityMode : public Interpreter::Opcode0 + { + public: + + virtual void execute(Interpreter::Runtime &runtime) + { + InterpreterContext& context = + static_cast (runtime.getContext()); + + MWBase::World *world = + MWBase::Environment::get().getWorld(); + + bool value = !world->isVanityEnabled(); + if (world->toggleVanityMode(value, true)) { + context.report( + (value) ? "Vanity Mode -> On" : "Vanity Mode -> Off" + ); + } else { + context.report("Vanity Mode -> No"); + } + } + }; + const int opcodeXBox = 0x200000c; const int opcodeOnActivate = 0x200000d; const int opcodeActivate = 0x2000075; @@ -222,6 +245,7 @@ namespace MWScript const int opcodeToggleWater = 0x2000144; const int opcodeTogglePathgrid = 0x2000146; const int opcodeDontSaveObject = 0x2000153; + const int opcodeToggleVanityMode = 0x2000174; void registerExtensions (Compiler::Extensions& extensions) { @@ -244,6 +268,8 @@ namespace MWScript extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid); extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid); extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject); + extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode); + extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -263,6 +289,7 @@ namespace MWScript interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid); interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater); interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject); + interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode); } } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 51216e3a5..889741989 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -298,6 +298,10 @@ namespace MWWorld } virtual void renderPlayer(); + + virtual bool isVanityEnabled() { + return mRendering->isVanityEnabled(); + } }; }