From ce7bc20fa199b41c00c5e30a9ed0ff301dd81872 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Apr 2013 01:14:58 -0700 Subject: [PATCH] Avoid special-casing player rotation --- apps/openmw/mwrender/player.cpp | 29 +----------- apps/openmw/mwrender/player.hpp | 7 +-- apps/openmw/mwrender/renderingmanager.cpp | 36 ++++----------- apps/openmw/mwrender/renderingmanager.hpp | 7 +-- apps/openmw/mwworld/physicssystem.cpp | 4 +- apps/openmw/mwworld/worldimp.cpp | 55 +++++++++++++++-------- 6 files changed, 52 insertions(+), 86 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 0566cbd5e..6835fd64c 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -40,17 +40,6 @@ namespace MWRender { delete mAnimation; } - - bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) - { - if (mVanity.enabled) - toggleVanityMode(false); - - if (mFreeLook || mVanity.enabled || mPreviewMode) - rotateCamera(rot, adjust); - - return (!mVanity.enabled && !mPreviewMode); - } void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) { @@ -63,16 +52,15 @@ namespace MWRender } Ogre::Quaternion xr(Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X); - Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z); if (!mVanity.enabled && !mPreviewMode) { - mPlayerNode->setOrientation(zr); mCameraNode->setOrientation(xr); } else { + Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z); mCameraNode->setOrientation(zr * xr); } } - std::string Player::getHandle() const + const std::string &Player::getHandle() const { return mPlayerNode->getName(); } @@ -318,19 +306,6 @@ namespace MWRender 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); - } - void Player::togglePlayerLooking(bool enable) { mFreeLook = enable; diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index d9e65d9a6..332db457c 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -57,9 +57,6 @@ 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 rotate(const Ogre::Vector3 &rot, bool adjust); - void rotateCamera(const Ogre::Vector3 &rot, bool adjust); float getYaw(); @@ -68,9 +65,7 @@ namespace MWRender float getPitch(); void setPitch(float angle); - void compensateYaw(float diff); - - std::string getHandle() const; + const std::string &getHandle() const; /// Attach camera to object /// \note there is no protection from attaching the same camera to diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index da51f10c1..1ce1baa39 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -264,37 +264,19 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3 ptr.getRefData().getBaseNode()->setScale(scale); } -bool RenderingManager::rotateObject(const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust) +void RenderingManager::rotateObject(const MWWorld::Ptr &ptr) { - bool isActive = ptr.getRefData().getBaseNode() != 0; - bool isPlayer = isActive && ptr.getRefData().getHandle() == "player"; - bool force = true; + Ogre::Vector3 rot(ptr.getRefData().getPosition().rot); - if (isPlayer) - force = mPlayer->rotate(rot, adjust); + if(ptr.getRefData().getHandle() == mPlayer->getHandle()) + mPlayer->rotateCamera(rot, false); - MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); - if (!isPlayer && isActive) - { - if(adjust) - { - const float *objRot = ptr.getRefData().getPosition().rot; - rot.x += objRot[0]; - rot.y += objRot[1]; - rot.z += objRot[2]; - } + Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); + if(!MWWorld::Class::get(ptr).isActor()) + newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) * + Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) * newo; - Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) * - Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) * - Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); - ptr.getRefData().getBaseNode()->setOrientation(newo); - } - else if(isPlayer) - { - rot.x = -mPlayer->getPitch(); - rot.z = mPlayer->getYaw(); - } - return force; + ptr.getRefData().getBaseNode()->setOrientation(newo); } void diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 0284a6837..6420a5b7e 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -121,11 +121,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position); void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale); - /// Rotates object accordingly to its type - /// \param rot euler angles in radians - /// \param adjust indicates should rotation be set or adjusted - /// \return true if object needs to be rotated physically - bool rotateObject (const MWWorld::Ptr& ptr, Ogre::Vector3 &rot, bool adjust = false); + /// Updates an object's rotation + void rotateObject (const MWWorld::Ptr& ptr); void setWaterHeight(const float height); void toggleWater(); diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 19ee2e517..6a0ff6cae 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -145,7 +145,7 @@ namespace MWWorld // FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why? return position + (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)* Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)* - Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) * + Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) * movement; } @@ -161,7 +161,7 @@ namespace MWWorld { velocity = (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)* Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)* - Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) * + Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) * movement / time; } else diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d3190e0b5..d1e19bf8b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -810,33 +810,50 @@ namespace MWWorld void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust) { - if (mRendering->rotateObject(ptr, rot, adjust)) + const float two_pi = Ogre::Math::TWO_PI; + const float pi = Ogre::Math::PI; + + float *objRot = ptr.getRefData().getPosition().rot; + if(adjust) + { + objRot[0] += rot.x; + objRot[1] += rot.y; + objRot[2] += rot.z; + } + else { - // rotate physically iff renderer confirm so - float *objRot = ptr.getRefData().getPosition().rot; objRot[0] = rot.x; objRot[1] = rot.y; objRot[2] = rot.z; + } - float fullRotateRad=Ogre::Degree(360).valueRadians(); + if(Class::get(ptr).isActor()) + { + /* HACK? Actors shouldn't really be rotating around X (or Y), but + * currently it's done so for rotating the camera, which needs + * clamping. + */ + const float half_pi = Ogre::Math::HALF_PI; - while(objRot[0]>=fullRotateRad) - objRot[0] -= fullRotateRad; - while(objRot[1]>=fullRotateRad) - objRot[1] -= fullRotateRad; - while(objRot[2]>=fullRotateRad) - objRot[2] -= fullRotateRad; + if(objRot[0] < -half_pi) objRot[0] = -half_pi; + else if(objRot[0] > half_pi) objRot[0] = half_pi; + } + else + { + while(objRot[0] < -pi) objRot[0] += two_pi; + while(objRot[0] > pi) objRot[0] -= two_pi; + } - while(objRot[0]<=-fullRotateRad) - objRot[0] += fullRotateRad; - while(objRot[1]<=-fullRotateRad) - objRot[1] += fullRotateRad; - while(objRot[2]<=-fullRotateRad) - objRot[2] += fullRotateRad; + while(objRot[1] < -pi) objRot[1] += two_pi; + while(objRot[1] > pi) objRot[1] -= two_pi; - if (ptr.getRefData().getBaseNode() != 0) { - mPhysics->rotateObject(ptr); - } + while(objRot[2] < -pi) objRot[2] += two_pi; + while(objRot[2] > pi) objRot[2] -= two_pi; + + if(ptr.getRefData().getBaseNode() != 0) + { + mRendering->rotateObject(ptr); + mPhysics->rotateObject(ptr); } }