From ff627706573cc0c624cadd79c692316de80e5686 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 3 Aug 2012 14:42:09 +0400 Subject: [PATCH] World::isUnderwater(), World::isSwimming() --- apps/openmw/mwbase/world.hpp | 3 +++ apps/openmw/mwrender/renderingmanager.cpp | 20 +++++++++-------- apps/openmw/mwrender/renderingmanager.hpp | 1 - apps/openmw/mwrender/water.cpp | 20 ++++++----------- apps/openmw/mwrender/water.hpp | 3 ++- apps/openmw/mwworld/worldimp.cpp | 26 +++++++++++++++++++++++ apps/openmw/mwworld/worldimp.hpp | 3 +++ 7 files changed, 52 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f257b723e..d9e19bead 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -249,6 +249,9 @@ namespace MWBase ///< @return true if it is possible to place on object at specified cursor location virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0; + + virtual bool isSwimming(const MWWorld::Ptr &object) = 0; + virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ae0e57219..cbf799d7a 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -275,11 +275,20 @@ void RenderingManager::update (float duration){ mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); - checkUnderwater(); + if (mWater) { + Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); - if (mWater) + MWBase::World *world = MWBase::Environment::get().getWorld(); + + mWater->updateUnderwater( + world->isUnderwater( + *world->getPlayer().getPlayer().getCell()->cell, + Ogre::Vector3(cam.x, -cam.z, cam.y)) + ); mWater->update(duration); + } } + void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ if(store->cell->data.flags & store->cell->HasWater || ((!(store->cell->data.flags & ESM::Cell::Interior)) @@ -459,13 +468,6 @@ void RenderingManager::toggleLight() setAmbientMode(); } -void RenderingManager::checkUnderwater() -{ - if(mWater) - { - mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y ); - } -} void RenderingManager::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index d6a372d10..12cbee9b8 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -91,7 +91,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale); void rotateObject (const MWWorld::Ptr& ptr, const::Ogre::Quaternion& orientation); - void checkUnderwater(); void setWaterHeight(const float height); void toggleWater(); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 92fc97b3b..d5b93b7cb 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -184,22 +184,16 @@ void Water::toggle() updateVisible(); } -void Water::checkUnderwater(float y) +void +Water::updateUnderwater(bool underwater) { - if (!mActive) - { + if (!mActive) { return; } - - if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) - { - mIsUnderwater = false; - } - - if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID) - { - mIsUnderwater = true; - } + mIsUnderwater = + underwater && + mWater->isVisible() && + mCamera->getPolygonMode() == Ogre::PM_SOLID; updateVisible(); } diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index d0a5a4352..f56ba7410 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -101,7 +101,8 @@ namespace MWRender { void processChangedSettings(const Settings::CategorySettingVector& settings); - void checkUnderwater(float y); + /// Updates underwater state accordingly + void updateUnderwater(bool underwater); void changeCell(const ESM::Cell* cell); void setHeight(const float height); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 67d8a7cec..4bdf3f948 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -18,6 +18,8 @@ #include "manualref.hpp" #include "cellfunctors.hpp" +#include + using namespace Ogre; namespace @@ -1095,4 +1097,28 @@ namespace MWWorld { mRendering->getTriangleBatchCount(triangles, batches); } + + bool + World::isSwimming(const MWWorld::Ptr &object) + { + /// \todo add check ifActor() - only actors can swim + float *fpos = object.getRefData().getPosition().pos; + Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]); + + /// \fixme should rely on object height + pos.z += 30; + + return isUnderwater(*object.getCell()->cell, pos); + } + + bool + World::isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) + { + if (cell.data.flags & ESM::Cell::HasWater == 0) { + return false; + } + bool res = pos.z < cell.water; + std::cout << "World::isUnderwater(" << pos.z << "):" << res << std::endl; + return res; + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d39871c21..f80b88be2 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -270,6 +270,9 @@ namespace MWWorld ///< @return true if it is possible to place on object at specified cursor location virtual void processChangedSettings(const Settings::CategorySettingVector& settings); + + virtual bool isSwimming(const MWWorld::Ptr &object); + virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos); }; }