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:
parent
d4264353a3
commit
9b0ac4e299
9 changed files with 205 additions and 98 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue