From 137017b3259bb0eb9c593d39aad868fef3c8adc3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 27 Apr 2013 01:24:36 -0700 Subject: [PATCH 01/12] Don't allow forcing vanity mode --- apps/openmw/mwbase/world.hpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 10 ++- apps/openmw/mwrender/player.cpp | 81 ++++++++--------------- apps/openmw/mwrender/player.hpp | 4 +- apps/openmw/mwrender/renderingmanager.hpp | 4 +- apps/openmw/mwscript/miscextensions.cpp | 6 +- apps/openmw/mwworld/worldimp.hpp | 4 +- 7 files changed, 40 insertions(+), 71 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index a00ae9c3c..fa092203f 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -317,7 +317,7 @@ namespace MWBase virtual void togglePOV() = 0; virtual void togglePreviewMode(bool enable) = 0; - virtual bool toggleVanityMode(bool enable, bool force) = 0; + virtual bool toggleVanityMode(bool enable) = 0; virtual void allowVanityMode(bool allow) = 0; virtual void togglePlayerLooking(bool enable) = 0; virtual void changeVanityModeScale(float factor) = 0; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 6a34161e0..b494c4597 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -719,19 +719,17 @@ namespace MWInput void InputManager::resetIdleTime() { - if (mTimeIdle < 0) { - MWBase::Environment::get().getWorld()->toggleVanityMode(false, false); - } + if (mTimeIdle < 0) + MWBase::Environment::get().getWorld()->toggleVanityMode(false); mTimeIdle = 0.f; } void InputManager::updateIdleTime(float dt) { - if (mTimeIdle >= 0.f) { + if (mTimeIdle >= 0.f) mTimeIdle += dt; - } if (mTimeIdle > 30.f) { - MWBase::Environment::get().getWorld()->toggleVanityMode(true, false); + MWBase::Environment::get().getWorld()->toggleVanityMode(true); mTimeIdle = -1.f; } } diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index fb0602bda..0566cbd5e 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -28,7 +28,6 @@ namespace MWRender { mVanity.enabled = false; mVanity.allowed = true; - mVanity.forced = false; mCameraNode->attachObject(mCamera); mCameraNode->setPosition(0.f, 0.f, mHeight); @@ -44,32 +43,13 @@ namespace MWRender bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) { - if (mVanity.enabled) { + if (mVanity.enabled) toggleVanityMode(false); - } - - Ogre::Vector3 trueRot = rot; - - /// \note rotate player on forced vanity - if (mVanity.forced) { - if (mFreeLook) { - float diff = (adjust) ? rot.z : mMainCam.yaw - rot.z; - - mVanity.enabled = false; - rotateCamera(rot, adjust); - mVanity.enabled = true; - - compensateYaw(diff); - } - trueRot.z = 0.f; - } - if (mFreeLook || mVanity.enabled || mPreviewMode) { - rotateCamera(trueRot, adjust); - } + if (mFreeLook || mVanity.enabled || mPreviewMode) + rotateCamera(rot, adjust); - /// \note if vanity mode is forced by TVM then rotate player - return (!mVanity.enabled && !mPreviewMode) || mVanity.forced; + return (!mVanity.enabled && !mPreviewMode); } void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) @@ -81,14 +61,9 @@ namespace MWRender 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::NEGATIVE_UNIT_Z - ); + + 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); @@ -150,23 +125,19 @@ namespace MWRender void Player::allowVanityMode(bool allow) { - if (!allow && mVanity.enabled && !mVanity.forced) { + if (!allow && mVanity.enabled) toggleVanityMode(false); - } mVanity.allowed = allow; } - bool Player::toggleVanityMode(bool enable, bool force) + bool Player::toggleVanityMode(bool enable) { - if ((mVanity.forced && !force) || - (!mVanity.allowed && (force || enable))) - { + if(!mVanity.allowed && enable) return false; - } else if (mVanity.enabled == enable) { + + if(mVanity.enabled == enable) return true; - } mVanity.enabled = enable; - mVanity.forced = force && enable; mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); @@ -185,6 +156,7 @@ namespace MWRender setLowHeight(!mFirstPersonView); } rot.z = getYaw(); + mCamera->setPosition(0.f, 0.f, offset); rotateCamera(rot, false); @@ -193,12 +165,13 @@ namespace MWRender void Player::togglePreviewMode(bool enable) { - if (mPreviewMode == enable) { + if(mPreviewMode == enable) return; - } + mPreviewMode = enable; mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); + float offset = mCamera->getPosition().z; if (mPreviewMode) { mMainCam.offset = offset; @@ -211,15 +184,15 @@ namespace MWRender setLowHeight(!mFirstPersonView); } + mCamera->setPosition(0.f, 0.f, offset); rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); } float Player::getYaw() { - if (mVanity.enabled || mPreviewMode) { + if(mVanity.enabled || mPreviewMode) return mPreviewCam.yaw; - } return mMainCam.yaw; } @@ -247,16 +220,16 @@ namespace MWRender void Player::setPitch(float angle) { - const float epsilon = 0.000001; + const float epsilon = 0.000001f; float limit = Ogre::Math::HALF_PI - epsilon; - if (mVanity.forced || mPreviewMode) { - limit /= 2; - } - if (angle > limit) { + if(mPreviewMode) + limit /= 2; + + if(angle > limit) angle = limit; - } else if (angle < -limit) { + else if(angle < -limit) angle = -limit; - } + if (mVanity.enabled || mPreviewMode) { mPreviewCam.pitch = angle; } else { @@ -266,9 +239,9 @@ namespace MWRender void Player::setCameraDistance(float dist, bool adjust, bool override) { - if (mFirstPersonView && !mPreviewMode && !mVanity.enabled) { + if(mFirstPersonView && !mPreviewMode && !mVanity.enabled) return; - } + Ogre::Vector3 v(0.f, 0.f, dist); if (adjust) { v += mCamera->getPosition(); diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 9de41823d..d9e65d9a6 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -37,7 +37,7 @@ namespace MWRender bool mFreeLook; struct { - bool enabled, allowed, forced; + bool enabled, allowed; } mVanity; float mHeight, mCameraDistance; @@ -79,7 +79,7 @@ namespace MWRender void toggleViewMode(); - bool toggleVanityMode(bool enable, bool force = false); + bool toggleVanityMode(bool enable); void allowVanityMode(bool allow); void togglePreviewMode(bool enable); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index cece7a95f..0284a6837 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -71,8 +71,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList mPlayer->togglePreviewMode(enable); } - bool toggleVanityMode(bool enable, bool force) { - return mPlayer->toggleVanityMode(enable, force); + bool toggleVanityMode(bool enable) { + return mPlayer->toggleVanityMode(enable); } void allowVanityMode(bool allow) { diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 489f6bd3d..1f172a2da 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -282,10 +282,8 @@ namespace MWScript MWBase::World *world = MWBase::Environment::get().getWorld(); - if (world->toggleVanityMode(sActivate, true)) { - context.report( - (sActivate) ? "Vanity Mode -> On" : "Vanity Mode -> Off" - ); + if (world->toggleVanityMode(sActivate)) { + context.report(sActivate ? "Vanity Mode -> On" : "Vanity Mode -> Off"); sActivate = !sActivate; } else { context.report("Vanity Mode -> No"); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index a51bdc2e6..250ad9ef1 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -347,8 +347,8 @@ namespace MWWorld mRendering->togglePreviewMode(enable); } - virtual bool toggleVanityMode(bool enable, bool force) { - return mRendering->toggleVanityMode(enable, force); + virtual bool toggleVanityMode(bool enable) { + return mRendering->toggleVanityMode(enable); } virtual void allowVanityMode(bool allow) { From ce7bc20fa199b41c00c5e30a9ed0ff301dd81872 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Apr 2013 01:14:58 -0700 Subject: [PATCH 02/12] 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 | 59 +++++++++++++++-------- 6 files changed, 54 insertions(+), 88 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; + + 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[0]<=-fullRotateRad) - objRot[0] += fullRotateRad; - while(objRot[1]<=-fullRotateRad) - objRot[1] += fullRotateRad; - while(objRot[2]<=-fullRotateRad) - objRot[2] += fullRotateRad; - - if (ptr.getRefData().getBaseNode() != 0) { - mPhysics->rotateObject(ptr); - } + while(objRot[1] < -pi) objRot[1] += two_pi; + while(objRot[1] > pi) objRot[1] -= two_pi; + + 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); } } From 4cedf0fbab922fa81da75a689853100a9a5fbc6d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Apr 2013 11:12:55 -0700 Subject: [PATCH 03/12] Avoid colliding with AvoidNodes These are placed under the RootCollisionNode hierarchy, but the shapes they hold aren't collided with. Their exact function is unknown, but seems to be related to lava? Maybe damage avoidance info for the AI. --- components/nif/niffile.cpp | 2 +- components/nif/record.hpp | 1 + components/nifbullet/bulletnifloader.cpp | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index a66bd99db..cb7c2feb0 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -207,7 +207,7 @@ struct RecordFactoryEntry { static const RecordFactoryEntry recordFactories [] = { { "NiNode", &construct , RC_NiNode }, - { "AvoidNode", &construct , RC_NiNode }, + { "AvoidNode", &construct , RC_AvoidNode }, { "NiBSParticleNode", &construct , RC_NiBSParticleNode }, { "NiBSAnimationNode", &construct , RC_NiBSAnimationNode }, { "NiBillboardNode", &construct , RC_NiNode }, diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 3f852ed83..87e342dca 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -36,6 +36,7 @@ enum RecordType { RC_MISSING = 0, RC_NiNode, + RC_AvoidNode, RC_NiTriShape, RC_NiRotatingParticles, RC_NiAutoNormalParticles, diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index a3eff95c3..a1e2cd8d1 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -185,6 +185,10 @@ void ManualBulletShapeLoader::handleNode(btTriangleMesh* mesh, const Nif::Node * else isCollisionNode = isCollisionNode && (node->recType != Nif::RC_RootCollisionNode); + // Don't collide with AvoidNode shapes + if(node->recType == Nif::RC_AvoidNode) + flags |= 0x800; + // Marker objects /// \todo don't do this in the editor std::string nodename = node->name; From ba3a67f84b4594b2d2b23662e4e710478bce4327 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Apr 2013 23:44:44 -0700 Subject: [PATCH 04/12] Don't store the player base node in MWRender::Player --- apps/openmw/mwrender/player.cpp | 37 +++++++++++++---------- apps/openmw/mwrender/player.hpp | 12 +++----- apps/openmw/mwrender/renderingmanager.cpp | 3 +- apps/openmw/mwrender/renderingmanager.hpp | 2 +- apps/openmw/mwworld/refdata.cpp | 9 ++++-- apps/openmw/mwworld/refdata.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 14 +++++---- 7 files changed, 44 insertions(+), 35 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 6835fd64c..153d4af49 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/windowmanager.hpp" @@ -16,8 +17,7 @@ namespace MWRender { Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) : mCamera(camera), - mPlayerNode(node), - mCameraNode(mPlayerNode->createChildSceneNode()), + mCameraNode(NULL), mFirstPersonView(true), mPreviewMode(false), mFreeLook(true), @@ -29,9 +29,6 @@ namespace MWRender mVanity.enabled = false; mVanity.allowed = true; - mCameraNode->attachObject(mCamera); - mCameraNode->setPosition(0.f, 0.f, mHeight); - mPreviewCam.yaw = 0.f; mPreviewCam.offset = 400.f; } @@ -62,12 +59,22 @@ namespace MWRender const std::string &Player::getHandle() const { - return mPlayerNode->getName(); + return mTrackingPtr.getRefData().getHandle(); } void Player::attachTo(const MWWorld::Ptr &ptr) { - ptr.getRefData().setBaseNode(mPlayerNode); + mTrackingPtr = ptr; + Ogre::SceneNode *node = mTrackingPtr.getRefData().getBaseNode()->createChildSceneNode(Ogre::Vector3(0.0f, 0.0f, mHeight)); + if(mCameraNode) + { + node->setOrientation(mCameraNode->getOrientation()); + node->setPosition(mCameraNode->getPosition()); + node->setScale(mCameraNode->getScale()); + mCameraNode->getCreator()->destroySceneNode(mCameraNode); + } + mCameraNode = node; + mCameraNode->attachObject(mCamera); } void Player::updateListener() @@ -84,13 +91,11 @@ namespace MWRender updateListener(); // only show the crosshair in game mode and in first person mode. - MWBase::Environment::get().getWindowManager ()->showCrosshair - (!MWBase::Environment::get().getWindowManager ()->isGuiMode () && (mFirstPersonView && !mVanity.enabled && !mPreviewMode)); + MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager(); + wm->showCrosshair(!wm->isGuiMode() && (mFirstPersonView && !mVanity.enabled && !mPreviewMode)); - if (mFirstPersonView && !mVanity.enabled) { - return; - } - if (mVanity.enabled) { + if(mVanity.enabled) + { Ogre::Vector3 rot(0.f, 0.f, 0.f); rot.z = Ogre::Degree(3.f * duration).valueRadians(); rotateCamera(rot, true); @@ -283,21 +288,21 @@ namespace MWRender float Player::getHeight() { - return mHeight * mPlayerNode->getScale().z; + return mHeight * mTrackingPtr.getRefData().getBaseNode()->getScale().z; } bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera) { mCamera->getParentSceneNode ()->needUpdate(true); camera = mCamera->getRealPosition(); - player = mPlayerNode->getPosition(); + player = mTrackingPtr.getRefData().getBaseNode()->getPosition(); return mFirstPersonView && !mVanity.enabled && !mPreviewMode; } Ogre::Vector3 Player::getPosition() { - return mPlayerNode->getPosition(); + return mTrackingPtr.getRefData().getBaseNode()->getPosition(); } void Player::getSightAngles(float &pitch, float &yaw) diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 332db457c..3c645230b 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -3,6 +3,8 @@ #include +#include "../mwworld/ptr.hpp" + namespace Ogre { class Vector3; @@ -10,14 +12,10 @@ namespace Ogre class SceneNode; } -namespace MWWorld -{ - class Ptr; -} - namespace MWRender { class NpcAnimation; + /// \brief Player character rendering and camera control class Player { @@ -25,9 +23,9 @@ namespace MWRender float pitch, yaw, offset; }; - Ogre::Camera *mCamera; + MWWorld::Ptr mTrackingPtr; - Ogre::SceneNode *mPlayerNode; + Ogre::Camera *mCamera; Ogre::SceneNode *mCameraNode; NpcAnimation *mAnimation; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 1ce1baa39..252e29666 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -858,8 +858,9 @@ void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned i } } -void RenderingManager::attachCameraTo(const MWWorld::Ptr &ptr) +void RenderingManager::setupPlayer(const MWWorld::Ptr &ptr) { + ptr.getRefData().setBaseNode(mRendering.getScene()->getSceneNode("player")); mPlayer->attachTo(ptr); } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 6420a5b7e..20ec0d9ae 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -92,7 +92,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw); - void attachCameraTo(const MWWorld::Ptr &ptr); + void setupPlayer(const MWWorld::Ptr &ptr); void renderPlayer(const MWWorld::Ptr &ptr); SkyManager* getSkyManager(); diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index db565c451..c1a3ae785 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -81,10 +81,13 @@ namespace MWWorld {} } - std::string RefData::getHandle() + const std::string &RefData::getHandle() { - if (!mBaseNode) - return ""; + if(!mBaseNode) + { + static const std::string empty; + return empty; + } return mBaseNode->getName(); } diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 77ceb3721..642f5412c 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -60,7 +60,7 @@ namespace MWWorld RefData& operator= (const RefData& refData); /// Return OGRE handle (may be empty). - std::string getHandle(); + const std::string &getHandle(); /// Return OGRE base node (can be a null pointer). Ogre::SceneNode* getBaseNode(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a3fda913d..f3909a1da 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1493,13 +1493,15 @@ namespace MWWorld void World::setupPlayer(bool newGame) { - const ESM::NPC* player = mStore.get().find ("player"); - mPlayer = new MWWorld::Player (player, *this); - mRendering->attachCameraTo(mPlayer->getPlayer()); - if (newGame) + const ESM::NPC *player = mStore.get().find("player"); + mPlayer = new MWWorld::Player(player, *this); + + Ptr ptr = mPlayer->getPlayer(); + mRendering->setupPlayer(ptr); + if(newGame) { - MWWorld::Class::get(mPlayer->getPlayer()).getContainerStore(mPlayer->getPlayer()).fill(player->mInventory, "", mStore); - MWWorld::Class::get(mPlayer->getPlayer()).getInventoryStore(mPlayer->getPlayer()).autoEquip (mPlayer->getPlayer()); + MWWorld::Class::get(ptr).getContainerStore(ptr).fill(player->mInventory, "", mStore); + MWWorld::Class::get(ptr).getInventoryStore(ptr).autoEquip(ptr); } } From bb8277920b8c5c5c2f5264e3372e183a846cab7d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 03:31:46 -0700 Subject: [PATCH 05/12] Manage the player's NpcAnimation object in the RenderingManager It may be more appropriate to manage it in MWRender::Actors with the other Animation-based objects, but that will need some (minor) interface changes. --- apps/openmw/mwrender/player.cpp | 13 ++++---- apps/openmw/mwrender/player.hpp | 5 +-- apps/openmw/mwrender/renderingmanager.cpp | 38 ++++++++++++++--------- apps/openmw/mwrender/renderingmanager.hpp | 2 ++ 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 153d4af49..7eb7156ab 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -15,7 +15,7 @@ namespace MWRender { - Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) + Player::Player (Ogre::Camera *camera) : mCamera(camera), mCameraNode(NULL), mFirstPersonView(true), @@ -35,7 +35,6 @@ namespace MWRender Player::~Player() { - delete mAnimation; } void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) @@ -273,11 +272,13 @@ namespace MWRender void Player::setAnimation(NpcAnimation *anim) { - anim->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? - NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); - - delete mAnimation; + // If we're switching to a new NpcAnimation, ensure the old one is + // using a normal view mode + if(mAnimation && mAnimation != anim) + mAnimation->setViewMode(NpcAnimation::VM_Normal); mAnimation = anim; + mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? + NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); } void Player::setHeight(float height) diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 3c645230b..8675e0760 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -49,8 +49,7 @@ namespace MWRender void setLowHeight(bool low = true); public: - - Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); + Player(Ogre::Camera *camera); ~Player(); /// Set where the player is looking at. Uses Morrowind (euler) angles @@ -89,8 +88,6 @@ namespace MWRender void setCameraDistance(); void setAnimation(NpcAnimation *anim); - NpcAnimation *getAnimation() const - { return mAnimation; } void setHeight(float height); float getHeight(); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 252e29666..2e168caed 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -53,8 +53,9 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback) : mRendering(_rend) , mFallback(fallback) - , mObjects(mRendering,mFallback) + , mObjects(mRendering, mFallback) , mActors(mRendering, this) + , mPlayerAnimation(NULL) , mAmbientMode(0) , mSunEnabled(0) , mPhysicsEngine(engine) @@ -148,14 +149,13 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const applyCompositors(); - SceneNode *rt = mRendering.getScene()->getRootSceneNode(); - mRootNode = rt; + mRootNode = mRendering.getScene()->getRootSceneNode(); + mRootNode->createChildSceneNode("player"); mObjects.setRootNode(mRootNode); mActors.setRootNode(mRootNode); - Ogre::SceneNode *playerNode = mRootNode->createChildSceneNode ("player"); - mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); + mPlayer = new MWRender::Player(mRendering.getCamera()); mShadows = new Shadows(&mRendering); @@ -183,6 +183,7 @@ RenderingManager::~RenderingManager () mRendering.getWindow()->removeListener(this); mRendering.removeWindowEventListener(this); + delete mPlayerAnimation; delete mPlayer; delete mSkyManager; delete mDebugging; @@ -866,14 +867,23 @@ void RenderingManager::setupPlayer(const MWWorld::Ptr &ptr) void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) { - MWRender::NpcAnimation *anim = - new MWRender::NpcAnimation( - ptr, ptr.getRefData ().getBaseNode (), - MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors - ); - mPlayer->setAnimation(anim); - mWater->removeEmitter (ptr); - mWater->addEmitter (ptr); + if(!mPlayerAnimation) + { + mPlayerAnimation = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), + MWWorld::Class::get(ptr).getInventoryStore(ptr), + RV_Actors); + } + else + { + // Reconstruct the NpcAnimation in-place + mPlayerAnimation->~NpcAnimation(); + new(mPlayerAnimation) NpcAnimation(ptr, ptr.getRefData().getBaseNode(), + MWWorld::Class::get(ptr).getInventoryStore(ptr), + RV_Actors); + } + mPlayer->setAnimation(mPlayerAnimation); + mWater->removeEmitter(ptr); + mWater->addEmitter(ptr); // apply race height MWBase::Environment::get().getWorld()->scaleObject(ptr, 1.f); } @@ -914,7 +924,7 @@ Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr) { Animation *anim = mActors.getAnimation(ptr); if(!anim && ptr.getRefData().getHandle() == "player") - anim = mPlayer->getAnimation(); + anim = mPlayerAnimation; return anim; } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 20ec0d9ae..c7e27a405 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -238,6 +238,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList MWRender::Objects mObjects; MWRender::Actors mActors; + MWRender::NpcAnimation *mPlayerAnimation; + // 0 normal, 1 more bright, 2 max int mAmbientMode; From dbba126344b1483514e1585202405aab4e0c5fa3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 04:40:28 -0700 Subject: [PATCH 06/12] Use a method to check if the view should be first person --- apps/openmw/mwrender/player.cpp | 16 ++++++++-------- apps/openmw/mwrender/player.hpp | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 7eb7156ab..640f8bd66 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -104,8 +104,8 @@ namespace MWRender void Player::toggleViewMode() { mFirstPersonView = !mFirstPersonView; - mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? - NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); + mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson : + NpcAnimation::VM_Normal); if (mFirstPersonView) { mCamera->setPosition(0.f, 0.f, 0.f); setLowHeight(false); @@ -131,8 +131,8 @@ namespace MWRender return true; mVanity.enabled = enable; - mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? - NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); + mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson : + NpcAnimation::VM_Normal); float offset = mPreviewCam.offset; Ogre::Vector3 rot(0.f, 0.f, 0.f); @@ -161,8 +161,8 @@ namespace MWRender return; mPreviewMode = enable; - mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? - NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); + mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson : + NpcAnimation::VM_Normal); float offset = mCamera->getPosition().z; if (mPreviewMode) { @@ -277,8 +277,8 @@ namespace MWRender if(mAnimation && mAnimation != anim) mAnimation->setViewMode(NpcAnimation::VM_Normal); mAnimation = anim; - mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? - NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); + mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson : + NpcAnimation::VM_Normal); } void Player::setHeight(float height) diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 8675e0760..5ded521d4 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -76,6 +76,9 @@ namespace MWRender void togglePreviewMode(bool enable); + bool isFirstPerson() const + { return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); } + void update(float duration); /// Set camera distance for current mode. Don't work on 1st person view. From d17e1e83d585548d6ff75f0b8aa362bf289273c0 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 05:50:40 -0700 Subject: [PATCH 07/12] Rename MWRender's Player to Camera --- apps/openmw/CMakeLists.txt | 2 +- .../mwrender/{player.cpp => camera.cpp} | 54 ++++++++-------- .../mwrender/{player.hpp => camera.hpp} | 16 +++-- apps/openmw/mwrender/debugging.cpp | 1 - apps/openmw/mwrender/debugging.hpp | 2 - apps/openmw/mwrender/renderingmanager.cpp | 62 ++++++++----------- apps/openmw/mwrender/renderingmanager.hpp | 60 ++++++++---------- apps/openmw/mwrender/sky.cpp | 2 +- apps/openmw/mwworld/physicssystem.cpp | 30 +++++---- apps/openmw/mwworld/physicssystem.hpp | 4 +- apps/openmw/mwworld/worldimp.cpp | 5 +- 11 files changed, 108 insertions(+), 130 deletions(-) rename apps/openmw/mwrender/{player.cpp => camera.cpp} (87%) rename apps/openmw/mwrender/{player.hpp => camera.hpp} (87%) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 08033f822..b5d4badf2 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -14,7 +14,7 @@ set(GAME_HEADER source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender - renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation + renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows compositors characterpreview externalrendering globalmap videoplayer ripplesimulation refraction ) diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/camera.cpp similarity index 87% rename from apps/openmw/mwrender/player.cpp rename to apps/openmw/mwrender/camera.cpp index 640f8bd66..b4fd6a543 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -1,4 +1,4 @@ -#include "player.hpp" +#include "camera.hpp" #include #include @@ -15,7 +15,7 @@ namespace MWRender { - Player::Player (Ogre::Camera *camera) + Camera::Camera (Ogre::Camera *camera) : mCamera(camera), mCameraNode(NULL), mFirstPersonView(true), @@ -33,11 +33,11 @@ namespace MWRender mPreviewCam.offset = 400.f; } - Player::~Player() + Camera::~Camera() { } - void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) + void Camera::rotateCamera(const Ogre::Vector3 &rot, bool adjust) { if (adjust) { setYaw(getYaw() + rot.z); @@ -56,12 +56,12 @@ namespace MWRender } } - const std::string &Player::getHandle() const + const std::string &Camera::getHandle() const { return mTrackingPtr.getRefData().getHandle(); } - void Player::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)); @@ -76,7 +76,7 @@ namespace MWRender mCameraNode->attachObject(mCamera); } - void Player::updateListener() + void Camera::updateListener() { Ogre::Vector3 pos = mCamera->getRealPosition(); Ogre::Vector3 dir = mCamera->getRealDirection(); @@ -85,7 +85,7 @@ namespace MWRender MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up); } - void Player::update(float duration) + void Camera::update(float duration) { updateListener(); @@ -101,7 +101,7 @@ namespace MWRender } } - void Player::toggleViewMode() + void Camera::toggleViewMode() { mFirstPersonView = !mFirstPersonView; mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson : @@ -115,14 +115,14 @@ namespace MWRender } } - void Player::allowVanityMode(bool allow) + void Camera::allowVanityMode(bool allow) { if (!allow && mVanity.enabled) toggleVanityMode(false); mVanity.allowed = allow; } - bool Player::toggleVanityMode(bool enable) + bool Camera::toggleVanityMode(bool enable) { if(!mVanity.allowed && enable) return false; @@ -155,7 +155,7 @@ namespace MWRender return true; } - void Player::togglePreviewMode(bool enable) + void Camera::togglePreviewMode(bool enable) { if(mPreviewMode == enable) return; @@ -181,14 +181,14 @@ namespace MWRender rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); } - float Player::getYaw() + float Camera::getYaw() { if(mVanity.enabled || mPreviewMode) return mPreviewCam.yaw; return mMainCam.yaw; } - void Player::setYaw(float angle) + void Camera::setYaw(float angle) { if (angle > Ogre::Math::PI) { angle -= Ogre::Math::TWO_PI; @@ -202,7 +202,7 @@ namespace MWRender } } - float Player::getPitch() + float Camera::getPitch() { if (mVanity.enabled || mPreviewMode) { return mPreviewCam.pitch; @@ -210,7 +210,7 @@ namespace MWRender return mMainCam.pitch; } - void Player::setPitch(float angle) + void Camera::setPitch(float angle) { const float epsilon = 0.000001f; float limit = Ogre::Math::HALF_PI - epsilon; @@ -229,7 +229,7 @@ namespace MWRender } } - void Player::setCameraDistance(float dist, bool adjust, bool override) + void Camera::setCameraDistance(float dist, bool adjust, bool override) { if(mFirstPersonView && !mPreviewMode && !mVanity.enabled) return; @@ -258,7 +258,7 @@ namespace MWRender } } - void Player::setCameraDistance() + void Camera::setCameraDistance() { if (mDistanceAdjusted) { if (mVanity.enabled || mPreviewMode) { @@ -270,7 +270,7 @@ namespace MWRender mDistanceAdjusted = false; } - void Player::setAnimation(NpcAnimation *anim) + void Camera::setAnimation(NpcAnimation *anim) { // If we're switching to a new NpcAnimation, ensure the old one is // using a normal view mode @@ -281,18 +281,18 @@ namespace MWRender NpcAnimation::VM_Normal); } - void Player::setHeight(float height) + void Camera::setHeight(float height) { mHeight = height; mCameraNode->setPosition(0.f, 0.f, mHeight); } - float Player::getHeight() + float Camera::getHeight() { return mHeight * mTrackingPtr.getRefData().getBaseNode()->getScale().z; } - bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera) + bool Camera::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera) { mCamera->getParentSceneNode ()->needUpdate(true); camera = mCamera->getRealPosition(); @@ -301,23 +301,23 @@ namespace MWRender return mFirstPersonView && !mVanity.enabled && !mPreviewMode; } - Ogre::Vector3 Player::getPosition() + Ogre::Vector3 Camera::getPosition() { return mTrackingPtr.getRefData().getBaseNode()->getPosition(); } - void Player::getSightAngles(float &pitch, float &yaw) + void Camera::getSightAngles(float &pitch, float &yaw) { pitch = mMainCam.pitch; yaw = mMainCam.yaw; } - void Player::togglePlayerLooking(bool enable) + void Camera::togglePlayerLooking(bool enable) { mFreeLook = enable; } - void Player::setLowHeight(bool low) + void Camera::setLowHeight(bool low) { if (low) { mCameraNode->setPosition(0.f, 0.f, mHeight * 0.85); @@ -326,7 +326,7 @@ namespace MWRender } } - bool Player::isVanityOrPreviewModeEnabled() + bool Camera::isVanityOrPreviewModeEnabled() { return mPreviewMode || mVanity.enabled; } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/camera.hpp similarity index 87% rename from apps/openmw/mwrender/player.hpp rename to apps/openmw/mwrender/camera.hpp index 5ded521d4..7bbdd303d 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -1,5 +1,5 @@ -#ifndef GAME_MWRENDER_PLAYER_H -#define GAME_MWRENDER_PLAYER_H +#ifndef GAME_MWRENDER_CAMERA_H +#define GAME_MWRENDER_CAMERA_H #include @@ -16,8 +16,8 @@ namespace MWRender { class NpcAnimation; - /// \brief Player character rendering and camera control - class Player + /// \brief Camera control + class Camera { struct CamData { float pitch, yaw, offset; @@ -49,10 +49,10 @@ namespace MWRender void setLowHeight(bool low = true); public: - Player(Ogre::Camera *camera); - ~Player(); + Camera(Ogre::Camera *camera); + ~Camera(); - /// Set where the player is looking at. Uses Morrowind (euler) angles + /// 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); @@ -65,8 +65,6 @@ namespace MWRender const std::string &getHandle() const; /// Attach camera to object - /// \note there is no protection from attaching the same camera to - /// several different objects void attachTo(const MWWorld::Ptr &); void toggleViewMode(); diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 54f288bff..b318c2d56 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -20,7 +20,6 @@ #include "../mwworld/ptr.hpp" -#include "player.hpp" #include "renderconst.hpp" using namespace Ogre; diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index 6a4eef58f..4a574017c 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -39,8 +39,6 @@ namespace MWWorld namespace MWRender { - class Player; - class Debugging { OEngine::Physic::PhysicEngine* mEngine; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 2e168caed..7180f6efd 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -49,8 +49,9 @@ using namespace Ogre; namespace MWRender { -RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, - const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback) +RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, + const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine, + MWWorld::Fallback* fallback) : mRendering(_rend) , mFallback(fallback) , mObjects(mRendering, mFallback) @@ -155,7 +156,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mObjects.setRootNode(mRootNode); mActors.setRootNode(mRootNode); - mPlayer = new MWRender::Player(mRendering.getCamera()); + mCamera = new MWRender::Camera(mRendering.getCamera()); mShadows = new Shadows(&mRendering); @@ -184,7 +185,7 @@ RenderingManager::~RenderingManager () mRendering.removeWindowEventListener(this); delete mPlayerAnimation; - delete mPlayer; + delete mCamera; delete mSkyManager; delete mDebugging; delete mShadows; @@ -269,8 +270,8 @@ void RenderingManager::rotateObject(const MWWorld::Ptr &ptr) { Ogre::Vector3 rot(ptr.getRefData().getPosition().rot); - if(ptr.getRefData().getHandle() == mPlayer->getHandle()) - mPlayer->rotateCamera(rot, false); + if(ptr.getRefData().getHandle() == mCamera->getHandle()) + mCamera->rotateCamera(rot, false); Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); if(!MWWorld::Class::get(ptr).isActor()) @@ -300,7 +301,7 @@ void RenderingManager::update (float duration, bool paused) { MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::Ptr player = world->getPlayer().getPlayer(); int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude; mRendering.getFader()->setFactor(1.f-(blind / 100.f)); @@ -313,16 +314,16 @@ void RenderingManager::update (float duration, bool paused) Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]); Ogre::Vector3 orig, dest; - mPlayer->setCameraDistance(); - if (!mPlayer->getPosition(orig, dest)) { - orig.z += mPlayer->getHeight() * mRootNode->getScale().z; + mCamera->setCameraDistance(); + if(!mCamera->getPosition(orig, dest)) + { + orig.z += mCamera->getHeight() * mRootNode->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); + std::pair test = mPhysicsEngine->rayTest(btOrig, btDest); if (!test.first.empty()) { - mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false); + mCamera->setCameraDistance(test.second * orig.distance(dest), false, false); } } @@ -336,14 +337,12 @@ void RenderingManager::update (float duration, bool paused) Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); - applyFog(world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam)); + applyFog(world->isUnderwater(player.getCell(), cam)); if(paused) - { return; - } - mPlayer->update(duration); + mCamera->update(duration); mActors.update (duration); mObjects.update (duration); @@ -354,18 +353,11 @@ void RenderingManager::update (float duration, bool paused) mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); Ogre::SceneNode *node = data.getBaseNode(); - //Ogre::Quaternion orient = - //node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); - Ogre::Quaternion orient = -node->_getDerivedOrientation(); + Ogre::Quaternion orient = node->_getDerivedOrientation(); mLocalMap->updatePlayer(playerPos, orient); - mWater->updateUnderwater( - world->isUnderwater( - world->getPlayer().getPlayer().getCell(), - cam) - ); + mWater->updateUnderwater(world->isUnderwater(player.getCell(), cam)); mWater->update(duration, playerPos); } @@ -862,7 +854,7 @@ void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned i void RenderingManager::setupPlayer(const MWWorld::Ptr &ptr) { ptr.getRefData().setBaseNode(mRendering.getScene()->getSceneNode("player")); - mPlayer->attachTo(ptr); + mCamera->attachTo(ptr); } void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) @@ -881,27 +873,27 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors); } - mPlayer->setAnimation(mPlayerAnimation); + mCamera->setAnimation(mPlayerAnimation); mWater->removeEmitter(ptr); mWater->addEmitter(ptr); // apply race height MWBase::Environment::get().getWorld()->scaleObject(ptr, 1.f); } -void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) +void RenderingManager::getCameraData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) { - eyepos = mPlayer->getPosition(); - eyepos.z += mPlayer->getHeight(); - mPlayer->getSightAngles(pitch, yaw); + eyepos = mCamera->getPosition(); + eyepos.z += mCamera->getHeight(); + mCamera->getSightAngles(pitch, yaw); } -bool RenderingManager::vanityRotateCamera(float* rot) +bool RenderingManager::vanityRotateCamera(const float *rot) { - if(!mPlayer->isVanityOrPreviewModeEnabled()) + if(!mCamera->isVanityOrPreviewModeEnabled()) return false; Ogre::Vector3 vRot(rot); - mPlayer->rotateCamera(vRot, true); + mCamera->rotateCamera(vRot, true); return true; } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index c7e27a405..6a35bfb6d 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -17,7 +17,7 @@ #include "objects.hpp" #include "actors.hpp" -#include "player.hpp" +#include "camera.hpp" #include "occlusionquery.hpp" namespace Ogre @@ -50,47 +50,42 @@ namespace MWRender class VideoPlayer; class Animation; -class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener { - - private: - - +class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener +{ +private: virtual MWRender::Objects& getObjects(); virtual MWRender::Actors& getActors(); - public: +public: RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, - const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback); + const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine, + MWWorld::Fallback* fallback); virtual ~RenderingManager(); - void togglePOV() { - mPlayer->toggleViewMode(); - } + void togglePOV() + { mCamera->toggleViewMode(); } - void togglePreviewMode(bool enable) { - mPlayer->togglePreviewMode(enable); - } + void togglePreviewMode(bool enable) + { mCamera->togglePreviewMode(enable); } - bool toggleVanityMode(bool enable) { - return mPlayer->toggleVanityMode(enable); - } + bool toggleVanityMode(bool enable) + { return mCamera->toggleVanityMode(enable); } - void allowVanityMode(bool allow) { - mPlayer->allowVanityMode(allow); - } + void allowVanityMode(bool allow) + { mCamera->allowVanityMode(allow); } - void togglePlayerLooking(bool enable) { - mPlayer->togglePlayerLooking(enable); - } + void togglePlayerLooking(bool enable) + { mCamera->togglePlayerLooking(enable); } - void changeVanityModeScale(float factor) { - if (mPlayer->isVanityOrPreviewModeEnabled()) - mPlayer->setCameraDistance(-factor/120.f*10, true, true); + void changeVanityModeScale(float factor) + { + if(mCamera->isVanityOrPreviewModeEnabled()) + mCamera->setCameraDistance(-factor/120.f*10, true, true); } - bool vanityRotateCamera(float* rot); + bool vanityRotateCamera(const float *rot); - void getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw); + void getCameraData(Ogre::Vector3 &eyepos, float &pitch, float &yaw); void setupPlayer(const MWWorld::Ptr &ptr); void renderPlayer(const MWWorld::Ptr &ptr); @@ -204,12 +199,11 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void stopVideo(); void frameStarted(float dt); - protected: - virtual void windowResized(Ogre::RenderWindow* rw); +protected: + virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw); - private: - +private: sh::Factory* mFactory; void setAmbientMode(); @@ -254,7 +248,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList OEngine::Physic::PhysicEngine* mPhysicsEngine; - MWRender::Player *mPlayer; + MWRender::Camera *mCamera; MWRender::Debugging *mDebugging; diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 7f3abce70..516b48dde 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -205,7 +205,7 @@ unsigned int Moon::getPhaseInt() const return 0; } -SkyManager::SkyManager (SceneNode* root, Camera* pCamera) +SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera) : mHour(0.0f) , mDay(0) , mMonth(0) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 18db2dca8..ce32b79e5 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -260,14 +260,13 @@ namespace MWWorld std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world, float queryDistance) { btVector3 dir(0, 1, 0); - dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); - dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw); + dir = dir.rotate(btVector3(1, 0, 0), mCameraData.pitch); + dir = dir.rotate(btVector3(0, 0, 1), mCameraData.yaw); dir.setX(-dir.x()); - btVector3 origin( - mPlayerData.eyepos.x, - mPlayerData.eyepos.y, - mPlayerData.eyepos.z); + btVector3 origin(mCameraData.eyepos.x, + mCameraData.eyepos.y, + mCameraData.eyepos.z); origin += dir * 5; btVector3 dest = origin + dir * queryDistance; @@ -280,14 +279,13 @@ namespace MWWorld std::vector < std::pair > PhysicsSystem::getFacedHandles (float queryDistance) { btVector3 dir(0, 1, 0); - dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); - dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw); + dir = dir.rotate(btVector3(1, 0, 0), mCameraData.pitch); + dir = dir.rotate(btVector3(0, 0, 1), mCameraData.yaw); dir.setX(-dir.x()); - btVector3 origin( - mPlayerData.eyepos.x, - mPlayerData.eyepos.y, - mPlayerData.eyepos.z); + btVector3 origin(mCameraData.eyepos.x, + mCameraData.eyepos.y, + mCameraData.eyepos.z); origin += dir * 5; btVector3 dest = origin + dir * queryDistance; @@ -552,10 +550,10 @@ namespace MWWorld return true; } - void PhysicsSystem::updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw) + void PhysicsSystem::updateCameraData(const Ogre::Vector3 &eyepos, float pitch, float yaw) { - mPlayerData.eyepos = eyepos; - mPlayerData.pitch = pitch; - mPlayerData.yaw = yaw; + mCameraData.eyepos = eyepos; + mCameraData.pitch = pitch; + mCameraData.yaw = yaw; } } diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index 48214029e..3322c38a6 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -77,13 +77,13 @@ namespace MWWorld bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max); - void updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw); + void updateCameraData(const Ogre::Vector3 &eyepos, float pitch, float yaw); private: struct { Ogre::Vector3 eyepos; float pitch, yaw; - } mPlayerData; + } mCameraData; OEngine::Render::OgreRenderer &mRender; OEngine::Physic::PhysicEngine* mEngine; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3909a1da..855fdfe09 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -16,7 +16,6 @@ #include "../mwmechanics/movement.hpp" #include "../mwrender/sky.hpp" -#include "../mwrender/player.hpp" #include "../mwclass/door.hpp" @@ -1146,8 +1145,8 @@ namespace MWWorld float pitch, yaw; Ogre::Vector3 eyepos; - mRendering->getPlayerData(eyepos, pitch, yaw); - mPhysics->updatePlayerData(eyepos, pitch, yaw); + mRendering->getCameraData(eyepos, pitch, yaw); + mPhysics->updateCameraData(eyepos, pitch, yaw); performUpdateSceneQueries (); From a15758ac85e24dec9b872ad20a6d52d4eb7d9aa9 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 08:48:45 -0700 Subject: [PATCH 08/12] Fix preview and vanity cameras --- apps/openmw/mwrender/renderingmanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 7180f6efd..60a9b22a3 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -270,7 +270,8 @@ void RenderingManager::rotateObject(const MWWorld::Ptr &ptr) { Ogre::Vector3 rot(ptr.getRefData().getPosition().rot); - if(ptr.getRefData().getHandle() == mCamera->getHandle()) + if(ptr.getRefData().getHandle() == mCamera->getHandle() && + !mCamera->isVanityOrPreviewModeEnabled()) mCamera->rotateCamera(rot, false); Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); From 0cf531ba12979bc649d813212a0ea0f926054b3c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 09:53:36 -0700 Subject: [PATCH 09/12] Make sure to update parts when the weapon changes --- apps/openmw/mwrender/npcanimation.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 1d1ebf6b6..88f45daff 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -178,7 +178,8 @@ void NpcAnimation::updateParts(bool forceupdate) { &NpcAnimation::mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet, 0 }, { &NpcAnimation::mShirt, MWWorld::InventoryStore::Slot_Shirt, 0 }, { &NpcAnimation::mPants, MWWorld::InventoryStore::Slot_Pants, 0 }, - { &NpcAnimation::mShield, MWWorld::InventoryStore::Slot_CarriedLeft, 0 } + { &NpcAnimation::mShield, MWWorld::InventoryStore::Slot_CarriedLeft, 0 }, + { &NpcAnimation::mWeapon, MWWorld::InventoryStore::Slot_CarriedRight, 0 } }; static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]); @@ -239,7 +240,7 @@ void NpcAnimation::updateParts(bool forceupdate) ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron }; size_t parts_size = sizeof(parts)/sizeof(parts[0]); - for(int p = 0;p < static_cast (parts_size);++p) + for(size_t p = 0;p < parts_size;++p) reserveIndividualPart(parts[p], slotlist[i].mSlot, prio); } else if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Skirt) @@ -260,6 +261,8 @@ void NpcAnimation::updateParts(bool forceupdate) if(mViewMode == VM_HeadOnly) return; + showWeapons(mShowWeapons); + std::map bodypartMap; bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck; bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest; From 063322b081855969957a738a079574bd187b94e8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 10:12:50 -0700 Subject: [PATCH 10/12] Declare some variables closer to where they're used --- apps/openmw/mwrender/npcanimation.cpp | 60 +++++++++++++-------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 88f45daff..c616a1ff5 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -263,30 +263,6 @@ void NpcAnimation::updateParts(bool forceupdate) showWeapons(mShowWeapons); - std::map bodypartMap; - bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck; - bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest; - bodypartMap[ESM::PRT_Groin] = ESM::BodyPart::MP_Groin; - bodypartMap[ESM::PRT_RHand] = ESM::BodyPart::MP_Hand; - bodypartMap[ESM::PRT_LHand] = ESM::BodyPart::MP_Hand; - bodypartMap[ESM::PRT_RWrist] = ESM::BodyPart::MP_Wrist; - bodypartMap[ESM::PRT_LWrist] = ESM::BodyPart::MP_Wrist; - bodypartMap[ESM::PRT_RForearm] = ESM::BodyPart::MP_Forearm; - bodypartMap[ESM::PRT_LForearm] = ESM::BodyPart::MP_Forearm; - bodypartMap[ESM::PRT_RUpperarm] = ESM::BodyPart::MP_Upperarm; - bodypartMap[ESM::PRT_LUpperarm] = ESM::BodyPart::MP_Upperarm; - bodypartMap[ESM::PRT_RFoot] = ESM::BodyPart::MP_Foot; - bodypartMap[ESM::PRT_LFoot] = ESM::BodyPart::MP_Foot; - bodypartMap[ESM::PRT_RAnkle] = ESM::BodyPart::MP_Ankle; - bodypartMap[ESM::PRT_LAnkle] = ESM::BodyPart::MP_Ankle; - bodypartMap[ESM::PRT_RKnee] = ESM::BodyPart::MP_Knee; - bodypartMap[ESM::PRT_LKnee] = ESM::BodyPart::MP_Knee; - bodypartMap[ESM::PRT_RLeg] = ESM::BodyPart::MP_Upperleg; - bodypartMap[ESM::PRT_LLeg] = ESM::BodyPart::MP_Upperleg; - bodypartMap[ESM::PRT_Tail] = ESM::BodyPart::MP_Tail; - - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const int Flag_Female = 0x01; const int Flag_FirstPerson = 0x02; @@ -302,21 +278,43 @@ void NpcAnimation::updateParts(bool forceupdate) std::pair thisCombination = std::make_pair(race, flags); if (sRaceMapping.find(thisCombination) == sRaceMapping.end()) { - sRaceMapping[thisCombination].resize(ESM::PRT_Count); - for (int i=0; i bodypartMap; + if(bodypartMap.size() == 0) + { + bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck; + bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest; + bodypartMap[ESM::PRT_Groin] = ESM::BodyPart::MP_Groin; + bodypartMap[ESM::PRT_RHand] = ESM::BodyPart::MP_Hand; + bodypartMap[ESM::PRT_LHand] = ESM::BodyPart::MP_Hand; + bodypartMap[ESM::PRT_RWrist] = ESM::BodyPart::MP_Wrist; + bodypartMap[ESM::PRT_LWrist] = ESM::BodyPart::MP_Wrist; + bodypartMap[ESM::PRT_RForearm] = ESM::BodyPart::MP_Forearm; + bodypartMap[ESM::PRT_LForearm] = ESM::BodyPart::MP_Forearm; + bodypartMap[ESM::PRT_RUpperarm] = ESM::BodyPart::MP_Upperarm; + bodypartMap[ESM::PRT_LUpperarm] = ESM::BodyPart::MP_Upperarm; + bodypartMap[ESM::PRT_RFoot] = ESM::BodyPart::MP_Foot; + bodypartMap[ESM::PRT_LFoot] = ESM::BodyPart::MP_Foot; + bodypartMap[ESM::PRT_RAnkle] = ESM::BodyPart::MP_Ankle; + bodypartMap[ESM::PRT_LAnkle] = ESM::BodyPart::MP_Ankle; + bodypartMap[ESM::PRT_RKnee] = ESM::BodyPart::MP_Knee; + bodypartMap[ESM::PRT_LKnee] = ESM::BodyPart::MP_Knee; + bodypartMap[ESM::PRT_RLeg] = ESM::BodyPart::MP_Upperleg; + bodypartMap[ESM::PRT_LLeg] = ESM::BodyPart::MP_Upperleg; + bodypartMap[ESM::PRT_Tail] = ESM::BodyPart::MP_Tail; + } - const MWWorld::Store &partStore = store.get(); + sRaceMapping[thisCombination].resize(ESM::PRT_Count, NULL); - for (MWWorld::Store::iterator it = partStore.begin(); it != partStore.end(); ++it) + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::Store &partStore = store.get(); + for(MWWorld::Store::iterator it = partStore.begin(); it != partStore.end(); ++it) { const ESM::BodyPart& bodypart = *it; if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable) continue; if (bodypart.mData.mType != ESM::BodyPart::MT_Skin) - { continue; - } + if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female)) continue; if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace)) From 854de1c6c14ebd55b1cf05884ef4b4207cf6d094 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 11:43:37 -0700 Subject: [PATCH 11/12] Make sure the weapon is in the proper group --- apps/openmw/mwrender/npcanimation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index c616a1ff5..a92092020 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -481,7 +481,7 @@ void NpcAnimation::showWeapons(bool showWeapon) if(mWeapon != inv.end()) // special case for weapons { std::string mesh = MWWorld::Class::get(*mWeapon).getModel(*mWeapon); - addOrReplaceIndividualPart(ESM::PRT_Weapon,-1,1,mesh); + addOrReplaceIndividualPart(ESM::PRT_Weapon, MWWorld::InventoryStore::Slot_CarriedRight, 1, mesh); } } else From 020e3e8a8ed6425665e17ef729ac2ca2e7465480 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Apr 2013 12:08:43 -0700 Subject: [PATCH 12/12] Show the equipped weapon in the inventory screen And use the proper pose based on what's equipped. --- apps/openmw/mwrender/characterpreview.cpp | 46 ++++++++++++++++++++++- apps/openmw/mwrender/characterpreview.hpp | 1 + 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 24b089db3..4d9680b2c 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -12,6 +12,7 @@ #include "../mwbase/world.hpp" #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" #include "renderconst.hpp" #include "npcanimation.hpp" @@ -134,6 +135,46 @@ namespace MWRender void InventoryPreview::update(int sizeX, int sizeY) { + MWWorld::InventoryStore &inv = MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter); + MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + std::string groupname; + if(iter == inv.end()) + groupname = "inventoryhandtohand"; + else + { + const std::string &type = iter->getTypeName(); + if(type == typeid(ESM::Lockpick).name() || type == typeid(ESM::Probe).name()) + groupname = "inventoryweapononehand"; + else if(type == typeid(ESM::Weapon).name()) + { + MWWorld::LiveCellRef *ref = iter->get(); + + int type = ref->mBase->mData.mType; + if(type == ESM::Weapon::ShortBladeOneHand || + type == ESM::Weapon::LongBladeOneHand || + type == ESM::Weapon::BluntOneHand || + type == ESM::Weapon::AxeOneHand) + groupname = "inventoryweapononehand"; + else if(type == ESM::Weapon::LongBladeTwoHand || + type == ESM::Weapon::BluntTwoClose || + type == ESM::Weapon::AxeTwoHand) + groupname = "inventoryweapontwohand"; + else if(type == ESM::Weapon::BluntTwoWide || + type == ESM::Weapon::SpearTwoWide) + groupname = "inventoryweapontwowide"; + else + groupname = "inventoryhandtohand"; + } + else + groupname = "inventoryhandtohand"; + } + + if(groupname != mCurrentAnimGroup) + { + mCurrentAnimGroup = groupname; + mAnimation->play(mCurrentAnimGroup, "start", "stop", 0.0f, 0); + } + mAnimation->forceUpdate(); mAnimation->runAnimation(0.0f); @@ -155,7 +196,10 @@ namespace MWRender if (!mSelectionBuffer) mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0); - mAnimation->play("inventoryhandtohand", "start", "stop", 0.0f, 0); + mAnimation->showWeapons(true); + + mCurrentAnimGroup = "inventoryhandtohand"; + mAnimation->play(mCurrentAnimGroup, "start", "stop", 0.0f, 0); } // -------------------------------------------------------------------------------------------------- diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index 08cbd5108..d8f43f71b 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -53,6 +53,7 @@ namespace MWRender MWWorld::Ptr mCharacter; MWRender::NpcAnimation* mAnimation; + std::string mCurrentAnimGroup; std::string mName;