From a453a7f035fbd4e21a5790258fce123415309966 Mon Sep 17 00:00:00 2001 From: greye Date: Thu, 16 Aug 2012 13:15:38 +0400 Subject: [PATCH] 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){