forked from mirror/openmw-tes3mp
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})
|
source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||||
|
|
||||||
add_openmw_dir (mwrender
|
add_openmw_dir (mwrender
|
||||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation
|
||||||
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
|
actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
|
||||||
compositors characterpreview externalrendering globalmap videoplayer
|
compositors characterpreview externalrendering globalmap videoplayer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld//cellstore.hpp"
|
#include "../mwworld//cellstore.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
|
|
||||||
#include "../mwrender/objects.hpp"
|
#include "../mwrender/actors.hpp"
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
|
||||||
#include "../mwgui/tooltips.hpp"
|
#include "../mwgui/tooltips.hpp"
|
||||||
|
@ -21,9 +22,8 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
if (!model.empty()) {
|
if (!model.empty()) {
|
||||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
MWRender::Actors& actors = renderingInterface.getActors();
|
||||||
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
|
actors.insertActivator(ptr);
|
||||||
objects.insertMesh(ptr, model);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ namespace MWClass
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
if(!model.empty())
|
if(!model.empty())
|
||||||
physics.addObject(ptr);
|
physics.addObject(ptr);
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->addActor(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Activator::getModel(const MWWorld::Ptr &ptr) const
|
std::string Activator::getModel(const MWWorld::Ptr &ptr) const
|
||||||
|
|
|
@ -166,7 +166,9 @@ namespace MWMechanics
|
||||||
void Actors::addActor (const MWWorld::Ptr& ptr)
|
void Actors::addActor (const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(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)));
|
mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle)));
|
||||||
else
|
else
|
||||||
mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Dead)));
|
mActors.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Dead)));
|
||||||
|
@ -203,6 +205,11 @@ namespace MWMechanics
|
||||||
PtrControllerMap::iterator iter(mActors.begin());
|
PtrControllerMap::iterator iter(mActors.begin());
|
||||||
while(iter != mActors.end())
|
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(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead())
|
||||||
{
|
{
|
||||||
if(iter->second.getState() == CharState_Dead)
|
if(iter->second.getState() == CharState_Dead)
|
||||||
|
@ -267,7 +274,10 @@ namespace MWMechanics
|
||||||
void Actors::restoreDynamicStats()
|
void Actors::restoreDynamicStats()
|
||||||
{
|
{
|
||||||
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
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
|
int Actors::countDeaths (const std::string& id) const
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "../mwrender/animation.hpp"
|
#include "../mwrender/animation.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
namespace MWMechanics
|
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 "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
#include "animation.hpp"
|
#include "animation.hpp"
|
||||||
|
#include "activatoranimation.hpp"
|
||||||
#include "creatureanimation.hpp"
|
#include "creatureanimation.hpp"
|
||||||
#include "npcanimation.hpp"
|
#include "npcanimation.hpp"
|
||||||
|
|
||||||
|
@ -78,6 +79,13 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr)
|
||||||
delete mAllActors[ptr];
|
delete mAllActors[ptr];
|
||||||
mAllActors[ptr] = anim;
|
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)
|
bool Actors::deleteObject (const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,8 +31,9 @@ namespace MWRender
|
||||||
|
|
||||||
void setMwRoot(Ogre::SceneNode* root);
|
void setMwRoot(Ogre::SceneNode* root);
|
||||||
void insertBegin (const MWWorld::Ptr& ptr);
|
void insertBegin (const MWWorld::Ptr& ptr);
|
||||||
void insertCreature (const MWWorld::Ptr& ptr);
|
|
||||||
void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv);
|
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);
|
bool deleteObject (const MWWorld::Ptr& ptr);
|
||||||
///< \return found?
|
///< \return found?
|
||||||
|
|
||||||
|
|
|
@ -200,6 +200,9 @@ void Animation::playGroup(std::string groupname, int mode, int loops)
|
||||||
GroupTimes times;
|
GroupTimes times;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if(!mEntityList.mSkelBase)
|
||||||
|
throw std::runtime_error("Attempting to animate an inanimate object");
|
||||||
|
|
||||||
std::transform(groupname.begin(), groupname.end(), groupname.begin(), ::tolower);
|
std::transform(groupname.begin(), groupname.end(), groupname.begin(), ::tolower);
|
||||||
times.mAnimState = mEntityList.mSkelBase->getAnimationState(groupname);
|
times.mAnimState = mEntityList.mSkelBase->getAnimationState(groupname);
|
||||||
times.mLoops = loops;
|
times.mLoops = loops;
|
||||||
|
|
Loading…
Reference in a new issue