diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index a91149777..b31383936 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -153,7 +153,7 @@ namespace MWBase virtual void update(float duration) = 0; - virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up) = 0; + virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater) = 0; virtual void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated) = 0; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index f6403a925..c0a907f70 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -387,6 +387,7 @@ namespace MWRender osg::Vec3f focal, cameraPos; mCamera->getPosition(focal, cameraPos); + mCurrentCameraPos = cameraPos; if (mWater->isUnderwater(cameraPos)) { setFogColor(mUnderwaterColor * mUnderwaterWeight + mFogColor * (1.f-mUnderwaterWeight)); @@ -865,6 +866,11 @@ namespace MWRender return mCamera.get(); } + const osg::Vec3f &RenderingManager::getCameraPosition() const + { + return mCurrentCameraPos; + } + void RenderingManager::togglePOV() { mCamera->toggleViewMode(); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 203df2269..a0ea14cb4 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -159,6 +159,7 @@ namespace MWRender void resetCamera(); float getCameraDistance() const; Camera* getCamera(); + const osg::Vec3f& getCameraPosition() const; void togglePOV(); void togglePreviewMode(bool enable); bool toggleVanityMode(bool enable); @@ -188,6 +189,7 @@ namespace MWRender std::auto_ptr mPlayerAnimation; osg::ref_ptr mPlayerNode; std::auto_ptr mCamera; + osg::Vec3f mCurrentCameraPos; osg::ref_ptr mStateUpdater; diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index ceff1a619..3b24e26ab 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -946,16 +946,13 @@ namespace MWSound mOutput->finishUpdate(); } - void SoundManager::setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up) + void SoundManager::setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater) { mListenerPos = pos; mListenerDir = dir; mListenerUp = up; - MWWorld::Ptr player = MWMechanics::getPlayer(); - const MWWorld::CellStore *cell = player.getCell(); - - mListenerUnderwater = ((cell->getCell()->mData.mFlags&ESM::Cell::HasWater) && mListenerPos.z() < cell->getWaterLevel()); + mListenerUnderwater = underwater; } void SoundManager::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index 9c090585b..1f1a5cd6b 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -218,7 +218,7 @@ namespace MWSound virtual void update(float duration); - virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up); + virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater); virtual void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6bced30c4..22485ed92 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1601,18 +1601,23 @@ namespace MWWorld void World::updateSoundListener() { const ESM::Position& refpos = getPlayerPtr().getRefData().getPosition(); - osg::Vec3f playerPos = refpos.asVec3(); + osg::Vec3f listenerPos; - playerPos.z() += 1.85f * mPhysics->getHalfExtents(getPlayerPtr()).z(); + if (isFirstPerson()) + listenerPos = mRendering->getCameraPosition(); + else + listenerPos = refpos.asVec3() + osg::Vec3f(0, 0, 1.85f * mPhysics->getHalfExtents(getPlayerPtr()).z()); - osg::Quat playerOrient = osg::Quat(refpos.rot[1], osg::Vec3f(0,-1,0)) * + osg::Quat listenerOrient = osg::Quat(refpos.rot[1], osg::Vec3f(0,-1,0)) * osg::Quat(refpos.rot[0], osg::Vec3f(-1,0,0)) * osg::Quat(refpos.rot[2], osg::Vec3f(0,0,-1)); - osg::Vec3f forward = playerOrient * osg::Vec3f(0,1,0); - osg::Vec3f up = playerOrient * osg::Vec3f(0,0,1); + osg::Vec3f forward = listenerOrient * osg::Vec3f(0,1,0); + osg::Vec3f up = listenerOrient * osg::Vec3f(0,0,1); + + bool underwater = isUnderwater(getPlayerPtr().getCell(), listenerPos); - MWBase::Environment::get().getSoundManager()->setListenerPosDir(playerPos, forward, up); + MWBase::Environment::get().getSoundManager()->setListenerPosDir(listenerPos, forward, up, underwater); } void World::updateWindowManager ()