1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 16:15:31 +00:00

Implement NiFlipController

This commit is contained in:
scrawl 2013-12-08 18:51:56 +01:00
parent 51a9f0111c
commit 9fcb4fad5c
3 changed files with 95 additions and 6 deletions

View file

@ -306,7 +306,7 @@ public:
class NiFlipController : public Controller
{
public:
int mTexSlot;
int mTexSlot; // NiTexturingProperty::TextureType
float mDelta; // Time between two flips. delta = (start_time - stop_time) / num_sources
NiSourceTextureList mSources;

View file

@ -37,9 +37,9 @@ class NIFMaterialLoader {
static std::map<size_t,std::string> sMaterialMap;
public:
static std::string findTextureName(const std::string &filename);
public:
static Ogre::String getMaterial(const Nif::ShapeData *shapedata,
const Ogre::String &name, const Ogre::String &group,
const Nif::NiTexturingProperty *texprop,

View file

@ -109,6 +109,74 @@ ObjectScene::~ObjectScene()
mSkelBase = NULL;
}
// Animates a texture
class FlipController
{
public:
class Value : public Ogre::ControllerValue<Ogre::Real>
{
private:
Ogre::MovableObject* mMovable;
int mTexSlot;
float mDelta;
std::vector<std::string> mTextures;
MaterialControllerManager* mMaterialControllerMgr;
public:
Value(Ogre::MovableObject *movable, const Nif::NiFlipController *ctrl, MaterialControllerManager* materialControllerMgr)
: mMovable(movable)
, mMaterialControllerMgr(materialControllerMgr)
{
mTexSlot = ctrl->mTexSlot;
mDelta = ctrl->mDelta;
for (unsigned int i=0; i<ctrl->mSources.length(); ++i)
{
const Nif::NiSourceTexture* tex = ctrl->mSources[i].getPtr();
if (!tex->external)
std::cerr << "Warning: Found internal texture, ignoring." << std::endl;
mTextures.push_back(NIFMaterialLoader::findTextureName(tex->filename));
}
}
virtual Ogre::Real getValue() const
{
// Should not be called
return 0.0f;
}
virtual void setValue(Ogre::Real time)
{
if (mDelta == 0)
return;
int curTexture = int(time / mDelta) % mTextures.size();
Ogre::MaterialPtr mat = mMaterialControllerMgr->getWritableMaterial(mMovable);
Ogre::Material::TechniqueIterator techs = mat->getTechniqueIterator();
while(techs.hasMoreElements())
{
Ogre::Technique *tech = techs.getNext();
Ogre::Technique::PassIterator passes = tech->getPassIterator();
while(passes.hasMoreElements())
{
Ogre::Pass *pass = passes.getNext();
Ogre::Pass::TextureUnitStateIterator textures = pass->getTextureUnitStateIterator();
while (textures.hasMoreElements())
{
Ogre::TextureUnitState *texture = textures.getNext();
if ((texture->getName() == "diffuseMap" && mTexSlot == Nif::NiTexturingProperty::BaseTexture)
|| (texture->getName() == "normalMap" && mTexSlot == Nif::NiTexturingProperty::BumpTexture)
|| (texture->getName() == "detailMap" && mTexSlot == Nif::NiTexturingProperty::DetailTexture)
|| (texture->getName() == "emissiveMap" && mTexSlot == Nif::NiTexturingProperty::GlowTexture))
texture->setTextureName(mTextures[curTexture]);
}
}
}
}
};
typedef DefaultFunction Function;
};
class AlphaController
{
public:
@ -633,15 +701,15 @@ class NIFObjectLoader
const Nif::NiWireframeProperty *wireprop = NULL;
node->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
if(matprop)
{
Nif::ControllerPtr ctrls = matprop->controller;
while(!ctrls.empty())
{
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
if (ctrls->recType == Nif::RC_NiAlphaController)
{
const Nif::NiAlphaController *alphaCtrl = dynamic_cast<const Nif::NiAlphaController*>(ctrls.getPtr());
@ -661,6 +729,27 @@ class NIFObjectLoader
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrls = ctrls->next;
}
}
if (texprop)
{
Nif::ControllerPtr ctrls = texprop->controller;
while(!ctrls.empty())
{
if (ctrls->recType == Nif::RC_NiFlipController)
{
const Nif::NiFlipController *flipCtrl = dynamic_cast<const Nif::NiFlipController*>(ctrls.getPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW FlipController::Value(
movable, flipCtrl, &scene->mMaterialControllerMgr));
FlipController::Function* function = OGRE_NEW FlipController::Function(flipCtrl, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
Ogre::ControllerFunctionRealPtr func(function);
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrls = ctrls->next;
}
}