mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-02 03:15:35 +00:00
Treat activators as actors for rendering and mechanics
Kinda hacky, but it's the only way to get animated activators (flags, silt striders, etc) to work properly.
This commit is contained in:
parent
d2fc3c7b33
commit
94b93227d3
9 changed files with 120 additions and 9 deletions
|
@ -14,8 +14,8 @@ set(GAME_HEADER
|
|||
source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||
|
||||
add_openmw_dir (mwrender
|
||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
||||
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
|
||||
renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation
|
||||
actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
|
||||
compositors characterpreview externalrendering globalmap videoplayer
|
||||
)
|
||||
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld//cellstore.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwrender/actors.hpp"
|
||||
#include "../mwrender/renderinginterface.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
@ -21,9 +22,8 @@ namespace MWClass
|
|||
{
|
||||
const std::string model = getModel(ptr);
|
||||
if (!model.empty()) {
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
|
||||
objects.insertMesh(ptr, model);
|
||||
MWRender::Actors& actors = renderingInterface.getActors();
|
||||
actors.insertActivator(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ namespace MWClass
|
|||
const std::string model = getModel(ptr);
|
||||
if(!model.empty())
|
||||
physics.addObject(ptr);
|
||||
MWBase::Environment::get().getMechanicsManager()->addActor(ptr);
|
||||
}
|
||||
|
||||
std::string Activator::getModel(const MWWorld::Ptr &ptr) const
|
||||
|
|
|
@ -166,7 +166,9 @@ namespace MWMechanics
|
|||
void Actors::addActor (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
|
||||
if(!MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead())
|
||||
/* Kind of a hack. Activators need a character controller to manage an idle state. */
|
||||
if(ptr.getTypeName() == typeid(ESM::Activator).name() ||
|
||||
!MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead())
|
||||
mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle)));
|
||||
else
|
||||
mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Dead)));
|
||||
|
@ -203,6 +205,11 @@ namespace MWMechanics
|
|||
PtrControllerMap::iterator iter(mActors.begin());
|
||||
while(iter != mActors.end())
|
||||
{
|
||||
if(iter->first.getTypeName() == typeid(ESM::Activator).name())
|
||||
{
|
||||
iter++;
|
||||
continue;
|
||||
}
|
||||
if(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead())
|
||||
{
|
||||
if(iter->second.getState() == CharState_Dead)
|
||||
|
@ -267,7 +274,10 @@ namespace MWMechanics
|
|||
void Actors::restoreDynamicStats()
|
||||
{
|
||||
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
||||
calculateRestoration(iter->first, 3600);
|
||||
{
|
||||
if(iter->first.getTypeName() != typeid(ESM::Activator).name())
|
||||
calculateRestoration(iter->first, 3600);
|
||||
}
|
||||
}
|
||||
|
||||
int Actors::countDeaths (const std::string& id) const
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "../mwrender/animation.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
|
|
64
apps/openmw/mwrender/activatoranimation.cpp
Normal file
64
apps/openmw/mwrender/activatoranimation.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "activatoranimation.hpp"
|
||||
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreSubEntity.h>
|
||||
|
||||
#include "renderconst.hpp"
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
ActivatorAnimation::~ActivatorAnimation()
|
||||
{
|
||||
}
|
||||
|
||||
ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
|
||||
: Animation(ptr)
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Activator> *ref = mPtr.get<ESM::Activator>();
|
||||
|
||||
assert (ref->mBase != NULL);
|
||||
if(!ref->mBase->mModel.empty())
|
||||
{
|
||||
std::string mesh = "meshes\\" + ref->mBase->mModel;
|
||||
|
||||
createEntityList(mPtr.getRefData().getBaseNode(), mesh);
|
||||
for(size_t i = 0;i < mEntityList.mEntities.size();i++)
|
||||
{
|
||||
Ogre::Entity *ent = mEntityList.mEntities[i];
|
||||
|
||||
bool transparent = false;
|
||||
for (unsigned int j=0;j < ent->getNumSubEntities() && !transparent; ++j)
|
||||
{
|
||||
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
|
||||
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
||||
while (techIt.hasMoreElements() && !transparent)
|
||||
{
|
||||
Ogre::Technique* tech = techIt.getNext();
|
||||
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
|
||||
while (passIt.hasMoreElements() && !transparent)
|
||||
{
|
||||
Ogre::Pass* pass = passIt.getNext();
|
||||
|
||||
if (pass->getDepthWriteEnabled() == false)
|
||||
transparent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ent->setVisibilityFlags(RV_Misc);
|
||||
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActivatorAnimation::runAnimation(float timepassed)
|
||||
{
|
||||
// Placeholder
|
||||
|
||||
Animation::runAnimation(timepassed);
|
||||
}
|
||||
|
||||
}
|
23
apps/openmw/mwrender/activatoranimation.hpp
Normal file
23
apps/openmw/mwrender/activatoranimation.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _GAME_RENDER_ACTIVATORANIMATION_H
|
||||
#define _GAME_RENDER_ACTIVATORANIMATION_H
|
||||
|
||||
#include "animation.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Ptr;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class ActivatorAnimation : public Animation
|
||||
{
|
||||
public:
|
||||
ActivatorAnimation(const MWWorld::Ptr& ptr);
|
||||
virtual ~ActivatorAnimation();
|
||||
|
||||
virtual void runAnimation(float timepassed);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,6 +6,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "activatoranimation.hpp"
|
||||
#include "creatureanimation.hpp"
|
||||
#include "npcanimation.hpp"
|
||||
|
||||
|
@ -78,6 +79,13 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr)
|
|||
delete mAllActors[ptr];
|
||||
mAllActors[ptr] = anim;
|
||||
}
|
||||
void Actors::insertActivator (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
insertBegin(ptr);
|
||||
ActivatorAnimation* anim = new ActivatorAnimation(ptr);
|
||||
delete mAllActors[ptr];
|
||||
mAllActors[ptr] = anim;
|
||||
}
|
||||
|
||||
bool Actors::deleteObject (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
|
|
|
@ -31,8 +31,9 @@ namespace MWRender
|
|||
|
||||
void setMwRoot(Ogre::SceneNode* root);
|
||||
void insertBegin (const MWWorld::Ptr& ptr);
|
||||
void insertCreature (const MWWorld::Ptr& ptr);
|
||||
void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv);
|
||||
void insertCreature (const MWWorld::Ptr& ptr);
|
||||
void insertActivator (const MWWorld::Ptr& ptr);
|
||||
bool deleteObject (const MWWorld::Ptr& ptr);
|
||||
///< \return found?
|
||||
|
||||
|
|
|
@ -200,6 +200,9 @@ void Animation::playGroup(std::string groupname, int mode, int loops)
|
|||
GroupTimes times;
|
||||
|
||||
try {
|
||||
if(!mEntityList.mSkelBase)
|
||||
throw std::runtime_error("Attempting to animate an inanimate object");
|
||||
|
||||
std::transform(groupname.begin(), groupname.end(), groupname.begin(), ::tolower);
|
||||
times.mAnimState = mEntityList.mSkelBase->getAnimationState(groupname);
|
||||
times.mLoops = loops;
|
||||
|
|
Loading…
Reference in a new issue