diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 6835fd64ce..153d4af490 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 332db457c7..3c645230bb 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 1ce1baa39b..252e296661 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 6420a5b7e2..20ec0d9ae9 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 db565c4513..c1a3ae7859 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 77ceb3721a..642f5412c8 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 a3fda913d0..f3909a1da7 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); } }