mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-19 10:09:43 +00:00
Port Animation::addEffect
This commit is contained in:
parent
083c41c950
commit
edc5cad79e
17 changed files with 294 additions and 61 deletions
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
|
#include <components/sceneutil/controller.hpp>
|
||||||
|
|
||||||
#include <osgGA/TrackballManipulator>
|
#include <osgGA/TrackballManipulator>
|
||||||
#include <osg/PositionAttitudeTransform>
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
|
||||||
|
@ -129,6 +131,9 @@ int main(int argc, char** argv)
|
||||||
Resource::TextureManager texMgr(&resourceMgr);
|
Resource::TextureManager texMgr(&resourceMgr);
|
||||||
newNode->addChild(loader.load(nif, &texMgr));
|
newNode->addChild(loader.load(nif, &texMgr));
|
||||||
|
|
||||||
|
SceneUtil::AssignControllerSourcesVisitor visitor(boost::shared_ptr<SceneUtil::FrameTimeSource>(new SceneUtil::FrameTimeSource));
|
||||||
|
newNode->accept(visitor);
|
||||||
|
|
||||||
osg::PositionAttitudeTransform* trans = new osg::PositionAttitudeTransform;
|
osg::PositionAttitudeTransform* trans = new osg::PositionAttitudeTransform;
|
||||||
root->addChild(trans);
|
root->addChild(trans);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ set(GAME_HEADER
|
||||||
source_group(game FILES ${GAME} ${GAME_HEADER})
|
source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||||
|
|
||||||
add_openmw_dir (mwrender
|
add_openmw_dir (mwrender
|
||||||
actors objects renderingmanager animation sky npcanimation
|
actors objects renderingmanager animation sky npcanimation vismask
|
||||||
# debugging camera creatureanimation activatoranimation
|
# debugging camera creatureanimation activatoranimation
|
||||||
# renderinginterface localmap occlusionquery water shadows
|
# renderinginterface localmap occlusionquery water shadows
|
||||||
# characterpreview globalmap ripplesimulation refraction
|
# characterpreview globalmap ripplesimulation refraction
|
||||||
|
|
|
@ -10,13 +10,18 @@
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
#include <components/resource/texturemanager.hpp>
|
#include <components/resource/texturemanager.hpp>
|
||||||
|
|
||||||
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
|
||||||
#include <components/sceneutil/statesetupdater.hpp>
|
#include <components/sceneutil/statesetupdater.hpp>
|
||||||
|
#include <components/sceneutil/visitor.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "vismask.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -62,6 +67,30 @@ 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
|
||||||
|
@ -83,6 +112,8 @@ namespace MWRender
|
||||||
|
|
||||||
osg::Vec3f Animation::runAnimation(float duration)
|
osg::Vec3f Animation::runAnimation(float duration)
|
||||||
{
|
{
|
||||||
|
updateEffects(duration);
|
||||||
|
|
||||||
return osg::Vec3f();
|
return osg::Vec3f();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +178,133 @@ namespace MWRender
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, std::string texture)
|
||||||
|
{
|
||||||
|
// Early out if we already have this effect
|
||||||
|
for (std::vector<EffectParams>::iterator it = mEffects.begin(); it != mEffects.end(); ++it)
|
||||||
|
if (it->mLoop && loop && it->mEffectId == effectId && it->mBoneName == bonename)
|
||||||
|
return;
|
||||||
|
|
||||||
|
EffectParams params;
|
||||||
|
params.mModelName = model;
|
||||||
|
osg::ref_ptr<osg::Group> parentNode;
|
||||||
|
if (bonename.empty())
|
||||||
|
parentNode = mObjectRoot->asGroup();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SceneUtil::FindByNameVisitor visitor(bonename);
|
||||||
|
mObjectRoot->accept(visitor);
|
||||||
|
if (!visitor.mFoundNode)
|
||||||
|
throw std::runtime_error("Can't find bone " + bonename);
|
||||||
|
parentNode = visitor.mFoundNode;
|
||||||
|
}
|
||||||
|
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->createInstance(model, parentNode);
|
||||||
|
params.mObjects = PartHolderPtr(new PartHolder(node));
|
||||||
|
|
||||||
|
FindMaxControllerLengthVisitor findMaxLengthVisitor;
|
||||||
|
node->accept(findMaxLengthVisitor);
|
||||||
|
|
||||||
|
params.mMaxControllerLength = findMaxLengthVisitor.getMaxLength();
|
||||||
|
|
||||||
|
node->setNodeMask(Mask_Effect);
|
||||||
|
|
||||||
|
params.mLoop = loop;
|
||||||
|
params.mEffectId = effectId;
|
||||||
|
params.mBoneName = bonename;
|
||||||
|
|
||||||
|
params.mAnimTime = boost::shared_ptr<EffectAnimationTime>(new EffectAnimationTime);
|
||||||
|
|
||||||
|
SceneUtil::AssignControllerSourcesVisitor assignVisitor(boost::shared_ptr<SceneUtil::ControllerSource>(params.mAnimTime));
|
||||||
|
node->accept(assignVisitor);
|
||||||
|
|
||||||
|
if (!texture.empty())
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
|
||||||
|
mEffects.push_back(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::removeEffect(int effectId)
|
||||||
|
{
|
||||||
|
for (std::vector<EffectParams>::iterator it = mEffects.begin(); it != mEffects.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->mEffectId == effectId)
|
||||||
|
{
|
||||||
|
mEffects.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::getLoopingEffects(std::vector<int> &out)
|
||||||
|
{
|
||||||
|
for (std::vector<EffectParams>::iterator it = mEffects.begin(); it != mEffects.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->mLoop)
|
||||||
|
out.push_back(it->mEffectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::updateEffects(float duration)
|
||||||
|
{
|
||||||
|
for (std::vector<EffectParams>::iterator it = mEffects.begin(); it != mEffects.end(); )
|
||||||
|
{
|
||||||
|
it->mAnimTime->addTime(duration);
|
||||||
|
|
||||||
|
if (it->mAnimTime->getTime() >= it->mMaxControllerLength)
|
||||||
|
{
|
||||||
|
if (it->mLoop)
|
||||||
|
{
|
||||||
|
// Start from the beginning again; carry over the remainder
|
||||||
|
// Not sure if this is actually needed, the controller function might already handle loops
|
||||||
|
float remainder = it->mAnimTime->getTime() - it->mMaxControllerLength;
|
||||||
|
it->mAnimTime->resetTime(remainder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it = mEffects.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Animation::EffectAnimationTime::getValue(osg::NodeVisitor*)
|
||||||
|
{
|
||||||
|
return mTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::EffectAnimationTime::addTime(float duration)
|
||||||
|
{
|
||||||
|
mTime += duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animation::EffectAnimationTime::resetTime(float time)
|
||||||
|
{
|
||||||
|
mTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Animation::EffectAnimationTime::getTime() const
|
||||||
|
{
|
||||||
|
return mTime;
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr &ptr, const std::string &model, Resource::ResourceSystem* resourceSystem)
|
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr &ptr, const std::string &model, Resource::ResourceSystem* resourceSystem)
|
||||||
|
@ -159,11 +317,6 @@ namespace MWRender
|
||||||
if (!ptr.getClass().getEnchantment(ptr).empty())
|
if (!ptr.getClass().getEnchantment(ptr).empty())
|
||||||
addGlow(mObjectRoot, getEnchantmentColor(ptr));
|
addGlow(mObjectRoot, getEnchantmentColor(ptr));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// No model given. Create an object root anyway, so that lights can be added to it if needed.
|
|
||||||
//mObjectRoot = NifOgre::ObjectScenePtr (new NifOgre::ObjectScene(mInsert->getCreator()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,17 +61,18 @@ protected:
|
||||||
virtual void setValue(Ogre::Real value);
|
virtual void setValue(Ogre::Real value);
|
||||||
};
|
};
|
||||||
|
|
||||||
class EffectAnimationTime : public Ogre::ControllerValue<Ogre::Real>
|
class EffectAnimationTime : public SceneUtil::ControllerSource
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
float mTime;
|
float mTime;
|
||||||
public:
|
public:
|
||||||
EffectAnimationTime() : mTime(0) { }
|
virtual float getValue(osg::NodeVisitor* nv);
|
||||||
void addTime(float time) { mTime += time; }
|
|
||||||
void resetTime(float value) { mTime = value; }
|
|
||||||
|
|
||||||
virtual Ogre::Real getValue() const;
|
void addTime(float duration);
|
||||||
virtual void setValue(Ogre::Real value);
|
void resetTime(float time);
|
||||||
|
float getTime() const;
|
||||||
|
|
||||||
|
EffectAnimationTime() : mTime(0) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class NullAnimationTime : public SceneUtil::ControllerSource
|
class NullAnimationTime : public SceneUtil::ControllerSource
|
||||||
|
@ -124,6 +125,44 @@ protected:
|
||||||
|
|
||||||
Resource::ResourceSystem* mResourceSystem;
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
|
|
||||||
|
/// @brief Detaches the node from its parent when the object goes out of scope.
|
||||||
|
class PartHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PartHolder(osg::ref_ptr<osg::Node> node)
|
||||||
|
: mNode(node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~PartHolder()
|
||||||
|
{
|
||||||
|
if (mNode->getNumParents())
|
||||||
|
mNode->getParent(0)->removeChild(mNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Node> getNode()
|
||||||
|
{
|
||||||
|
return mNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<osg::Node> mNode;
|
||||||
|
};
|
||||||
|
typedef boost::shared_ptr<PartHolder> PartHolderPtr;
|
||||||
|
|
||||||
|
struct EffectParams
|
||||||
|
{
|
||||||
|
std::string mModelName; // Just here so we don't add the same effect twice
|
||||||
|
PartHolderPtr mObjects;
|
||||||
|
boost::shared_ptr<EffectAnimationTime> mAnimTime;
|
||||||
|
float mMaxControllerLength;
|
||||||
|
int mEffectId;
|
||||||
|
bool mLoop;
|
||||||
|
std::string mBoneName;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<EffectParams> mEffects;
|
||||||
|
|
||||||
/* Sets the appropriate animations on the bone groups based on priority.
|
/* Sets the appropriate animations on the bone groups based on priority.
|
||||||
*/
|
*/
|
||||||
//void resetActiveGroups();
|
//void resetActiveGroups();
|
||||||
|
@ -192,12 +231,12 @@ public:
|
||||||
* @param loop Loop the effect. If false, it is removed automatically after it finishes playing. If true,
|
* @param loop Loop the effect. If false, it is removed automatically after it finishes playing. If true,
|
||||||
* you need to remove it manually using removeEffect when the effect should end.
|
* you need to remove it manually using removeEffect when the effect should end.
|
||||||
* @param bonename Bone to attach to, or empty string to use the scene node instead
|
* @param bonename Bone to attach to, or empty string to use the scene node instead
|
||||||
* @param texture override the texture specified in the model's materials
|
* @param texture override the texture specified in the model's materials - if empty, do not override
|
||||||
* @note Will not add an effect twice.
|
* @note Will not add an effect twice.
|
||||||
*/
|
*/
|
||||||
//void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", std::string texture = "");
|
void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", std::string texture = "");
|
||||||
//void removeEffect (int effectId);
|
void removeEffect (int effectId);
|
||||||
//void getLoopingEffects (std::vector<int>& out);
|
void getLoopingEffects (std::vector<int>& out);
|
||||||
|
|
||||||
//void updatePtr(const MWWorld::Ptr &ptr);
|
//void updatePtr(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
|
@ -273,6 +312,9 @@ public:
|
||||||
//float getVelocity(const std::string &groupname) const;
|
//float getVelocity(const std::string &groupname) const;
|
||||||
|
|
||||||
virtual osg::Vec3f runAnimation(float duration);
|
virtual osg::Vec3f runAnimation(float duration);
|
||||||
|
|
||||||
|
/// This is typically called as part of runAnimation, but may be called manually if needed.
|
||||||
|
void updateEffects(float duration);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectAnimation : public Animation {
|
class ObjectAnimation : public Animation {
|
||||||
|
|
|
@ -587,12 +587,15 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, int group, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor)
|
Animation::PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, int group, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->createInstance(model);
|
osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->createInstance(model);
|
||||||
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, bonename);
|
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, bonename);
|
||||||
if (enchantedGlow)
|
if (enchantedGlow)
|
||||||
addGlow(attached, *glowColor);
|
addGlow(attached, *glowColor);
|
||||||
|
|
||||||
|
// TODO: set group userdata for inventory picking
|
||||||
|
|
||||||
return PartHolderPtr(new PartHolder(attached));
|
return PartHolderPtr(new PartHolder(attached));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,26 +50,6 @@ public:
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// @brief Detaches the node from its parent when the object goes out of scope.
|
|
||||||
class PartHolder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PartHolder(osg::ref_ptr<osg::Node> node)
|
|
||||||
: mNode(node)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~PartHolder()
|
|
||||||
{
|
|
||||||
if (mNode->getNumParents())
|
|
||||||
mNode->getParent(0)->removeChild(mNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
osg::ref_ptr<osg::Node> mNode;
|
|
||||||
};
|
|
||||||
typedef boost::shared_ptr<PartHolder> PartHolderPtr;
|
|
||||||
|
|
||||||
class NpcAnimation : public Animation, public WeaponAnimation, public MWWorld::InventoryStoreListener
|
class NpcAnimation : public Animation, public WeaponAnimation, public MWWorld::InventoryStoreListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -246,7 +246,7 @@ void Objects::removeCell(const MWWorld::CellStore* store)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::update(float dt, Ogre::Camera* camera)
|
void Objects::update(float dt)
|
||||||
{
|
{
|
||||||
PtrAnimationMap::const_iterator it = mObjects.begin();
|
PtrAnimationMap::const_iterator it = mObjects.begin();
|
||||||
for(;it != mObjects.end();++it)
|
for(;it != mObjects.end();++it)
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
|
|
||||||
Animation* getAnimation(const MWWorld::Ptr &ptr);
|
Animation* getAnimation(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
void update (float dt, Ogre::Camera* camera);
|
void update (float dt);
|
||||||
///< per-frame update
|
///< per-frame update
|
||||||
|
|
||||||
//Ogre::AxisAlignedBox getDimensions(MWWorld::CellStore*);
|
//Ogre::AxisAlignedBox getDimensions(MWWorld::CellStore*);
|
||||||
|
|
|
@ -160,4 +160,9 @@ namespace MWRender
|
||||||
return mSky.get();
|
return mSky.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingManager::update(float dt, bool paused)
|
||||||
|
{
|
||||||
|
mObjects->update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ namespace MWRender
|
||||||
|
|
||||||
osg::Vec3f getEyePos();
|
osg::Vec3f getEyePos();
|
||||||
|
|
||||||
|
void update(float dt, bool paused);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
osgViewer::Viewer& mViewer;
|
osgViewer::Viewer& mViewer;
|
||||||
osg::ref_ptr<osg::Group> mRootNode;
|
osg::ref_ptr<osg::Group> mRootNode;
|
||||||
|
|
17
apps/openmw/mwrender/vismask.hpp
Normal file
17
apps/openmw/mwrender/vismask.hpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef OPENMW_MWRENDER_VISMASK_H
|
||||||
|
#define OPENMW_MWRENDER_VISMASK_H
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Node masks used for controlling visibility of game objects.
|
||||||
|
enum VisMask
|
||||||
|
{
|
||||||
|
Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors
|
||||||
|
|
||||||
|
Mask_Effect = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -180,7 +180,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//mRendering.update (duration, paused);
|
mRendering.update (duration, paused);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::unloadCell (CellStoreCollection::iterator iter)
|
void Scene::unloadCell (CellStoreCollection::iterator iter)
|
||||||
|
|
|
@ -1606,13 +1606,13 @@ namespace MWWorld
|
||||||
goToJail();
|
goToJail();
|
||||||
|
|
||||||
updateWeather(duration, paused);
|
updateWeather(duration, paused);
|
||||||
/*
|
|
||||||
|
|
||||||
if (!paused)
|
//if (!paused)
|
||||||
doPhysics (duration);
|
// doPhysics (duration);
|
||||||
|
|
||||||
mWorldScene->update (duration, paused);
|
mWorldScene->update (duration, paused);
|
||||||
|
|
||||||
|
/*
|
||||||
performUpdateSceneQueries ();
|
performUpdateSceneQueries ();
|
||||||
|
|
||||||
updateWindowManager ();
|
updateWindowManager ();
|
||||||
|
|
|
@ -64,6 +64,11 @@ float ControllerFunction::calculate(float value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ControllerFunction::getMaximum() const
|
||||||
|
{
|
||||||
|
return mStopTime;
|
||||||
|
}
|
||||||
|
|
||||||
KeyframeController::KeyframeController()
|
KeyframeController::KeyframeController()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,8 @@ namespace NifOsg
|
||||||
ControllerFunction(const Nif::Controller *ctrl);
|
ControllerFunction(const Nif::Controller *ctrl);
|
||||||
|
|
||||||
float calculate(float value);
|
float calculate(float value);
|
||||||
|
|
||||||
|
virtual float getMaximum() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GeomMorpherController : public osg::Drawable::UpdateCallback, public SceneUtil::Controller, public ValueInterpolator
|
class GeomMorpherController : public osg::Drawable::UpdateCallback, public SceneUtil::Controller, public ValueInterpolator
|
||||||
|
|
|
@ -32,31 +32,26 @@ namespace SceneUtil
|
||||||
return nv->getFrameStamp()->getSimulationTime();
|
return nv->getFrameStamp()->getSimulationTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignControllerSourcesVisitor::AssignControllerSourcesVisitor()
|
ControllerVisitor::ControllerVisitor()
|
||||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignControllerSourcesVisitor::AssignControllerSourcesVisitor(boost::shared_ptr<ControllerSource> toAssign)
|
void ControllerVisitor::apply(osg::Node &node)
|
||||||
: mToAssign(toAssign)
|
|
||||||
, osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssignControllerSourcesVisitor::apply(osg::Node &node)
|
|
||||||
{
|
{
|
||||||
osg::NodeCallback* callback = node.getUpdateCallback();
|
osg::NodeCallback* callback = node.getUpdateCallback();
|
||||||
while (callback)
|
while (callback)
|
||||||
{
|
{
|
||||||
if (Controller* ctrl = dynamic_cast<Controller*>(callback))
|
if (Controller* ctrl = dynamic_cast<Controller*>(callback))
|
||||||
assign(node, *ctrl);
|
visit(node, *ctrl);
|
||||||
if (CompositeStateSetUpdater* composite = dynamic_cast<CompositeStateSetUpdater*>(callback))
|
if (CompositeStateSetUpdater* composite = dynamic_cast<CompositeStateSetUpdater*>(callback))
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<composite->getNumControllers(); ++i)
|
for (unsigned int i=0; i<composite->getNumControllers(); ++i)
|
||||||
{
|
{
|
||||||
StateSetUpdater* statesetcontroller = composite->getController(i);
|
StateSetUpdater* statesetcontroller = composite->getController(i);
|
||||||
if (Controller* ctrl = dynamic_cast<Controller*>(statesetcontroller))
|
if (Controller* ctrl = dynamic_cast<Controller*>(statesetcontroller))
|
||||||
assign(node, *ctrl);
|
visit(node, *ctrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,18 +61,29 @@ namespace SceneUtil
|
||||||
traverse(node);
|
traverse(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignControllerSourcesVisitor::apply(osg::Geode &geode)
|
void ControllerVisitor::apply(osg::Geode &geode)
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
||||||
{
|
{
|
||||||
osg::Drawable* drw = geode.getDrawable(i);
|
osg::Drawable* drw = geode.getDrawable(i);
|
||||||
osg::Drawable::UpdateCallback* callback = drw->getUpdateCallback();
|
osg::Drawable::UpdateCallback* callback = drw->getUpdateCallback();
|
||||||
if (Controller* ctrl = dynamic_cast<Controller*>(callback))
|
if (Controller* ctrl = dynamic_cast<Controller*>(callback))
|
||||||
assign(geode, *ctrl);
|
visit(geode, *ctrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignControllerSourcesVisitor::assign(osg::Node&, Controller &ctrl)
|
AssignControllerSourcesVisitor::AssignControllerSourcesVisitor()
|
||||||
|
: ControllerVisitor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignControllerSourcesVisitor::AssignControllerSourcesVisitor(boost::shared_ptr<ControllerSource> toAssign)
|
||||||
|
: ControllerVisitor()
|
||||||
|
, mToAssign(toAssign)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssignControllerSourcesVisitor::visit(osg::Node&, Controller &ctrl)
|
||||||
{
|
{
|
||||||
if (!ctrl.mSource.get())
|
if (!ctrl.mSource.get())
|
||||||
ctrl.mSource = mToAssign;
|
ctrl.mSource = mToAssign;
|
||||||
|
|
|
@ -25,6 +25,10 @@ namespace SceneUtil
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual float calculate(float input) = 0;
|
virtual float calculate(float input) = 0;
|
||||||
|
|
||||||
|
/// Get the "stop time" of the controller function, typically the maximum of the calculate() function.
|
||||||
|
/// May not be meaningful for all types of controller functions.
|
||||||
|
virtual float getMaximum() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Controller
|
class Controller
|
||||||
|
@ -42,18 +46,27 @@ namespace SceneUtil
|
||||||
boost::shared_ptr<ControllerFunction> mFunction;
|
boost::shared_ptr<ControllerFunction> mFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AssignControllerSourcesVisitor : public osg::NodeVisitor
|
/// Pure virtual base class - visit() all controllers that are attached as UpdateCallbacks in a scene graph.
|
||||||
|
class ControllerVisitor : public osg::NodeVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ControllerVisitor();
|
||||||
|
|
||||||
|
virtual void apply(osg::Node& node);
|
||||||
|
virtual void apply(osg::Geode& geode);
|
||||||
|
|
||||||
|
virtual void visit(osg::Node& node, Controller& ctrl) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssignControllerSourcesVisitor : public ControllerVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AssignControllerSourcesVisitor();
|
AssignControllerSourcesVisitor();
|
||||||
AssignControllerSourcesVisitor(boost::shared_ptr<ControllerSource> toAssign);
|
AssignControllerSourcesVisitor(boost::shared_ptr<ControllerSource> toAssign);
|
||||||
|
|
||||||
virtual void apply(osg::Node& node);
|
|
||||||
virtual void apply(osg::Geode& geode);
|
|
||||||
|
|
||||||
/// Assign the wanted ControllerSource. May be overriden in derived classes.
|
/// Assign the wanted ControllerSource. May be overriden in derived classes.
|
||||||
/// By default assigns the ControllerSource passed to the constructor of this class if no ControllerSource is assigned to that controller yet.
|
/// By default assigns the ControllerSource passed to the constructor of this class if no ControllerSource is assigned to that controller yet.
|
||||||
virtual void assign(osg::Node& node, Controller& ctrl);
|
virtual void visit(osg::Node& node, Controller& ctrl);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<ControllerSource> mToAssign;
|
boost::shared_ptr<ControllerSource> mToAssign;
|
||||||
|
|
Loading…
Reference in a new issue