diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 9fa5e38a28..941222b0c6 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -22,8 +22,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender actors objects renderingmanager animation sky npcanimation vismask creatureanimation effectmanager util renderinginterface pathgrid rendermode - bulletdebugdraw globalmap characterpreview -# camera + bulletdebugdraw globalmap characterpreview camera # localmap occlusionquery water shadows # ripplesimulation refraction # terrainstorage weaponanimation diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index ca21e36125..5ce1607b5a 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -5,7 +5,6 @@ #include -#include #include #include @@ -592,8 +591,6 @@ void OMW::Engine::go() } // Start the main rendering loop - mViewer->setCameraManipulator(new osgGA::TrackballManipulator); - osg::Timer frameTimer; while (!mViewer->done() && !MWBase::Environment::get().getStateManager()->hasQuitRequest()) { diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index df6d6e9f25..416f66cec6 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -249,6 +249,11 @@ namespace MWRender mInsert->removeChild(mObjectRoot); } + MWWorld::Ptr Animation::getPtr() + { + return mPtr; + } + void Animation::setActive(bool active) { if (SceneUtil::Skeleton* skel = dynamic_cast(mObjectRoot.get())) diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 119814135e..82b54bdeaa 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -254,6 +254,8 @@ public: Animation(const MWWorld::Ptr &ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem); virtual ~Animation(); + MWWorld::Ptr getPtr(); + /// Set active flag on the object skeleton, if one exists. /// @see SceneUtil::Skeleton::setActive void setActive(bool active); diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index c7a27dfe8f..a92f901583 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -1,9 +1,6 @@ #include "camera.hpp" -#include -#include -#include -#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -13,12 +10,38 @@ #include "npcanimation.hpp" +namespace +{ + +class UpdateCameraCallback : public osg::NodeCallback +{ +public: + UpdateCameraCallback(MWRender::Camera* cam) + : mCamera(cam) + { + } + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + osg::Camera* cam = static_cast(node); + + // traverse first to update animations, in case the camera is attached to an animated node + traverse(node, nv); + + mCamera->updateCamera(cam); + } + +private: + MWRender::Camera* mCamera; +}; + +} + namespace MWRender { - Camera::Camera (Ogre::Camera *camera) + + Camera::Camera (osg::Camera* camera) : mCamera(camera), - mCameraNode(NULL), - mCameraPosNode(NULL), mAnimation(NULL), mFirstPersonView(true), mPreviewMode(false), @@ -27,10 +50,11 @@ namespace MWRender mFurthest(800.f), mIsNearest(false), mHeight(124.f), - mCameraDistance(192.f), + mMaxCameraDistance(192.f), mDistanceAdjusted(false), mVanityToggleQueued(false), - mViewModeToggleQueued(false) + mViewModeToggleQueued(false), + mCameraDistance(0.f) { mVanity.enabled = false; mVanity.allowed = true; @@ -41,10 +65,46 @@ namespace MWRender mMainCam.pitch = 0.f; mMainCam.yaw = 0.f; mMainCam.offset = 400.f; + + mUpdateCallback = new UpdateCameraCallback(this); + mCamera->addUpdateCallback(mUpdateCallback); } Camera::~Camera() { + mCamera->removeUpdateCallback(mUpdateCallback); + } + + MWWorld::Ptr Camera::getTrackingPtr() const + { + return mTrackingPtr; + } + + void Camera::updateCamera(osg::Camera *cam) + { + if (mTrackingPtr.isEmpty()) + return; + const osg::Node* trackNode = mTrackingNode; + if (!trackNode) + return; + osg::MatrixList mats = trackNode->getWorldMatrices(); + if (!mats.size()) + return; + const osg::Matrix& worldMat = mats[0]; + + osg::Vec3 position = worldMat.getTrans(); + if (!isFirstPerson()) + position.z() += mHeight; + + osg::Quat orient = osg::Quat(getPitch(), osg::Vec3(1,0,0)) * osg::Quat(getYaw(), osg::Vec3(0,0,1)); + + osg::Vec3 offset = orient * osg::Vec3(0, -mCameraDistance, 0); + position += offset; + + osg::Vec3 forward = orient * osg::Vec3(0,1,0); + osg::Vec3 up = orient * osg::Vec3(0,0,1); + + cam->setViewMatrixAsLookAt(position, position + forward, up); } void Camera::reset() @@ -55,68 +115,20 @@ namespace MWRender toggleViewMode(); } - void Camera::rotateCamera(const Ogre::Vector3 &rot, bool adjust) + void Camera::rotateCamera(float pitch, float yaw, bool adjust) { - if (adjust) { - setYaw(getYaw() + rot.z); - setPitch(getPitch() + rot.x); - } else { - setYaw(rot.z); - setPitch(rot.x); + if (adjust) + { + pitch += getPitch(); + yaw += getYaw(); } - - Ogre::Quaternion xr(Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X); - Ogre::Quaternion orient = xr; - if (mVanity.enabled || mPreviewMode) { - Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::UNIT_Z); - orient = zr * xr; - } - - if (isFirstPerson()) - mCamera->getParentNode()->setOrientation(orient); - else - mCameraNode->setOrientation(orient); + setYaw(yaw); + setPitch(pitch); } - const std::string &Camera::getHandle() const - { - return mTrackingPtr.getRefData().getHandle(); - } - - Ogre::SceneNode* Camera::attachTo(const MWWorld::Ptr &ptr) + void Camera::attachTo(const MWWorld::Ptr &ptr) { mTrackingPtr = ptr; - Ogre::SceneNode *node = mTrackingPtr.getRefData().getBaseNode()->createChildSceneNode(Ogre::Vector3(0.0f, 0.0f, mHeight)); - node->setInheritScale(false); - Ogre::SceneNode *posNode = node->createChildSceneNode(); - posNode->setInheritScale(false); - if(mCameraNode) - { - node->setOrientation(mCameraNode->getOrientation()); - posNode->setPosition(mCameraPosNode->getPosition()); - mCameraNode->getCreator()->destroySceneNode(mCameraNode); - mCameraNode->getCreator()->destroySceneNode(mCameraPosNode); - } - mCameraNode = node; - mCameraPosNode = posNode; - - if (!isFirstPerson()) - { - mCamera->detachFromParent(); - mCameraPosNode->attachObject(mCamera); - } - - return mCameraPosNode; - } - - void Camera::setPosition(const Ogre::Vector3& position) - { - mCameraPosNode->setPosition(position); - } - - void Camera::setPosition(float x, float y, float z) - { - setPosition(Ogre::Vector3(x,y,z)); } void Camera::update(float duration, bool paused) @@ -147,9 +159,7 @@ namespace MWRender if(mVanity.enabled) { - Ogre::Vector3 rot(0.f, 0.f, 0.f); - rot.z = Ogre::Degree(3.f * duration).valueRadians(); - rotateCamera(rot, true); + rotateCamera(0.f, osg::DegreesToRadians(3.f * duration), true); } } @@ -169,9 +179,9 @@ namespace MWRender processViewChange(); if (mFirstPersonView) { - setPosition(0.f, 0.f, 0.f); + mCameraDistance = 0.f; } else { - setPosition(0.f, 0.f, mCameraDistance); + mCameraDistance = mMaxCameraDistance; } } @@ -202,18 +212,15 @@ namespace MWRender processViewChange(); float offset = mPreviewCam.offset; - Ogre::Vector3 rot(0.f, 0.f, 0.f); + if (mVanity.enabled) { - rot.x = Ogre::Degree(-30.f).valueRadians(); - mMainCam.offset = mCameraPosNode->getPosition().z; + setPitch(osg::DegreesToRadians(-30.f)); + mMainCam.offset = mCameraDistance; } else { - rot.x = getPitch(); offset = mMainCam.offset; } - rot.z = getYaw(); - setPosition(0.f, 0.f, offset); - rotateCamera(rot, false); + mCameraDistance = offset; return true; } @@ -229,7 +236,7 @@ namespace MWRender mPreviewMode = enable; processViewChange(); - float offset = mCameraPosNode->getPosition().z; + float offset = mCameraDistance; if (mPreviewMode) { mMainCam.offset = offset; offset = mPreviewCam.offset; @@ -238,13 +245,12 @@ namespace MWRender offset = mMainCam.offset; } - setPosition(0.f, 0.f, offset); + mCameraDistance = offset; } void Camera::setSneakOffset(float offset) { - if(mAnimation) - mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -offset)); + // TODO: implement } float Camera::getYaw() @@ -256,10 +262,10 @@ namespace MWRender void Camera::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 (angle > osg::PI) { + angle -= osg::PI*2; + } else if (angle < -osg::PI) { + angle += osg::PI*2; } if (mVanity.enabled || mPreviewMode) { mPreviewCam.yaw = angle; @@ -279,7 +285,7 @@ namespace MWRender void Camera::setPitch(float angle) { const float epsilon = 0.000001f; - float limit = Ogre::Math::HALF_PI - epsilon; + float limit = osg::PI_2 - epsilon; if(mPreviewMode) limit /= 2; @@ -297,7 +303,7 @@ namespace MWRender float Camera::getCameraDistance() const { - return mCameraPosNode->getPosition().z; + return mCameraDistance; } void Camera::setCameraDistance(float dist, bool adjust, bool override) @@ -307,25 +313,24 @@ namespace MWRender mIsNearest = false; - Ogre::Vector3 v(0.f, 0.f, dist); - if (adjust) { - v += mCameraPosNode->getPosition(); - } - if (v.z >= mFurthest) { - v.z = mFurthest; - } else if (!override && v.z < 10.f) { - v.z = 10.f; - } else if (override && v.z <= mNearest) { - v.z = mNearest; + if (adjust) + dist += mCameraDistance; + + if (dist >= mFurthest) { + dist = mFurthest; + } else if (!override && dist < 10.f) { + dist = -10.f; + } else if (override && dist <= mNearest) { + dist = -mNearest; mIsNearest = true; } - setPosition(v); + mCameraDistance = dist; if (override) { if (mVanity.enabled || mPreviewMode) { - mPreviewCam.offset = v.z; + mPreviewCam.offset = mCameraDistance; } else if (!mFirstPersonView) { - mCameraDistance = v.z; + mMaxCameraDistance = mCameraDistance; } } else { mDistanceAdjusted = true; @@ -336,9 +341,9 @@ namespace MWRender { if (mDistanceAdjusted) { if (mVanity.enabled || mPreviewMode) { - setPosition(0, 0, mPreviewCam.offset); + mCameraDistance = mPreviewCam.offset; } else if (!mFirstPersonView) { - setPosition(0, 0, mCameraDistance); + mCameraDistance = mMaxCameraDistance; } } mDistanceAdjusted = false; @@ -351,7 +356,6 @@ namespace MWRender if(mAnimation && mAnimation != anim) { mAnimation->setViewMode(NpcAnimation::VM_Normal); - mAnimation->detachObjectFromBone(mCamera); } mAnimation = anim; @@ -360,29 +364,25 @@ namespace MWRender void Camera::processViewChange() { - mAnimation->detachObjectFromBone(mCamera); - mCamera->detachFromParent(); - if(isFirstPerson()) { mAnimation->setViewMode(NpcAnimation::VM_FirstPerson); - Ogre::TagPoint *tag = mAnimation->attachObjectToBone("Head", mCamera); - tag->setInheritOrientation(false); + mTrackingNode = mAnimation->getNode("Head"); } else { mAnimation->setViewMode(NpcAnimation::VM_Normal); - mCameraPosNode->attachObject(mCamera); + mTrackingNode = mTrackingPtr.getRefData().getBaseNode(); } - rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); + rotateCamera(getPitch(), getYaw(), false); } - void Camera::getPosition(Ogre::Vector3 &focal, Ogre::Vector3 &camera) + void Camera::getPosition(osg::Vec3 &focal, osg::Vec3 &camera) { - mCamera->getParentSceneNode()->needUpdate(true); + //mCamera->getParentSceneNode()->needUpdate(true); - camera = mCamera->getRealPosition(); - focal = mCameraNode->_getDerivedPosition(); + //camera = mCamera->getRealPosition(); + //focal = mCameraNode->_getDerivedPosition(); } void Camera::togglePlayerLooking(bool enable) diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index 691a80862b..68f0870d71 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -3,13 +3,16 @@ #include +#include +#include + #include "../mwworld/ptr.hpp" -namespace Ogre +namespace osg { - class Vector3; class Camera; - class SceneNode; + class NodeCallback; + class Node; } namespace MWRender @@ -24,10 +27,9 @@ namespace MWRender }; MWWorld::Ptr mTrackingPtr; + osg::ref_ptr mTrackingNode; - Ogre::Camera *mCamera; - Ogre::SceneNode *mCameraNode; - Ogre::SceneNode *mCameraPosNode; + osg::ref_ptr mCamera; NpcAnimation *mAnimation; @@ -42,7 +44,7 @@ namespace MWRender bool enabled, allowed; } mVanity; - float mHeight, mCameraDistance; + float mHeight, mMaxCameraDistance; CamData mMainCam, mPreviewCam; bool mDistanceAdjusted; @@ -50,19 +52,25 @@ namespace MWRender bool mVanityToggleQueued; bool mViewModeToggleQueued; - void setPosition(const Ogre::Vector3& position); - void setPosition(float x, float y, float z); + float mCameraDistance; + + osg::ref_ptr mUpdateCallback; public: - Camera(Ogre::Camera *camera); + Camera(osg::Camera* camera); ~Camera(); + MWWorld::Ptr getTrackingPtr() const; + + /// Update the view matrix of \a cam + void updateCamera(osg::Camera* cam); + /// Reset to defaults void reset(); /// Set where the camera is looking at. Uses Morrowind (euler) angles /// \param rot Rotation angles in radians - void rotateCamera(const Ogre::Vector3 &rot, bool adjust); + void rotateCamera(float pitch, float yaw, bool adjust); float getYaw(); void setYaw(float angle); @@ -70,10 +78,8 @@ namespace MWRender float getPitch(); void setPitch(float angle); - const std::string &getHandle() const; - /// Attach camera to object - Ogre::SceneNode* attachTo(const MWWorld::Ptr &); + void attachTo(const MWWorld::Ptr &); /// @param Force view mode switch, even if currently not allowed by the animation. void toggleViewMode(bool force=false); @@ -85,9 +91,6 @@ namespace MWRender void togglePreviewMode(bool enable); /// \brief Lowers the camera for sneak. - /// As animation is tied to the camera, this needs - /// to be set each frame after the animation is - /// applied. void setSneakOffset(float offset); bool isFirstPerson() const @@ -111,7 +114,7 @@ namespace MWRender void setAnimation(NpcAnimation *anim); /// Stores focal and camera world positions in passed arguments - void getPosition(Ogre::Vector3 &focal, Ogre::Vector3 &camera); + void getPosition(osg::Vec3 &focal, osg::Vec3 &camera); void togglePlayerLooking(bool enable); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5ece10dc13..bbff16a10f 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -31,6 +31,7 @@ #include "npcanimation.hpp" #include "vismask.hpp" #include "pathgrid.hpp" +#include "camera.hpp" namespace MWRender { @@ -104,6 +105,8 @@ namespace MWRender mEffectManager.reset(new EffectManager(mRootNode, mResourceSystem)); + mCamera.reset(new Camera(mViewer->getCamera())); + mViewer->setLightingMode(osgViewer::View::NO_LIGHT); osg::ref_ptr source = new osg::LightSource; @@ -253,11 +256,21 @@ namespace MWRender mSky->update(dt); } + void RenderingManager::updatePlayerPtr(const MWWorld::Ptr &ptr) + { + if(mPlayerAnimation.get()) + mPlayerAnimation->updatePtr(ptr); + + mCamera->attachTo(ptr); + } + void RenderingManager::rotateObject(const MWWorld::Ptr &ptr, const osg::Quat& rot) { - //if(ptr.getRefData().getHandle() == mCamera->getHandle() && - // !mCamera->isVanityOrPreviewModeEnabled()) - // mCamera->rotateCamera(-rot, false); + if(ptr == mCamera->getTrackingPtr() && + !mCamera->isVanityOrPreviewModeEnabled()) + { + mCamera->rotateCamera(-ptr.getRefData().getPosition().rot[0], -ptr.getRefData().getPosition().rot[2], false); + } ptr.getRefData().getBaseNode()->setAttitude(rot); } @@ -321,11 +334,30 @@ namespace MWRender { mPlayerAnimation.reset(new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0)); - //mCamera->setAnimation(mPlayerAnimation); + mCamera->setAnimation(mPlayerAnimation.get()); + mCamera->attachTo(player); //mWater->removeEmitter(ptr); //mWater->addEmitter(ptr); } + void RenderingManager::rebuildPtr(const MWWorld::Ptr &ptr) + { + NpcAnimation *anim = NULL; + if(ptr == mPlayerAnimation->getPtr()) + anim = mPlayerAnimation.get(); + else + anim = dynamic_cast(mObjects->getAnimation(ptr)); + if(anim) + { + anim->rebuild(); + if(mCamera->getTrackingPtr() == ptr) + { + mCamera->attachTo(ptr); + mCamera->setAnimation(anim); + } + } + } + void RenderingManager::updateProjectionMatrix() { double fovy, aspect, zNear, zFar; @@ -370,4 +402,75 @@ namespace MWRender } } + bool RenderingManager::vanityRotateCamera(const float *rot) + { + if(!mCamera->isVanityOrPreviewModeEnabled()) + return false; + + mCamera->rotateCamera(rot[0], rot[2], true); + return true; + } + + void RenderingManager::setCameraDistance(float dist, bool adjust, bool override) + { + if(!mCamera->isVanityOrPreviewModeEnabled() && !mCamera->isFirstPerson()) + { + if(mCamera->isNearest() && dist > 0.f) + mCamera->toggleViewMode(); + else + mCamera->setCameraDistance(-dist / 120.f * 10, adjust, override); + } + else if(mCamera->isFirstPerson() && dist < 0.f) + { + mCamera->toggleViewMode(); + mCamera->setCameraDistance(0.f, false, override); + } + } + + void RenderingManager::resetCamera() + { + mCamera->reset(); + } + + float RenderingManager::getCameraDistance() const + { + return mCamera->getCameraDistance(); + } + + Camera* RenderingManager::getCamera() + { + return mCamera.get(); + } + + void RenderingManager::togglePOV() + { + mCamera->toggleViewMode(); + } + + void RenderingManager::togglePreviewMode(bool enable) + { + mCamera->togglePreviewMode(enable); + } + + bool RenderingManager::toggleVanityMode(bool enable) + { + return mCamera->toggleVanityMode(enable); + } + + void RenderingManager::allowVanityMode(bool allow) + { + mCamera->allowVanityMode(allow); + } + + void RenderingManager::togglePlayerLooking(bool enable) + { + mCamera->togglePlayerLooking(enable); + } + + void RenderingManager::changeVanityModeScale(float factor) + { + if(mCamera->isVanityOrPreviewModeEnabled()) + mCamera->setCameraDistance(-factor/120.f*10, true, true); + } + } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 32e081995e..bb04d04e17 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -41,6 +41,7 @@ namespace MWRender class SkyManager; class NpcAnimation; class Pathgrid; + class Camera; class RenderingManager : public MWRender::RenderingInterface { @@ -66,7 +67,6 @@ namespace MWRender void updatePtr(const MWWorld::Ptr& old, const MWWorld::Ptr& updated); - // TODO rename to setRotation/setPosition/setScale, along with the World equivalents void rotateObject(const MWWorld::Ptr& ptr, const osg::Quat& rot); void moveObject(const MWWorld::Ptr& ptr, const osg::Vec3f& pos); void scaleObject(const MWWorld::Ptr& ptr, const osg::Vec3f& scale); @@ -92,11 +92,28 @@ namespace MWRender Animation* getAnimation(const MWWorld::Ptr& ptr); Animation* getPlayerAnimation(); + void updatePlayerPtr(const MWWorld::Ptr &ptr); + void setupPlayer(const MWWorld::Ptr& player); void renderPlayer(const MWWorld::Ptr& player); + void rebuildPtr(const MWWorld::Ptr& ptr); + void processChangedSettings(const Settings::CategorySettingVector& settings); + // camera stuff + bool vanityRotateCamera(const float *rot); + void setCameraDistance(float dist, bool adjust, bool override); + void resetCamera(); + float getCameraDistance() const; + Camera* getCamera(); + void togglePOV(); + void togglePreviewMode(bool enable); + bool toggleVanityMode(bool enable); + void allowVanityMode(bool allow); + void togglePlayerLooking(bool enable); + void changeVanityModeScale(float factor); + private: void updateProjectionMatrix(); void updateTextureFiltering(); @@ -114,6 +131,7 @@ namespace MWRender std::auto_ptr mEffectManager; std::auto_ptr mPlayerAnimation; osg::ref_ptr mPlayerNode; + std::auto_ptr mCamera; osg::ref_ptr mStateUpdater; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index d087a40d8c..fd63146f26 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -406,7 +406,7 @@ namespace MWWorld world->getPlayer().setCell(cell); MWWorld::Ptr player = world->getPlayerPtr(); - //mRendering.updatePlayerPtr(player); + mRendering.updatePlayerPtr(player); if (adjustPlayerPos) { world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 91484a6ba7..110ed61beb 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -37,6 +37,7 @@ //#include "../mwrender/animation.hpp" #include "../mwrender/renderingmanager.hpp" +#include "../mwrender/camera.hpp" #include "../mwscript/interpretercontext.hpp" #include "../mwscript/globalscripts.hpp" @@ -211,7 +212,7 @@ namespace MWWorld setupPlayer(); renderPlayer(); - //mRendering->resetCamera(); + mRendering->resetCamera(); MWBase::Environment::get().getWindowManager()->updatePlayer(); @@ -531,7 +532,6 @@ namespace MWWorld void World::useDeathCamera() { -#if 0 if(mRendering->getCamera()->isVanityOrPreviewModeEnabled() ) { mRendering->getCamera()->togglePreviewMode(false); @@ -539,7 +539,6 @@ namespace MWWorld } if(mRendering->getCamera()->isFirstPerson()) mRendering->getCamera()->toggleViewMode(true); -#endif } MWWorld::Player& World::getPlayer() @@ -1479,7 +1478,7 @@ namespace MWWorld bool World::toggleCollisionMode() { - return 0;//mPhysics->toggleCollisionMode(); + return mPhysics->toggleCollisionMode(); } bool World::toggleRenderMode (MWRender::RenderMode mode) @@ -1607,7 +1606,16 @@ namespace MWWorld } */ - //mWorldScene->playerMoved(mRendering->getEyePos()); + // Sink the camera while sneaking + bool sneaking = getPlayerPtr().getClass().getCreatureStats(getPlayerPtr()).getStance(MWMechanics::CreatureStats::Stance_Sneak); + bool inair = !isOnGround(getPlayerPtr()); + bool swimming = isSwimming(getPlayerPtr()); + + static const float i1stPersonSneakDelta = getStore().get().find("i1stPersonSneakDelta")->getFloat(); + if(!paused && sneaking && !(swimming || inair)) + mRendering->getCamera()->setSneakOffset(i1stPersonSneakDelta); + else + mRendering->getCamera()->setSneakOffset(0.f); } void World::updateSoundListener() @@ -2091,14 +2099,49 @@ namespace MWWorld */ } + void World::togglePOV() + { + mRendering->togglePOV(); + } + + bool World::isFirstPerson() const + { + return mRendering->getCamera()->isFirstPerson(); + } + + void World::togglePreviewMode(bool enable) + { + mRendering->togglePreviewMode(enable); + } + + bool World::toggleVanityMode(bool enable) + { + return mRendering->toggleVanityMode(enable); + } + + void World::allowVanityMode(bool allow) + { + mRendering->allowVanityMode(allow); + } + + void World::togglePlayerLooking(bool enable) + { + mRendering->togglePlayerLooking(enable); + } + + void World::changeVanityModeScale(float factor) + { + mRendering->changeVanityModeScale(factor); + } + bool World::vanityRotateCamera(float * rot) { - return 0;//mRendering->vanityRotateCamera(rot); + return mRendering->vanityRotateCamera(rot); } void World::setCameraDistance(float dist, bool adjust, bool override_) { - //mRendering->setCameraDistance(dist, adjust, override_); + mRendering->setCameraDistance(dist, adjust, override_); } void World::setupPlayer() @@ -2509,7 +2552,7 @@ namespace MWWorld void World::reattachPlayerCamera() { - //mRendering->rebuildPtr(getPlayerPtr()); + mRendering->rebuildPtr(getPlayerPtr()); } void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf) @@ -2542,7 +2585,7 @@ namespace MWWorld // NpcAnimation::updateParts will already rebuild the animation when it detects change of Npc type. // the following is just for reattaching the camera properly. - //mRendering->rebuildPtr(actor); + mRendering->rebuildPtr(actor); if(actor == getPlayerPtr()) { diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 21ad2d7ef2..67d4f863a7 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -467,33 +467,19 @@ namespace MWWorld virtual bool isWading(const MWWorld::Ptr &object) const; virtual bool isOnGround(const MWWorld::Ptr &ptr) const; - virtual void togglePOV() { - //mRendering->togglePOV(); - } + virtual void togglePOV(); - virtual bool isFirstPerson() const { - return 0;//mRendering->getCamera()->isFirstPerson(); - } + virtual bool isFirstPerson() const; - virtual void togglePreviewMode(bool enable) { - //mRendering->togglePreviewMode(enable); - } + virtual void togglePreviewMode(bool enable); - virtual bool toggleVanityMode(bool enable) { - return 0;//mRendering->toggleVanityMode(enable); - } + virtual bool toggleVanityMode(bool enable); - virtual void allowVanityMode(bool allow) { - //mRendering->allowVanityMode(allow); - } + virtual void allowVanityMode(bool allow); - virtual void togglePlayerLooking(bool enable) { - //mRendering->togglePlayerLooking(enable); - } + virtual void togglePlayerLooking(bool enable); - virtual void changeVanityModeScale(float factor) { - //mRendering->changeVanityModeScale(factor); - } + virtual void changeVanityModeScale(float factor); virtual bool vanityRotateCamera(float * rot); virtual void setCameraDistance(float dist, bool adjust = false, bool override = true);