1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-20 07:23:53 +00:00

NPCs / creatures can now emit ripples

This commit is contained in:
scrawl 2013-02-27 09:20:42 +01:00
parent d4264353a3
commit 9b0ac4e299
9 changed files with 205 additions and 98 deletions

View file

@ -6,6 +6,8 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "animation.hpp" #include "animation.hpp"
#include "activatoranimation.hpp" #include "activatoranimation.hpp"
#include "creatureanimation.hpp" #include "creatureanimation.hpp"
@ -72,6 +74,7 @@ void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv)
NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), inv, RV_Actors); NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), inv, RV_Actors);
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors[ptr] = anim; mAllActors[ptr] = anim;
mRendering->addWaterRippleEmitter (ptr);
} }
void Actors::insertCreature (const MWWorld::Ptr& ptr) void Actors::insertCreature (const MWWorld::Ptr& ptr)
{ {
@ -79,6 +82,7 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr)
CreatureAnimation* anim = new CreatureAnimation(ptr); CreatureAnimation* anim = new CreatureAnimation(ptr);
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors[ptr] = anim; mAllActors[ptr] = anim;
mRendering->addWaterRippleEmitter (ptr);
} }
void Actors::insertActivator (const MWWorld::Ptr& ptr) void Actors::insertActivator (const MWWorld::Ptr& ptr)
{ {
@ -90,6 +94,8 @@ void Actors::insertActivator (const MWWorld::Ptr& ptr)
bool Actors::deleteObject (const MWWorld::Ptr& ptr) bool Actors::deleteObject (const MWWorld::Ptr& ptr)
{ {
mRendering->removeWaterRippleEmitter (ptr);
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors.erase(ptr); mAllActors.erase(ptr);
@ -120,6 +126,7 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store)
{ {
if(iter->first.getCell() == store) if(iter->first.getCell() == store)
{ {
mRendering->removeWaterRippleEmitter (iter->first);
delete iter->second; delete iter->second;
mAllActors.erase(iter++); mAllActors.erase(iter++);
} }
@ -172,6 +179,8 @@ void Actors::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
anim->updatePtr(cur); anim->updatePtr(cur);
mAllActors[cur] = anim; mAllActors[cur] = anim;
} }
mRendering->updateWaterRippleEmitterPtr (old, cur);
} }
} }

View file

@ -13,6 +13,7 @@ namespace MWWorld
namespace MWRender namespace MWRender
{ {
class Animation; class Animation;
class RenderingManager;
class Actors class Actors
{ {
@ -20,13 +21,17 @@ namespace MWRender
typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap; typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap;
OEngine::Render::OgreRenderer &mRend; OEngine::Render::OgreRenderer &mRend;
MWRender::RenderingManager* mRendering;
Ogre::SceneNode* mRootNode; Ogre::SceneNode* mRootNode;
CellSceneNodeMap mCellSceneNodes; CellSceneNodeMap mCellSceneNodes;
PtrAnimationMap mAllActors; PtrAnimationMap mAllActors;
public: public:
Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {} Actors(OEngine::Render::OgreRenderer& _rend, MWRender::RenderingManager* rendering)
: mRend(_rend)
, mRendering(rendering)
{}
~Actors(); ~Actors();
void setRootNode(Ogre::SceneNode* root); void setRootNode(Ogre::SceneNode* root);

View file

@ -32,7 +32,7 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag
mLight = mRendering->getScene()->createLight(); mLight = mRendering->getScene()->createLight();
mLight->setType (Ogre::Light::LT_DIRECTIONAL); mLight->setType (Ogre::Light::LT_DIRECTIONAL);
mLight->setDirection (Ogre::Vector3(0.3, -0.7, 0.3)); mLight->setDirection (Ogre::Vector3(0.3, 0.3, -0.7));
mLight->setVisible (false); mLight->setVisible (false);
mLight->setDiffuseColour (ColourValue(0.7,0.7,0.7)); mLight->setDiffuseColour (ColourValue(0.7,0.7,0.7));
} }

View file

@ -51,7 +51,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine)
: mRendering(_rend) : mRendering(_rend)
, mObjects(mRendering) , mObjects(mRendering)
, mActors(mRendering) , mActors(mRendering, this)
, mAmbientMode(0) , mAmbientMode(0)
, mSunEnabled(0) , mSunEnabled(0)
, mPhysicsEngine(engine) , mPhysicsEngine(engine)
@ -136,7 +136,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
sh::Factory::getInstance ().setSharedParameter ("viewportBackground", sh::makeProperty<sh::Vector3> (new sh::Vector3(0,0,0)));
sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0))); sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0)));
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
@ -173,6 +172,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mDebugging = new Debugging(mRootNode, engine); mDebugging = new Debugging(mRootNode, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this); mLocalMap = new MWRender::LocalMap(&mRendering, this);
mWater = new MWRender::Water(mRendering.getCamera(), this);
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
} }
@ -222,15 +223,12 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
void RenderingManager::removeWater () void RenderingManager::removeWater ()
{ {
if(mWater){ mWater->setActive(false);
mWater->setActive(false);
}
} }
void RenderingManager::toggleWater() void RenderingManager::toggleWater()
{ {
if (mWater) mWater->toggle();
mWater->toggle();
} }
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
@ -321,6 +319,20 @@ RenderingManager::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &
void RenderingManager::update (float duration, bool paused) void RenderingManager::update (float duration, bool paused)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld();
// player position
MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
float *_playerPos = data.getPosition().pos;
Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]);
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
Ogre::Vector3 orig, dest; Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance(); mPlayer->setCameraDistance();
if (!mPlayer->getPosition(orig, dest)) { if (!mPlayer->getPosition(orig, dest)) {
@ -343,6 +355,17 @@ void RenderingManager::update (float duration, bool paused)
Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f); Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f);
/*
if (world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam))
{
mFogColour = Ogre::ColourValue(0.18039, 0.23137, 0.25490);
mFogStart = 0;
mFogEnd = 1500;
}
*/
applyFog();
if(paused) if(paused)
{ {
return; return;
@ -358,41 +381,21 @@ void RenderingManager::update (float duration, bool paused)
mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());
MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
float *fpos = data.getPosition().pos;
// only for LocalMap::updatePlayer()
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
Ogre::SceneNode *node = data.getBaseNode(); Ogre::SceneNode *node = data.getBaseNode();
//Ogre::Quaternion orient = //Ogre::Quaternion orient =
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); //node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
Ogre::Quaternion orient = Ogre::Quaternion orient =
node->_getDerivedOrientation(); node->_getDerivedOrientation();
mLocalMap->updatePlayer(pos, orient); mLocalMap->updatePlayer(playerPos, orient);
if (mWater) { mWater->updateUnderwater(
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
cam)
);
MWBase::World *world = MWBase::Environment::get().getWorld(); mWater->update(duration, playerPos);
mWater->updateUnderwater(
world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
cam)
);
// MW to ogre coordinates
orig = Ogre::Vector3(orig.x, orig.z, -orig.y);
mWater->update(duration, orig);
}
} }
void RenderingManager::preRenderTargetUpdate(const RenderTargetEvent &evt) void RenderingManager::preRenderTargetUpdate(const RenderTargetEvent &evt)
@ -416,10 +419,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
|| ((store->mCell->isExterior()) || ((store->mCell->isExterior())
&& !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land. && !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land.
{ {
if(mWater == 0) mWater->changeCell(store->mCell);
mWater = new MWRender::Water(mRendering.getCamera(), this, store->mCell);
else
mWater->changeCell(store->mCell);
mWater->setActive(true); mWater->setActive(true);
} }
else else
@ -428,8 +428,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store)
void RenderingManager::setWaterHeight(const float height) void RenderingManager::setWaterHeight(const float height)
{ {
if (mWater) mWater->setHeight(height);
mWater->setHeight(height);
} }
void RenderingManager::skyEnable () void RenderingManager::skyEnable ()
@ -521,24 +520,26 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell)
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
{ {
mFogColour = colour;
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance"); float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance"); mFogStart = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance"); mFogEnd = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getCamera()->setFarClipDistance ( max / density );
mRendering.getViewport()->setBackgroundColour (colour);
if (mWater)
mWater->setViewportBackground (colour);
sh::Factory::getInstance ().setSharedParameter ("viewportBackground",
sh::makeProperty<sh::Vector3> (new sh::Vector3(colour.r, colour.g, colour.b)));
mRendering.getCamera()->setFarClipDistance ( Settings::Manager::getFloat("max viewing distance", "Viewing distance") / density );
} }
void RenderingManager::applyFog ()
{
mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd);
mRendering.getViewport()->setBackgroundColour (mFogColour);
mWater->setViewportBackground (mFogColour);
sh::Factory::getInstance ().setSharedParameter ("viewportBackground",
sh::makeProperty<sh::Vector3> (new sh::Vector3(mFogColour.r, mFogColour.g, mFogColour.b)));
}
void RenderingManager::setAmbientMode() void RenderingManager::setAmbientMode()
{ {
@ -826,8 +827,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y);
} }
if (mWater) mWater->processChangedSettings(settings);
mWater->processChangedSettings(settings);
if (rebuild) if (rebuild)
mObjects.rebuildStaticGeometry(); mObjects.rebuildStaticGeometry();
@ -902,6 +902,8 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors
); );
mPlayer->setAnimation(anim); mPlayer->setAnimation(anim);
mWater->removeEmitter (ptr);
mWater->addEmitter (ptr);
} }
void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw)
@ -945,4 +947,19 @@ void RenderingManager::stopVideo()
mVideoPlayer->stopVideo (); mVideoPlayer->stopVideo ();
} }
void RenderingManager::addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale, float force)
{
mWater->addEmitter (ptr, scale, force);
}
void RenderingManager::removeWaterRippleEmitter (const MWWorld::Ptr& ptr)
{
mWater->removeEmitter (ptr);
}
void RenderingManager::updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
mWater->updateEmitterPtr(old, ptr);
}
} // namespace } // namespace

View file

@ -163,6 +163,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void skySetMoonColour (bool red); void skySetMoonColour (bool red);
void configureAmbient(MWWorld::CellStore &mCell); void configureAmbient(MWWorld::CellStore &mCell);
void addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
void removeWaterRippleEmitter (const MWWorld::Ptr& ptr);
void updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
void requestMap (MWWorld::CellStore* cell); void requestMap (MWWorld::CellStore* cell);
///< request the local map for a cell ///< request the local map for a cell
@ -204,6 +208,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
sh::Factory* mFactory; sh::Factory* mFactory;
void setAmbientMode(); void setAmbientMode();
void applyFog();
void setMenuTransparency(float val); void setMenuTransparency(float val);
@ -234,6 +239,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
Ogre::SceneNode *mRootNode; Ogre::SceneNode *mRootNode;
Ogre::ColourValue mFogColour;
float mFogStart;
float mFogEnd;
OEngine::Physic::PhysicEngine* mPhysicsEngine; OEngine::Physic::PhysicEngine* mPhysicsEngine;
MWRender::Player *mPlayer; MWRender::Player *mPlayer;

View file

@ -7,6 +7,11 @@
#include <extern/shiny/Main/Factory.hpp> #include <extern/shiny/Main/Factory.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
namespace MWRender namespace MWRender
{ {
@ -21,8 +26,7 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager)
mRippleAreaLength(1000), mRippleAreaLength(1000),
mImpulseSize(20), mImpulseSize(20),
mTexelOffset(0,0), mTexelOffset(0,0),
mFirstUpdate(true), mFirstUpdate(true)
mLastPos(0,0)
{ {
Ogre::AxisAlignedBox aabInf; Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite(); aabInf.setInfinite();
@ -142,34 +146,39 @@ void RippleSimulation::update(float dt, Ogre::Vector2 position)
new sh::Vector3(mRippleCenter.x + mTexelOffset.x, mRippleCenter.y + mTexelOffset.y, 0))); new sh::Vector3(mRippleCenter.x + mTexelOffset.x, mRippleCenter.y + mTexelOffset.y, 0)));
} }
void RippleSimulation::addImpulse(Ogre::Vector2 position, float scale, float force)
{
// don't emit if there wasn't enough movement
/// \todo this should be done somewhere else, otherwise multiple emitters cannot be supported
if ((position - mLastPos).length () <= 2)
return;
mLastPos = position;
/// \todo scale, force
mImpulses.push(position);
}
void RippleSimulation::addImpulses() void RippleSimulation::addImpulses()
{ {
mRectangle->setVisible(false); mRectangle->setVisible(false);
mImpulse->setVisible(true); mImpulse->setVisible(true);
while (mImpulses.size()) /// \todo it should be more efficient to render all emitters at once
for (std::vector<Emitter>::iterator it=mEmitters.begin(); it !=mEmitters.end(); ++it)
{ {
Ogre::Vector2 pos = mImpulses.front(); if (it->mPtr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ())
pos -= mRippleCenter; {
pos /= mRippleAreaLength; // fetch a new ptr (to handle cell change etc)
float size = mImpulseSize / mRippleAreaLength; // for non-player actors this is done in updateObjectCell
mImpulse->setCorners(pos.x-size, pos.y+size, pos.x+size, pos.y-size, false); it->mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
mImpulses.pop(); }
float* _currentPos = it->mPtr.getRefData().getPosition().pos;
Ogre::Vector3 currentPos (_currentPos[0], _currentPos[1], _currentPos[2]);
mRenderTargets[1]->update(); if ( (currentPos - it->mLastEmitPosition).length() > 2
&& MWBase::Environment::get().getWorld ()->isUnderwater (it->mPtr.getCell(), currentPos))
{
it->mLastEmitPosition = currentPos;
Ogre::Vector2 pos (currentPos.x, currentPos.y);
pos -= mRippleCenter;
pos /= mRippleAreaLength;
float size = mImpulseSize / mRippleAreaLength;
mImpulse->setCorners(pos.x-size, pos.y+size, pos.x+size, pos.y-size, false);
// don't render if we are offscreen
if (pos.x - size >= 1.0 || pos.y+size <= -1.0 || pos.x+size <= -1.0 || pos.y-size >= 1.0)
continue;
mRenderTargets[1]->update();
}
} }
mImpulse->setVisible(false); mImpulse->setVisible(false);
@ -216,5 +225,39 @@ void RippleSimulation::swapHeightMaps()
mTextures[2] = tmp2; mTextures[2] = tmp2;
} }
void RippleSimulation::addEmitter(const MWWorld::Ptr& ptr, float scale, float force)
{
Emitter newEmitter;
newEmitter.mPtr = ptr;
newEmitter.mScale = scale;
newEmitter.mForce = force;
newEmitter.mLastEmitPosition = Ogre::Vector3(0,0,0);
mEmitters.push_back (newEmitter);
}
void RippleSimulation::removeEmitter (const MWWorld::Ptr& ptr)
{
for (std::vector<Emitter>::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it)
{
if (it->mPtr == ptr)
{
mEmitters.erase(it);
return;
}
}
}
void RippleSimulation::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
for (std::vector<Emitter>::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it)
{
if (it->mPtr == old)
{
it->mPtr = ptr;
return;
}
}
}
} }

View file

@ -4,6 +4,9 @@
#include <OgreTexture.h> #include <OgreTexture.h>
#include <OgreMaterial.h> #include <OgreMaterial.h>
#include <OgreVector2.h> #include <OgreVector2.h>
#include <OgreVector3.h>
#include "../mwworld/ptr.hpp"
namespace Ogre namespace Ogre
{ {
@ -16,6 +19,14 @@ namespace Ogre
namespace MWRender namespace MWRender
{ {
struct Emitter
{
MWWorld::Ptr mPtr;
Ogre::Vector3 mLastEmitPosition;
float mScale;
float mForce;
};
class RippleSimulation class RippleSimulation
{ {
public: public:
@ -24,9 +35,14 @@ public:
void update(float dt, Ogre::Vector2 position); void update(float dt, Ogre::Vector2 position);
void addImpulse (Ogre::Vector2 position, float scale = 1.f, float force = 1.f); /// adds an emitter, position will be tracked automatically
void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
void removeEmitter (const MWWorld::Ptr& ptr);
void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
private: private:
std::vector<Emitter> mEmitters;
Ogre::RenderTexture* mRenderTargets[4]; Ogre::RenderTexture* mRenderTargets[4];
Ogre::TexturePtr mTextures[4]; Ogre::TexturePtr mTextures[4];
@ -34,8 +50,6 @@ private:
float mRippleAreaLength; float mRippleAreaLength;
float mImpulseSize; float mImpulseSize;
Ogre::Vector2 mLastPos;
bool mFirstUpdate; bool mFirstUpdate;
Ogre::Camera* mCamera; Ogre::Camera* mCamera;
@ -51,8 +65,6 @@ private:
Ogre::Rectangle2D* mImpulse; Ogre::Rectangle2D* mImpulse;
std::queue <Ogre::Vector2> mImpulses;
void addImpulses(); void addImpulses();
void heightMapToNormalMap(); void heightMapToNormalMap();
void waterSimulation(); void waterSimulation();

View file

@ -81,6 +81,7 @@ void CubeReflection::update ()
PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky) PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky)
: Reflection(sceneManager) : Reflection(sceneManager)
, mSky(sky) , mSky(sky)
, mRenderActive(false)
{ {
mCamera = mSceneMgr->createCamera ("PlaneReflectionCamera"); mCamera = mSceneMgr->createCamera ("PlaneReflectionCamera");
mSceneMgr->addRenderQueueListener(this); mSceneMgr->addRenderQueueListener(this);
@ -186,7 +187,7 @@ void PlaneReflection::setVisibilityMask (int flags)
// -------------------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------------------
Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : Water::Water (Ogre::Camera *camera, RenderingManager* rend) :
mCamera (camera), mSceneMgr (camera->getSceneManager()), mCamera (camera), mSceneMgr (camera->getSceneManager()),
mIsUnderwater(false), mVisibilityFlags(0), mIsUnderwater(false), mVisibilityFlags(0),
mActive(1), mToggled(1), mActive(1), mToggled(1),
@ -202,7 +203,7 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mMaterial = MaterialManager::getSingleton().getByName("Water"); mMaterial = MaterialManager::getSingleton().getByName("Water");
mTop = cell->mWater; mTop = 0;
mIsUnderwater = false; mIsUnderwater = false;
@ -216,10 +217,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
if(!(cell->mData.mFlags & cell->Interior))
{
mWaterNode->setPosition(getSceneNodeCoordinates(cell->mData.mX, cell->mData.mY));
}
mWaterNode->attachObject(mWater); mWaterNode->attachObject(mWater);
applyRTT(); applyRTT();
@ -397,7 +394,7 @@ void Water::update(float dt, Ogre::Vector3 player)
{ {
//mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); //mSimulation->addImpulse(Ogre::Vector2(player.x, player.z));
} }
mSimulation->update(dt, Ogre::Vector2(player.x, player.z)); mSimulation->update(dt, Ogre::Vector2(player.x, player.y));
if (mReflection) if (mReflection)
mReflection->update(); mReflection->update();
@ -499,10 +496,19 @@ void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& co
} }
} }
void Water::addImpulse (Vector2 position, float scale, float force) void Water::addEmitter (const MWWorld::Ptr& ptr, float scale, float force)
{ {
if (mSimulation) mSimulation->addEmitter (ptr, scale, force);
mSimulation->addImpulse (position, scale, force); }
void Water::removeEmitter (const MWWorld::Ptr& ptr)
{
mSimulation->removeEmitter (ptr);
}
void Water::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr)
{
mSimulation->updateEmitterPtr(old, ptr);
} }
} // namespace } // namespace

View file

@ -11,9 +11,12 @@
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <extern/shiny/Main/MaterialInstance.hpp>
#include "renderconst.hpp" #include "renderconst.hpp"
#include <extern/shiny/Main/MaterialInstance.hpp> #include "../mwworld/ptr.hpp"
namespace Ogre namespace Ogre
{ {
@ -138,7 +141,7 @@ namespace MWRender {
RippleSimulation* mSimulation; RippleSimulation* mSimulation;
public: public:
Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell); Water (Ogre::Camera *camera, RenderingManager* rend);
~Water(); ~Water();
void setActive(bool active); void setActive(bool active);
@ -146,7 +149,10 @@ namespace MWRender {
void toggle(); void toggle();
void update(float dt, Ogre::Vector3 player); void update(float dt, Ogre::Vector3 player);
void addImpulse (Ogre::Vector2 position, float scale = 1.f, float force = 1.f); /// adds an emitter, position will be tracked automatically using its scene node
void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
void removeEmitter (const MWWorld::Ptr& ptr);
void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
void setViewportBackground(const Ogre::ColourValue& bg); void setViewportBackground(const Ogre::ColourValue& bg);