From fe1a9ac3c575306ec2ef8a5ab866792d228f61e5 Mon Sep 17 00:00:00 2001 From: greye Date: Tue, 14 Aug 2012 02:36:18 +0400 Subject: [PATCH] poor camera with some fixes --- apps/openmw/mwinput/mouselookevent.cpp | 2 +- apps/openmw/mwrender/localmap.cpp | 2 +- apps/openmw/mwrender/player.cpp | 163 +++++++++++----------- apps/openmw/mwrender/player.hpp | 21 ++- apps/openmw/mwrender/renderingmanager.cpp | 19 ++- apps/openmw/mwworld/physicssystem.cpp | 42 +++--- 6 files changed, 129 insertions(+), 120 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; - } - - 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; + if (mPreviewMode == enable) { + return; + } + mPreviewMode = enable; + } + + float Player::getYaw() + { + if (mVanityMode || mPreviewMode) { + return mPreviewCam.yaw; + } + return mMainCam.yaw; + } + + 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::getPitch() + { + if (mVanityMode || 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; + } + 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); }