Support animation groups for Light and Door objects (Fixes #2039)

moveref
scrawl 10 years ago
parent 019cd96719
commit d55fe43fc9

@ -8,6 +8,7 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
@ -22,7 +23,7 @@
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp" #include "../mwrender/actors.hpp"
#include "../mwrender/renderinginterface.hpp" #include "../mwrender/renderinginterface.hpp"
namespace namespace
@ -51,7 +52,8 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
renderingInterface.getObjects().insertModel(ptr, model); MWRender::Actors& actors = renderingInterface.getActors();
actors.insertActivator(ptr);
} }
} }
@ -70,6 +72,8 @@ namespace MWClass
MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState); MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState);
} }
} }
MWBase::Environment::get().getMechanicsManager()->add(ptr);
} }
std::string Door::getModel(const MWWorld::Ptr &ptr) const std::string Door::getModel(const MWWorld::Ptr &ptr) const

@ -8,6 +8,7 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
@ -22,6 +23,7 @@
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp" #include "../mwrender/objects.hpp"
#include "../mwrender/actors.hpp"
#include "../mwrender/renderinginterface.hpp" #include "../mwrender/renderinginterface.hpp"
namespace namespace
@ -54,13 +56,12 @@ namespace MWClass
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
const std::string model = getModel(ptr);
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
// Insert even if model is empty, so that the light is added // Insert even if model is empty, so that the light is added
renderingInterface.getObjects().insertModel(ptr, model, false, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)); MWRender::Actors& actors = renderingInterface.getActors();
actors.insertActivator(ptr, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
} }
void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
@ -78,6 +79,8 @@ namespace MWClass
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop); MWBase::SoundManager::Play_Loop);
MWBase::Environment::get().getMechanicsManager()->add(ptr);
} }
std::string Light::getModel(const MWWorld::Ptr &ptr) const std::string Light::getModel(const MWWorld::Ptr &ptr) const

@ -1,5 +1,8 @@
#include "activatoranimation.hpp" #include "activatoranimation.hpp"
#include <OgreSceneNode.h>
#include <OgreParticleSystem.h>
#include <components/esm/loadacti.hpp> #include <components/esm/loadacti.hpp>
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -27,6 +30,28 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
addAnimSource(model); addAnimSource(model);
} }
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()));
}
}
void ActivatorAnimation::addLight(const ESM::Light *light)
{
addExtraLight(mInsert->getCreator(), mObjectRoot, light);
}
void ActivatorAnimation::removeParticles()
{
for (unsigned int i=0; i<mObjectRoot->mParticles.size(); ++i)
{
// Don't destroyParticleSystem, the ParticleSystemController is still holding a pointer to it.
// Don't setVisible, this could conflict with a VisController.
// The following will remove all spawned particles, then set the speed factor to zero so that no new ones will be spawned.
mObjectRoot->mParticles[i]->setSpeedFactor(0.f);
mObjectRoot->mParticles[i]->clear();
}
} }
} }

@ -15,6 +15,9 @@ namespace MWRender
public: public:
ActivatorAnimation(const MWWorld::Ptr& ptr); ActivatorAnimation(const MWWorld::Ptr& ptr);
virtual ~ActivatorAnimation(); virtual ~ActivatorAnimation();
void addLight(const ESM::Light *light);
void removeParticles();
}; };
} }

@ -83,10 +83,19 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr, bool weaponsShields)
mAllActors[ptr] = anim; mAllActors[ptr] = anim;
mRendering->addWaterRippleEmitter (ptr); mRendering->addWaterRippleEmitter (ptr);
} }
void Actors::insertActivator (const MWWorld::Ptr& ptr) void Actors::insertActivator (const MWWorld::Ptr& ptr, bool addLight)
{ {
insertBegin(ptr); insertBegin(ptr);
ActivatorAnimation* anim = new ActivatorAnimation(ptr); ActivatorAnimation* anim = new ActivatorAnimation(ptr);
if(ptr.getTypeName() == typeid(ESM::Light).name())
{
if (addLight)
anim->addLight(ptr.get<ESM::Light>()->mBase);
else
anim->removeParticles();
}
delete mAllActors[ptr]; delete mAllActors[ptr];
mAllActors[ptr] = anim; mAllActors[ptr] = anim;
} }

@ -41,7 +41,7 @@ namespace MWRender
void insertNPC(const MWWorld::Ptr& ptr); void insertNPC(const MWWorld::Ptr& ptr);
void insertCreature (const MWWorld::Ptr& ptr, bool weaponsShields); void insertCreature (const MWWorld::Ptr& ptr, bool weaponsShields);
void insertActivator (const MWWorld::Ptr& ptr); void insertActivator (const MWWorld::Ptr& ptr, bool addLight=false);
bool deleteObject (const MWWorld::Ptr& ptr); bool deleteObject (const MWWorld::Ptr& ptr);
///< \return found? ///< \return found?

@ -1507,23 +1507,6 @@ ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &mod
} }
} }
void ObjectAnimation::addLight(const ESM::Light *light)
{
addExtraLight(mInsert->getCreator(), mObjectRoot, light);
}
void ObjectAnimation::removeParticles()
{
for (unsigned int i=0; i<mObjectRoot->mParticles.size(); ++i)
{
// Don't destroyParticleSystem, the ParticleSystemController is still holding a pointer to it.
// Don't setVisible, this could conflict with a VisController.
// The following will remove all spawned particles, then set the speed factor to zero so that no new ones will be spawned.
mObjectRoot->mParticles[i]->setSpeedFactor(0.f);
mObjectRoot->mParticles[i]->clear();
}
}
class FindEntityTransparency { class FindEntityTransparency {
public: public:

@ -346,9 +346,6 @@ class ObjectAnimation : public Animation {
public: public:
ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model); ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model);
void addLight(const ESM::Light *light);
void removeParticles();
bool canBatch() const; bool canBatch() const;
void fillBatch(Ogre::StaticGeometry *sg); void fillBatch(Ogre::StaticGeometry *sg);
}; };

@ -73,20 +73,12 @@ void Objects::insertBegin(const MWWorld::Ptr& ptr)
ptr.getRefData().setBaseNode(insert); ptr.getRefData().setBaseNode(insert);
} }
void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool batch, bool addLight) void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool batch)
{ {
insertBegin(ptr); insertBegin(ptr);
std::auto_ptr<ObjectAnimation> anim(new ObjectAnimation(ptr, mesh)); std::auto_ptr<ObjectAnimation> anim(new ObjectAnimation(ptr, mesh));
if(ptr.getTypeName() == typeid(ESM::Light).name())
{
if (addLight)
anim->addLight(ptr.get<ESM::Light>()->mBase);
else
anim->removeParticles();
}
if (!mesh.empty()) if (!mesh.empty())
{ {
Ogre::AxisAlignedBox bounds = anim->getWorldBounds(); Ogre::AxisAlignedBox bounds = anim->getWorldBounds();

@ -41,7 +41,7 @@ public:
, mRootNode(NULL) , mRootNode(NULL)
{} {}
~Objects(){} ~Objects(){}
void insertModel(const MWWorld::Ptr& ptr, const std::string &model, bool batch=false, bool addLight=false); void insertModel(const MWWorld::Ptr& ptr, const std::string &model, bool batch=false);
ObjectAnimation* getAnimation(const MWWorld::Ptr &ptr); ObjectAnimation* getAnimation(const MWWorld::Ptr &ptr);

Loading…
Cancel
Save