mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 03:45:32 +00:00
Implement NiFlipController
This commit is contained in:
parent
51a9f0111c
commit
9fcb4fad5c
3 changed files with 95 additions and 6 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue