Port EffectManager

c++11
scrawl 10 years ago
parent fcc7aa02ab
commit 68f93294da

@ -21,11 +21,11 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender add_openmw_dir (mwrender
actors objects renderingmanager animation sky npcanimation vismask actors objects renderingmanager animation sky npcanimation vismask
creatureanimation creatureanimation effectmanager util
# debugging camera activatoranimation # debugging camera activatoranimation
# renderinginterface localmap occlusionquery water shadows # renderinginterface localmap occlusionquery water shadows
# characterpreview globalmap ripplesimulation refraction # characterpreview globalmap ripplesimulation refraction
# terrainstorage renderconst effectmanager weaponanimation # terrainstorage renderconst weaponanimation
) )
#add_openmw_dir (mwinput #add_openmw_dir (mwinput

@ -17,6 +17,11 @@ namespace Ogre
class Image; class Image;
} }
namespace osg
{
class Vec3f;
}
namespace Loading namespace Loading
{ {
class Listener; class Listener;
@ -546,9 +551,9 @@ namespace MWBase
virtual void spawnRandomCreature(const std::string& creatureList) = 0; virtual void spawnRandomCreature(const std::string& creatureList) = 0;
/// Spawn a blood effect for \a ptr at \a worldPosition /// Spawn a blood effect for \a ptr at \a worldPosition
virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const Ogre::Vector3& worldPosition) = 0; virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) = 0;
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const Ogre::Vector3& worldPos) = 0; virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos) = 0;
virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects, virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects,
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName) = 0; const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName) = 0;

@ -319,7 +319,7 @@ namespace MWClass
damage = 0; damage = 0;
if (damage > 0) if (damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, osg::Vec3f(hitPosition.x, hitPosition.y, hitPosition.z));
MWMechanics::diseaseContact(victim, ptr); MWMechanics::diseaseContact(victim, ptr);

@ -583,7 +583,7 @@ namespace MWClass
damage = 0; damage = 0;
if (healthdmg && damage > 0) if (healthdmg && damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, osg::Vec3f(hitPosition.x, hitPosition.y, hitPosition.z));
MWMechanics::diseaseContact(victim, ptr); MWMechanics::diseaseContact(victim, ptr);

@ -218,7 +218,7 @@ namespace MWMechanics
appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition); appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition);
if (damage > 0) if (damage > 0)
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, osg::Vec3f(hitPosition.x, hitPosition.y, hitPosition.z));
// Non-enchanted arrows shot at enemies have a chance to turn up in their inventory // Non-enchanted arrows shot at enemies have a chance to turn up in their inventory
if (victim != MWBase::Environment::get().getWorld()->getPlayerPtr() if (victim != MWBase::Environment::get().getWorld()->getPlayerPtr()

@ -34,7 +34,7 @@ namespace MWMechanics
.search("VFX_Summon_End"); .search("VFX_Summon_End");
if (fx) if (fx)
MWBase::Environment::get().getWorld()->spawnEffect("meshes\\" + fx->mModel, MWBase::Environment::get().getWorld()->spawnEffect("meshes\\" + fx->mModel,
"", Ogre::Vector3(ptr.getRefData().getPosition().pos)); "", ptr.getRefData().getPosition().asVec3());
} }
else else
{ {
@ -190,7 +190,7 @@ namespace MWMechanics
.search("VFX_Summon_End"); .search("VFX_Summon_End");
if (fx) if (fx)
MWBase::Environment::get().getWorld()->spawnEffect("meshes\\" + fx->mModel, MWBase::Environment::get().getWorld()->spawnEffect("meshes\\" + fx->mModel,
"", Ogre::Vector3(ptr.getRefData().getPosition().pos)); "", ptr.getRefData().getPosition().asVec3());
MWBase::Environment::get().getWorld()->deleteObject(ptr); MWBase::Environment::get().getWorld()->deleteObject(ptr);
} }

@ -24,6 +24,7 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include "util.hpp"
namespace namespace
{ {
@ -70,30 +71,6 @@ namespace
std::vector<osg::ref_ptr<osg::Texture2D> > mTextures; std::vector<osg::ref_ptr<osg::Texture2D> > mTextures;
}; };
class FindMaxControllerLengthVisitor : public SceneUtil::ControllerVisitor
{
public:
FindMaxControllerLengthVisitor()
: SceneUtil::ControllerVisitor()
, mMaxLength(0)
{
}
virtual void visit(osg::Node& , SceneUtil::Controller& ctrl)
{
if (ctrl.mFunction)
mMaxLength = std::max(mMaxLength, ctrl.mFunction->getMaximum());
}
float getMaxLength() const
{
return mMaxLength;
}
private:
float mMaxLength;
};
} }
namespace MWRender namespace MWRender
@ -246,7 +223,7 @@ namespace MWRender
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->createInstance(model, parentNode); osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->createInstance(model, parentNode);
params.mObjects = PartHolderPtr(new PartHolder(node)); params.mObjects = PartHolderPtr(new PartHolder(node));
FindMaxControllerLengthVisitor findMaxLengthVisitor; SceneUtil::FindMaxControllerLengthVisitor findMaxLengthVisitor;
node->accept(findMaxLengthVisitor); node->accept(findMaxLengthVisitor);
params.mMaxControllerLength = findMaxLengthVisitor.getMaxLength(); params.mMaxControllerLength = findMaxLengthVisitor.getMaxLength();
@ -262,22 +239,7 @@ namespace MWRender
SceneUtil::AssignControllerSourcesVisitor assignVisitor(boost::shared_ptr<SceneUtil::ControllerSource>(params.mAnimTime)); SceneUtil::AssignControllerSourcesVisitor assignVisitor(boost::shared_ptr<SceneUtil::ControllerSource>(params.mAnimTime));
node->accept(assignVisitor); node->accept(assignVisitor);
if (!texture.empty()) overrideTexture(texture, mResourceSystem, node);
{
std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(texture, mResourceSystem->getVFS());
// Not sure if wrap settings should be pulled from the overridden texture?
osg::ref_ptr<osg::Texture2D> tex = mResourceSystem->getTextureManager()->getTexture2D(correctedTexture, osg::Texture2D::CLAMP,
osg::Texture2D::CLAMP);
osg::ref_ptr<osg::StateSet> stateset;
if (node->getStateSet())
stateset = static_cast<osg::StateSet*>(node->getStateSet()->clone(osg::CopyOp::SHALLOW_COPY));
else
stateset = new osg::StateSet;
stateset->setTextureAttribute(0, tex, osg::StateAttribute::OVERRIDE);
node->setStateSet(stateset);
}
// TODO: in vanilla morrowind the effect is scaled based on the host object's bounding box. // TODO: in vanilla morrowind the effect is scaled based on the host object's bounding box.
@ -330,22 +292,22 @@ namespace MWRender
} }
} }
float Animation::EffectAnimationTime::getValue(osg::NodeVisitor*) float EffectAnimationTime::getValue(osg::NodeVisitor*)
{ {
return mTime; return mTime;
} }
void Animation::EffectAnimationTime::addTime(float duration) void EffectAnimationTime::addTime(float duration)
{ {
mTime += duration; mTime += duration;
} }
void Animation::EffectAnimationTime::resetTime(float time) void EffectAnimationTime::resetTime(float time)
{ {
mTime = time; mTime = time;
} }
float Animation::EffectAnimationTime::getTime() const float EffectAnimationTime::getTime() const
{ {
return mTime; return mTime;
} }

@ -22,6 +22,20 @@ namespace MWRender
{ {
class Camera; class Camera;
class EffectAnimationTime : public SceneUtil::ControllerSource
{
private:
float mTime;
public:
virtual float getValue(osg::NodeVisitor* nv);
void addTime(float duration);
void resetTime(float time);
float getTime() const;
EffectAnimationTime() : mTime(0) { }
};
class Animation class Animation
{ {
public: public:
@ -61,20 +75,6 @@ protected:
virtual void setValue(Ogre::Real value); virtual void setValue(Ogre::Real value);
}; };
class EffectAnimationTime : public SceneUtil::ControllerSource
{
private:
float mTime;
public:
virtual float getValue(osg::NodeVisitor* nv);
void addTime(float duration);
void resetTime(float time);
float getTime() const;
EffectAnimationTime() : mTime(0) { }
};
class NullAnimationTime : public SceneUtil::ControllerSource class NullAnimationTime : public SceneUtil::ControllerSource
{ {
public: public:

@ -1,102 +1,83 @@
#include "effectmanager.hpp" #include "effectmanager.hpp"
#include <osg/PositionAttitudeTransform>
#include <components/misc/resourcehelpers.hpp> #include <components/misc/resourcehelpers.hpp>
#include <OgreSceneManager.h> #include <components/resource/resourcesystem.hpp>
#include <OgreParticleSystem.h> #include <components/resource/scenemanager.hpp>
#include <OgreSceneNode.h>
#include <OgreTechnique.h> #include <components/sceneutil/controller.hpp>
#include "animation.hpp" #include "animation.hpp"
#include "renderconst.hpp" #include "vismask.hpp"
#include "util.hpp"
namespace MWRender namespace MWRender
{ {
EffectManager::EffectManager(Ogre::SceneManager *sceneMgr) EffectManager::EffectManager(osg::ref_ptr<osg::Group> parent, Resource::ResourceSystem* resourceSystem)
: mSceneMgr(sceneMgr) : mParentNode(parent)
, mResourceSystem(resourceSystem)
{ {
} }
void EffectManager::addEffect(const std::string &model, std::string textureOverride, const Ogre::Vector3 &worldPosition, float scale) EffectManager::~EffectManager()
{ {
Ogre::SceneNode* sceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(worldPosition); clear();
sceneNode->setScale(scale,scale,scale); }
NifOgre::ObjectScenePtr scene = NifOgre::Loader::createObjects(sceneNode, model); void EffectManager::addEffect(const std::string &model, const std::string& textureOverride, const osg::Vec3f &worldPosition, float scale)
{
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->createInstance(model);
MWRender::Animation::setRenderProperties(scene, RV_Effects, node->setNodeMask(Mask_Effect);
RQG_Main, RQG_Alpha, 0.f, false, NULL);
for(size_t i = 0;i < scene->mControllers.size();i++) Effect effect;
{ effect.mAnimTime.reset(new EffectAnimationTime);
if(scene->mControllers[i].getSource().isNull())
scene->mControllers[i].setSource(Ogre::SharedPtr<EffectAnimationTime> (new EffectAnimationTime()));
}
if (!textureOverride.empty()) SceneUtil::FindMaxControllerLengthVisitor findMaxLengthVisitor;
{ node->accept(findMaxLengthVisitor);
std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(textureOverride); effect.mMaxControllerLength = findMaxLengthVisitor.getMaxLength();
for(size_t i = 0;i < scene->mParticles.size(); ++i)
{ osg::ref_ptr<osg::PositionAttitudeTransform> trans = new osg::PositionAttitudeTransform;
Ogre::ParticleSystem* partSys = scene->mParticles[i]; trans->setPosition(worldPosition);
trans->setScale(osg::Vec3f(scale, scale, scale));
Ogre::MaterialPtr mat = scene->mMaterialControllerMgr.getWritableMaterial(partSys); trans->addChild(node);
for (int t=0; t<mat->getNumTechniques(); ++t) SceneUtil::AssignControllerSourcesVisitor assignVisitor(effect.mAnimTime);
{ node->accept(assignVisitor);
Ogre::Technique* tech = mat->getTechnique(t);
for (int p=0; p<tech->getNumPasses(); ++p) overrideTexture(textureOverride, mResourceSystem, node);
{
Ogre::Pass* pass = tech->getPass(p);
for (int tex=0; tex<pass->getNumTextureUnitStates(); ++tex)
{
Ogre::TextureUnitState* tus = pass->getTextureUnitState(tex);
tus->setTextureName(correctedTexture);
}
}
}
}
}
mEffects.push_back(std::make_pair(sceneNode, scene)); mParentNode->addChild(trans);
mEffects[trans] = effect;
} }
void EffectManager::update(float dt, Ogre::Camera* camera) void EffectManager::update(float dt)
{ {
for (std::vector<std::pair<Ogre::SceneNode*, NifOgre::ObjectScenePtr> >::iterator it = mEffects.begin(); it != mEffects.end(); ) for (EffectMap::iterator it = mEffects.begin(); it != mEffects.end(); )
{ {
NifOgre::ObjectScenePtr objects = it->second; it->second.mAnimTime->addTime(dt);
for(size_t i = 0; i < objects->mControllers.size() ;i++)
{
EffectAnimationTime* value = dynamic_cast<EffectAnimationTime*>(objects->mControllers[i].getSource().get());
if (value)
value->addTime(dt);
objects->mControllers[i].update();
}
objects->rotateBillboardNodes(camera);
// Finished playing? if (it->second.mAnimTime->getTime() >= it->second.mMaxControllerLength)
if (objects->mControllers[0].getSource()->getValue() >= objects->mMaxControllerLength)
{ {
Ogre::SceneNode* node = it->first; mParentNode->removeChild(it->first);
it = mEffects.erase(it); mEffects.erase(it++);
mSceneMgr->destroySceneNode(node);
continue;
} }
++it; else
++it;
} }
} }
void EffectManager::clear() void EffectManager::clear()
{ {
for (std::vector<std::pair<Ogre::SceneNode*, NifOgre::ObjectScenePtr> >::iterator it = mEffects.begin(); it != mEffects.end(); ) for (EffectMap::iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{ {
Ogre::SceneNode* node = it->first; mParentNode->removeChild(it->first);
it = mEffects.erase(it);
mSceneMgr->destroySceneNode(node);
} }
mEffects.clear();
} }
} }

@ -1,43 +1,60 @@
#ifndef OPENMW_MWRENDER_EFFECTMANAGER_H #ifndef OPENMW_MWRENDER_EFFECTMANAGER_H
#define OPENMW_MWRENDER_EFFECTMANAGER_H #define OPENMW_MWRENDER_EFFECTMANAGER_H
#include <components/nifogre/ogrenifloader.hpp> #include <string>
#include <map>
namespace MWRender #include <osg/ref_ptr>
{
class EffectAnimationTime : public Ogre::ControllerValue<Ogre::Real> #include <boost/shared_ptr.hpp>
{
private:
float mTime;
public:
EffectAnimationTime() : mTime(0) { }
void addTime(float time) { mTime += time; }
virtual Ogre::Real getValue() const { return mTime; } namespace osg
virtual void setValue(Ogre::Real value) {} {
}; class Group;
class Vec3f;
class PositionAttitudeTransform;
}
namespace Resource
{
class ResourceSystem;
}
namespace MWRender
{
class EffectAnimationTime;
// Note: effects attached to another object should be managed by MWRender::Animation::addEffect. // Note: effects attached to another object should be managed by MWRender::Animation::addEffect.
// This class manages "free" effects, i.e. attached to a dedicated scene node in the world. // This class manages "free" effects, i.e. attached to a dedicated scene node in the world.
class EffectManager class EffectManager
{ {
public: public:
EffectManager(Ogre::SceneManager* sceneMgr); EffectManager(osg::ref_ptr<osg::Group> parent, Resource::ResourceSystem* resourceSystem);
~EffectManager() { clear(); } ~EffectManager();
/// Add an effect. When it's finished playing, it will be removed automatically. /// Add an effect. When it's finished playing, it will be removed automatically.
void addEffect (const std::string& model, std::string textureOverride, const Ogre::Vector3& worldPosition, float scale); void addEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPosition, float scale);
void update(float dt, Ogre::Camera* camera); void update(float dt);
/// Remove all effects /// Remove all effects
void clear(); void clear();
private: private:
std::vector<std::pair<Ogre::SceneNode*, NifOgre::ObjectScenePtr> > mEffects; struct Effect
Ogre::SceneManager* mSceneMgr; {
float mMaxControllerLength;
boost::shared_ptr<EffectAnimationTime> mAnimTime;
};
typedef std::map<osg::ref_ptr<osg::PositionAttitudeTransform>, Effect> EffectMap;
EffectMap mEffects;
osg::ref_ptr<osg::Group> mParentNode;
Resource::ResourceSystem* mResourceSystem;
EffectManager(const EffectManager&);
void operator=(const EffectManager&);
}; };
} }

@ -19,7 +19,6 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/cellstore.hpp"
#include "renderconst.hpp" #include "renderconst.hpp"
#include "animation.hpp" #include "animation.hpp"

@ -18,6 +18,7 @@
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include "sky.hpp" #include "sky.hpp"
#include "effectmanager.hpp"
namespace MWRender namespace MWRender
{ {
@ -60,6 +61,8 @@ namespace MWRender
mSky.reset(new SkyManager(mRootNode, resourceSystem->getSceneManager())); mSky.reset(new SkyManager(mRootNode, resourceSystem->getSceneManager()));
mEffectManager.reset(new EffectManager(mRootNode, mResourceSystem));
mViewer.setLightingMode(osgViewer::View::NO_LIGHT); mViewer.setLightingMode(osgViewer::View::NO_LIGHT);
osg::ref_ptr<osg::LightSource> source = new osg::LightSource; osg::ref_ptr<osg::LightSource> source = new osg::LightSource;
@ -163,6 +166,24 @@ namespace MWRender
void RenderingManager::update(float dt, bool paused) void RenderingManager::update(float dt, bool paused)
{ {
mObjects->update(dt); mObjects->update(dt);
mEffectManager->update(dt);
}
void RenderingManager::spawnEffect(const std::string &model, const std::string &texture, const osg::Vec3f &worldPosition, float scale)
{
mEffectManager->addEffect(model, texture, worldPosition, scale);
}
void RenderingManager::notifyWorldSpaceChanged()
{
mEffectManager->clear();
//mWater->clearRipples();
}
void RenderingManager::clear()
{
//mLocalMap->clear();
notifyWorldSpaceChanged();
} }
} }

@ -33,6 +33,7 @@ namespace MWRender
class StateUpdater; class StateUpdater;
class EffectManager;
class SkyManager; class SkyManager;
class RenderingManager : public MWRender::RenderingInterface class RenderingManager : public MWRender::RenderingInterface
@ -63,6 +64,14 @@ namespace MWRender
osg::Vec3f getEyePos(); osg::Vec3f getEyePos();
void spawnEffect(const std::string &model, const std::string &texture, const osg::Vec3f &worldPosition, float scale = 1.f);
/// Clear all savegame-specific data
void clear();
/// Clear all worldspace-specific data
void notifyWorldSpaceChanged();
void update(float dt, bool paused); void update(float dt, bool paused);
private: private:
@ -74,6 +83,7 @@ namespace MWRender
std::auto_ptr<Objects> mObjects; std::auto_ptr<Objects> mObjects;
std::auto_ptr<SkyManager> mSky; std::auto_ptr<SkyManager> mSky;
std::auto_ptr<EffectManager> mEffectManager;
osg::ref_ptr<StateUpdater> mStateUpdater; osg::ref_ptr<StateUpdater> mStateUpdater;

@ -0,0 +1,31 @@
#include "util.hpp"
#include <osg/Node>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/texturemanager.hpp>
#include <components/misc/resourcehelpers.hpp>
namespace MWRender
{
void overrideTexture(const std::string &texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr<osg::Node> node)
{
if (texture.empty())
return;
std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(texture, resourceSystem->getVFS());
// Not sure if wrap settings should be pulled from the overridden texture?
osg::ref_ptr<osg::Texture2D> tex = resourceSystem->getTextureManager()->getTexture2D(correctedTexture, osg::Texture2D::CLAMP,
osg::Texture2D::CLAMP);
osg::ref_ptr<osg::StateSet> stateset;
if (node->getStateSet())
stateset = static_cast<osg::StateSet*>(node->getStateSet()->clone(osg::CopyOp::SHALLOW_COPY));
else
stateset = new osg::StateSet;
stateset->setTextureAttribute(0, tex, osg::StateAttribute::OVERRIDE);
node->setStateSet(stateset);
}
}

@ -0,0 +1,24 @@
#ifndef OPENMW_MWRENDER_UTIL_H
#define OPENMW_MWRENDER_UTIL_H
#include <osg/ref_ptr>
#include <string>
namespace osg
{
class Node;
}
namespace Resource
{
class ResourceSystem;
}
namespace MWRender
{
void overrideTexture(const std::string& texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Node> node);
}
#endif

@ -5,6 +5,8 @@
#include "../mwscript/locals.hpp" #include "../mwscript/locals.hpp"
#include <osg/Vec3f>
namespace Ogre namespace Ogre
{ {
class SceneNode; class SceneNode;

@ -276,7 +276,7 @@ namespace MWWorld
void World::clear() void World::clear()
{ {
mWeatherManager->clear(); mWeatherManager->clear();
//mRendering->clear(); mRendering->clear();
#if 0 #if 0
mProjectileManager->clear(); mProjectileManager->clear();
#endif #endif
@ -991,8 +991,9 @@ namespace MWWorld
// changed worldspace // changed worldspace
#if 0 #if 0
mProjectileManager->clear(); mProjectileManager->clear();
mRendering->notifyWorldSpaceChanged();
#endif #endif
mRendering->notifyWorldSpaceChanged();
mCurrentWorldSpace = cellName; mCurrentWorldSpace = cellName;
} }
@ -1010,8 +1011,8 @@ namespace MWWorld
// changed worldspace // changed worldspace
#if 0 #if 0
mProjectileManager->clear(); mProjectileManager->clear();
mRendering->notifyWorldSpaceChanged();
#endif #endif
mRendering->notifyWorldSpaceChanged();
} }
removeContainerScripts(getPlayerPtr()); removeContainerScripts(getPlayerPtr());
mWorldScene->changeToExteriorCell(position, true); mWorldScene->changeToExteriorCell(position, true);
@ -3203,7 +3204,7 @@ namespace MWWorld
} }
} }
void World::spawnBloodEffect(const Ptr &ptr, const Vector3 &worldPosition) void World::spawnBloodEffect(const Ptr &ptr, const osg::Vec3f &worldPosition)
{ {
if (ptr == getPlayerPtr() && Settings::Manager::getBool("hit fader", "GUI")) if (ptr == getPlayerPtr() && Settings::Manager::getBool("hit fader", "GUI"))
return; return;
@ -3230,12 +3231,12 @@ namespace MWWorld
modelName << roll; modelName << roll;
std::string model = "meshes\\" + getFallback()->getFallbackString(modelName.str()); std::string model = "meshes\\" + getFallback()->getFallbackString(modelName.str());
//mRendering->spawnEffect(model, texture, worldPosition); mRendering->spawnEffect(model, texture, worldPosition);
} }
void World::spawnEffect(const std::string &model, const std::string &textureOverride, const Vector3 &worldPos) void World::spawnEffect(const std::string &model, const std::string &textureOverride, const osg::Vec3f &worldPos)
{ {
//mRendering->spawnEffect(model, textureOverride, worldPos); mRendering->spawnEffect(model, textureOverride, worldPos);
} }
void World::explodeSpell(const Vector3 &origin, const ESM::EffectList &effects, const Ptr &caster, ESM::RangeType rangeType, void World::explodeSpell(const Vector3 &origin, const ESM::EffectList &effects, const Ptr &caster, ESM::RangeType rangeType,
@ -3251,15 +3252,13 @@ namespace MWWorld
continue; // Not an area effect continue; // Not an area effect
// Spawn the explosion orb effect // Spawn the explosion orb effect
/*
const ESM::Static* areaStatic; const ESM::Static* areaStatic;
if (!effect->mCasting.empty()) if (!effect->mCasting.empty())
areaStatic = getStore().get<ESM::Static>().find (effect->mArea); areaStatic = getStore().get<ESM::Static>().find (effect->mArea);
else else
areaStatic = getStore().get<ESM::Static>().find ("VFX_DefaultArea"); areaStatic = getStore().get<ESM::Static>().find ("VFX_DefaultArea");
mRendering->spawnEffect("meshes\\" + areaStatic->mModel, "", origin, static_cast<float>(effectIt->mArea)); mRendering->spawnEffect("meshes\\" + areaStatic->mModel, "", osg::Vec3f(origin.x, origin.y, origin.z), static_cast<float>(effectIt->mArea));
*/
// Play explosion sound (make sure to use NoTrack, since we will delete the projectile now) // Play explosion sound (make sure to use NoTrack, since we will delete the projectile now)
static const std::string schools[] = { static const std::string schools[] = {

@ -650,9 +650,9 @@ namespace MWWorld
virtual void spawnRandomCreature(const std::string& creatureList); virtual void spawnRandomCreature(const std::string& creatureList);
/// Spawn a blood effect for \a ptr at \a worldPosition /// Spawn a blood effect for \a ptr at \a worldPosition
virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const Ogre::Vector3& worldPosition); virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition);
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const Ogre::Vector3& worldPos); virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos);
virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects, virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects,
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName); const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName);

@ -3,6 +3,8 @@
#include <stdint.h> #include <stdint.h>
#include <osg/Vec3f>
namespace ESM namespace ESM
{ {
@ -37,6 +39,11 @@ struct Position
{ {
float pos[3]; float pos[3];
float rot[3]; float rot[3];
osg::Vec3f asVec3() const
{
return osg::Vec3f(pos[0], pos[1], pos[2]);
}
}; };
#pragma pack(pop) #pragma pack(pop)

@ -89,4 +89,21 @@ namespace SceneUtil
ctrl.mSource = mToAssign; ctrl.mSource = mToAssign;
} }
FindMaxControllerLengthVisitor::FindMaxControllerLengthVisitor()
: SceneUtil::ControllerVisitor()
, mMaxLength(0)
{
}
void FindMaxControllerLengthVisitor::visit(osg::Node &, Controller &ctrl)
{
if (ctrl.mFunction)
mMaxLength = std::max(mMaxLength, ctrl.mFunction->getMaximum());
}
float FindMaxControllerLengthVisitor::getMaxLength() const
{
return mMaxLength;
}
} }

@ -72,6 +72,20 @@ namespace SceneUtil
boost::shared_ptr<ControllerSource> mToAssign; boost::shared_ptr<ControllerSource> mToAssign;
}; };
/// Finds the maximum of all controller functions in the given scene graph
class FindMaxControllerLengthVisitor : public ControllerVisitor
{
public:
FindMaxControllerLengthVisitor();
virtual void visit(osg::Node& , Controller& ctrl);
float getMaxLength() const;
private:
float mMaxLength;
};
} }
#endif #endif

Loading…
Cancel
Save