diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index 82116378de..bb00791b15 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -29,6 +29,26 @@ namespace Nif target.post(nif); } + void NiInterpController::read(NIFStream* nif) + { + Controller::read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,104) && nif->getVersion() <= NIFStream::generateVersion(10,1,0,108)) + mManagerControlled = nif->getBoolean(); + } + + void NiSingleInterpController::read(NIFStream* nif) + { + NiInterpController::read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,104)) + mInterpolator.read(nif); + } + + void NiSingleInterpController::post(NIFFile* nif) + { + NiInterpController::post(nif); + mInterpolator.post(nif); + } + void NiParticleSystemController::read(NIFStream *nif) { Controller::read(nif); @@ -93,27 +113,24 @@ namespace Nif void NiMaterialColorController::read(NIFStream *nif) { - Controller::read(nif); - if (nif->getVersion() > NIFStream::generateVersion(10,1,0,103)) - interpolator.read(nif); + NiSingleInterpController::read(nif); // Two bits that correspond to the controlled material color. // 00: Ambient // 01: Diffuse // 10: Specular // 11: Emissive if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) - targetColor = nif->getUShort() & 3; + mTargetColor = nif->getUShort() & 3; else - targetColor = (flags >> 4) & 3; + mTargetColor = (flags >> 4) & 3; if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) - data.read(nif); + mData.read(nif); } void NiMaterialColorController::post(NIFFile *nif) { - Controller::post(nif); - interpolator.post(nif); - data.post(nif); + NiSingleInterpController::post(nif); + mData.post(nif); } void NiLookAtController::read(NIFStream *nif) @@ -166,23 +183,20 @@ namespace Nif void NiKeyframeController::read(NIFStream *nif) { - Controller::read(nif); + NiSingleInterpController::read(nif); if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) - data.read(nif); - else - interpolator.read(nif); + mData.read(nif); } void NiKeyframeController::post(NIFFile *nif) { - Controller::post(nif); - data.post(nif); - interpolator.post(nif); + NiSingleInterpController::post(nif); + mData.post(nif); } void NiMultiTargetTransformController::read(NIFStream *nif) { - Controller::read(nif); + NiInterpController::read(nif); size_t numTargets = nif->getUShort(); std::vector targets; targets.resize(numTargets); @@ -193,29 +207,39 @@ namespace Nif void NiMultiTargetTransformController::post(NIFFile *nif) { - Controller::post(nif); + NiInterpController::post(nif); mExtraTargets.post(nif); } - void NiFloatInterpController::read(NIFStream *nif) + void NiAlphaController::read(NIFStream *nif) { - Controller::read(nif); + NiFloatInterpController::read(nif); if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) - data.read(nif); - else - interpolator.read(nif); + mData.read(nif); } - void NiFloatInterpController::post(NIFFile *nif) + void NiAlphaController::post(NIFFile *nif) { - Controller::post(nif); - data.post(nif); - interpolator.post(nif); + NiFloatInterpController::post(nif); + mData.post(nif); + } + + void NiRollController::read(NIFStream *nif) + { + NiSingleInterpController::read(nif); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) + mData.read(nif); + } + + void NiRollController::post(NIFFile *nif) + { + NiSingleInterpController::post(nif); + mData.post(nif); } void NiGeomMorpherController::read(NIFStream *nif) { - Controller::read(nif); + NiInterpController::read(nif); if (nif->getVersion() >= NIFFile::NIFVersion::VER_OB_OLD) /*bool updateNormals = !!*/nif->getUShort(); data.read(nif); @@ -245,28 +269,27 @@ namespace Nif void NiGeomMorpherController::post(NIFFile *nif) { - Controller::post(nif); + NiInterpController::post(nif); data.post(nif); interpolators.post(nif); } void NiVisController::read(NIFStream *nif) { - Controller::read(nif); - data.read(nif); + NiBoolInterpController::read(nif); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) + mData.read(nif); } void NiVisController::post(NIFFile *nif) { - Controller::post(nif); - data.post(nif); + NiBoolInterpController::post(nif); + mData.post(nif); } void NiFlipController::read(NIFStream *nif) { - Controller::read(nif); - if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0)) - mInterpolator.read(nif); + NiFloatInterpController::read(nif); mTexSlot = nif->getUInt(); if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) { @@ -278,8 +301,7 @@ namespace Nif void NiFlipController::post(NIFFile *nif) { - Controller::post(nif); - mInterpolator.post(nif); + NiFloatInterpController::post(nif); mSources.post(nif); } diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index 06de446a0d..44a3bcf427 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -29,6 +29,24 @@ namespace Nif { +// Base class for controllers that use NiInterpolators to animate objects. +struct NiInterpController : public Controller +{ + // Usually one of the flags. + bool mManagerControlled{false}; + + void read(NIFStream* nif) override; +}; + +// Base class for controllers that use one NiInterpolator. +struct NiSingleInterpController : public NiInterpController +{ + NiInterpolatorPtr mInterpolator; + + void read(NIFStream* nif) override; + void post(NIFFile* nif) override; +}; + struct NiParticleSystemController : public Controller { enum BSPArrayController { @@ -88,11 +106,10 @@ struct NiParticleSystemController : public Controller }; using NiBSPArrayController = NiParticleSystemController; -struct NiMaterialColorController : public Controller +struct NiMaterialColorController : public NiSingleInterpController { - NiPoint3InterpolatorPtr interpolator; - NiPosDataPtr data; - unsigned int targetColor; + NiPosDataPtr mData; + unsigned int mTargetColor; void read(NIFStream *nif) override; void post(NIFFile *nif) override; @@ -139,16 +156,15 @@ struct NiUVController : public Controller void post(NIFFile *nif) override; }; -struct NiKeyframeController : public Controller +struct NiKeyframeController : public NiSingleInterpController { - NiKeyframeDataPtr data; - NiTransformInterpolatorPtr interpolator; + NiKeyframeDataPtr mData; void read(NIFStream *nif) override; void post(NIFFile *nif) override; }; -struct NiMultiTargetTransformController : public Controller +struct NiMultiTargetTransformController : public NiInterpController { NodeList mExtraTargets; @@ -156,19 +172,29 @@ struct NiMultiTargetTransformController : public Controller void post(NIFFile *nif) override; }; -struct NiFloatInterpController : public Controller +// Base class for controllers that use a NiFloatInterpolator to animate their target. +struct NiFloatInterpController : public NiSingleInterpController { }; + +// Ditto for NiBoolInterpolator. +struct NiBoolInterpController : public NiSingleInterpController { }; + +struct NiAlphaController : public NiFloatInterpController { - NiFloatDataPtr data; - NiFloatInterpolatorPtr interpolator; + NiFloatDataPtr mData; void read(NIFStream *nif) override; void post(NIFFile *nif) override; }; -struct NiAlphaController : public NiFloatInterpController { }; -struct NiRollController : public NiFloatInterpController { }; +struct NiRollController : public NiSingleInterpController +{ + NiFloatDataPtr mData; -struct NiGeomMorpherController : public Controller + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; +}; + +struct NiGeomMorpherController : public NiInterpController { NiMorphDataPtr data; NiFloatInterpolatorList interpolators; @@ -177,17 +203,16 @@ struct NiGeomMorpherController : public Controller void post(NIFFile *nif) override; }; -struct NiVisController : public Controller +struct NiVisController : public NiBoolInterpController { - NiVisDataPtr data; + NiVisDataPtr mData; void read(NIFStream *nif) override; void post(NIFFile *nif) override; }; -struct NiFlipController : public Controller +struct NiFlipController : public NiFloatInterpController { - NiFloatInterpolatorPtr mInterpolator; int mTexSlot; // NiTexturingProperty::TextureType float mDelta; // Time between two flips. delta = (start_time - stop_time) / num_sources NiSourceTextureList mSources; @@ -207,9 +232,9 @@ struct NiControllerManager : public Controller void read(NIFStream *nif) override; }; -struct Interpolator : public Record { }; +struct NiInterpolator : public Record { }; -struct NiPoint3Interpolator : public Interpolator +struct NiPoint3Interpolator : public NiInterpolator { osg::Vec3f defaultVal; NiPosDataPtr data; @@ -217,15 +242,15 @@ struct NiPoint3Interpolator : public Interpolator void post(NIFFile *nif) override; }; -struct NiBoolInterpolator : public Interpolator +struct NiBoolInterpolator : public NiInterpolator { - bool defaultVal; + char defaultVal; NiBoolDataPtr data; void read(NIFStream *nif) override; void post(NIFFile *nif) override; }; -struct NiFloatInterpolator : public Interpolator +struct NiFloatInterpolator : public NiInterpolator { float defaultVal; NiFloatDataPtr data; @@ -233,7 +258,7 @@ struct NiFloatInterpolator : public Interpolator void post(NIFFile *nif) override; }; -struct NiTransformInterpolator : public Interpolator +struct NiTransformInterpolator : public NiInterpolator { osg::Vec3f defaultPos; osg::Quat defaultRot; @@ -244,7 +269,7 @@ struct NiTransformInterpolator : public Interpolator void post(NIFFile *nif) override; }; -struct NiColorInterpolator : public Interpolator +struct NiColorInterpolator : public NiInterpolator { osg::Vec4f defaultVal; NiColorDataPtr data; diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index 5ec00b0c92..e98fe89cab 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -141,9 +141,6 @@ struct NiPalette; struct NiParticleModifier; struct NiBoolData; struct NiSkinPartition; -struct NiFloatInterpolator; -struct NiPoint3Interpolator; -struct NiTransformInterpolator; struct BSShaderTextureSet; struct NiGeometryData; struct BSShaderProperty; @@ -154,6 +151,8 @@ struct bhkShape; struct bhkSerializable; struct hkPackedNiTriStripsData; struct NiAccumulator; +struct NiInterpolator; +struct NiFloatInterpolator; using NodePtr = RecordPtrT; using ExtraPtr = RecordPtrT; @@ -174,9 +173,6 @@ using NiPalettePtr = RecordPtrT; using NiParticleModifierPtr = RecordPtrT; using NiBoolDataPtr = RecordPtrT; using NiSkinPartitionPtr = RecordPtrT; -using NiFloatInterpolatorPtr = RecordPtrT; -using NiPoint3InterpolatorPtr = RecordPtrT; -using NiTransformInterpolatorPtr = RecordPtrT; using BSShaderTextureSetPtr = RecordPtrT; using NiGeometryDataPtr = RecordPtrT; using BSShaderPropertyPtr = RecordPtrT; @@ -186,6 +182,7 @@ using bhkWorldObjectPtr = RecordPtrT; using bhkShapePtr = RecordPtrT; using hkPackedNiTriStripsDataPtr = RecordPtrT; using NiAccumulatorPtr = RecordPtrT; +using NiInterpolatorPtr = RecordPtrT; using NodeList = RecordListT; using PropertyList = RecordListT; diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index b2beead8bd..280940dc40 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -86,29 +86,32 @@ KeyframeController::KeyframeController(const KeyframeController ©, const osg KeyframeController::KeyframeController(const Nif::NiKeyframeController *keyctrl) { - if (!keyctrl->interpolator.empty()) + if (!keyctrl->mInterpolator.empty()) { - const Nif::NiTransformInterpolator* interp = keyctrl->interpolator.getPtr(); - if (!interp->data.empty()) + if (keyctrl->mInterpolator->recType == Nif::RC_NiTransformInterpolator) { - mRotations = QuaternionInterpolator(interp->data->mRotations, interp->defaultRot); - mXRotations = FloatInterpolator(interp->data->mXRotations); - mYRotations = FloatInterpolator(interp->data->mYRotations); - mZRotations = FloatInterpolator(interp->data->mZRotations); - mTranslations = Vec3Interpolator(interp->data->mTranslations, interp->defaultPos); - mScales = FloatInterpolator(interp->data->mScales, interp->defaultScale); - mAxisOrder = interp->data->mAxisOrder; - } - else - { - mRotations = QuaternionInterpolator(Nif::QuaternionKeyMapPtr(), interp->defaultRot); - mTranslations = Vec3Interpolator(Nif::Vector3KeyMapPtr(), interp->defaultPos); - mScales = FloatInterpolator(Nif::FloatKeyMapPtr(), interp->defaultScale); + const Nif::NiTransformInterpolator* interp = static_cast(keyctrl->mInterpolator.getPtr()); + if (!interp->data.empty()) + { + mRotations = QuaternionInterpolator(interp->data->mRotations, interp->defaultRot); + mXRotations = FloatInterpolator(interp->data->mXRotations); + mYRotations = FloatInterpolator(interp->data->mYRotations); + mZRotations = FloatInterpolator(interp->data->mZRotations); + mTranslations = Vec3Interpolator(interp->data->mTranslations, interp->defaultPos); + mScales = FloatInterpolator(interp->data->mScales, interp->defaultScale); + mAxisOrder = interp->data->mAxisOrder; + } + else + { + mRotations = QuaternionInterpolator(Nif::QuaternionKeyMapPtr(), interp->defaultRot); + mTranslations = Vec3Interpolator(Nif::Vector3KeyMapPtr(), interp->defaultPos); + mScales = FloatInterpolator(Nif::FloatKeyMapPtr(), interp->defaultScale); + } } } - else if (!keyctrl->data.empty()) + else if (!keyctrl->mData.empty()) { - const Nif::NiKeyframeData* keydata = keyctrl->data.getPtr(); + const Nif::NiKeyframeData* keydata = keyctrl->mData.getPtr(); mRotations = QuaternionInterpolator(keydata->mRotations); mXRotations = FloatInterpolator(keydata->mXRotations); mYRotations = FloatInterpolator(keydata->mYRotations); @@ -298,14 +301,20 @@ void UVController::apply(osg::StateSet* stateset, osg::NodeVisitor* nv) } } -VisController::VisController(const Nif::NiVisData *data, unsigned int mask) - : mData(data->mVis) - , mMask(mask) +VisController::VisController(const Nif::NiVisController *ctrl, unsigned int mask) + : mMask(mask) { + if (!ctrl->mInterpolator.empty()) + { + if (ctrl->mInterpolator->recType == Nif::RC_NiBoolInterpolator) + mInterpolator = ByteInterpolator(static_cast(ctrl->mInterpolator.getPtr())); + } + else if (!ctrl->mData.empty()) + mData = ctrl->mData->mVis; + } VisController::VisController() - : mMask(0) { } @@ -313,12 +322,16 @@ VisController::VisController(const VisController ©, const osg::CopyOp ©o : SceneUtil::NodeCallback(copy, copyop) , Controller(copy) , mData(copy.mData) + , mInterpolator(copy.mInterpolator) , mMask(copy.mMask) { } bool VisController::calculate(float time) const { + if (!mInterpolator.empty()) + return mInterpolator.interpKey(time); + if(mData.size() == 0) return true; @@ -340,14 +353,15 @@ void VisController::operator() (osg::Node* node, osg::NodeVisitor* nv) traverse(node, nv); } -RollController::RollController(const Nif::NiFloatData *data) - : mData(data->mKeyList, 1.f) -{ -} - -RollController::RollController(const Nif::NiFloatInterpolator* interpolator) - : mData(interpolator) +RollController::RollController(const Nif::NiRollController* ctrl) { + if (!ctrl->mInterpolator.empty()) + { + if (ctrl->mInterpolator->recType == Nif::RC_NiFloatInterpolator) + mData = FloatInterpolator(static_cast(ctrl->mInterpolator.getPtr())); + } + else if (!ctrl->mData.empty()) + mData = FloatInterpolator(ctrl->mData->mKeyList, 1.f); } RollController::RollController(const RollController ©, const osg::CopyOp ©op) @@ -386,17 +400,16 @@ AlphaController::AlphaController() { } -AlphaController::AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial) - : mData(data->mKeyList, 1.f) - , mBaseMaterial(baseMaterial) -{ - -} - -AlphaController::AlphaController(const Nif::NiFloatInterpolator* interpolator, const osg::Material* baseMaterial) - : mData(interpolator) - , mBaseMaterial(baseMaterial) +AlphaController::AlphaController(const Nif::NiAlphaController* ctrl, const osg::Material* baseMaterial) + : mBaseMaterial(baseMaterial) { + if (!ctrl->mInterpolator.empty()) + { + if (ctrl->mInterpolator->recType == Nif::RC_NiFloatInterpolator) + mData = FloatInterpolator(static_cast(ctrl->mInterpolator.getPtr())); + } + else if (!ctrl->mData.empty()) + mData = FloatInterpolator(ctrl->mData->mKeyList, 1.f); } AlphaController::AlphaController(const AlphaController ©, const osg::CopyOp ©op) @@ -427,18 +440,17 @@ MaterialColorController::MaterialColorController() { } -MaterialColorController::MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial) - : mData(data->mKeyList, osg::Vec3f(1,1,1)) - , mTargetColor(color) - , mBaseMaterial(baseMaterial) -{ -} - -MaterialColorController::MaterialColorController(const Nif::NiPoint3Interpolator* interpolator, TargetColor color, const osg::Material* baseMaterial) - : mData(interpolator) - , mTargetColor(color) +MaterialColorController::MaterialColorController(const Nif::NiMaterialColorController* ctrl, const osg::Material* baseMaterial) + : mTargetColor(static_cast(ctrl->mTargetColor)) , mBaseMaterial(baseMaterial) { + if (!ctrl->mInterpolator.empty()) + { + if (ctrl->mInterpolator->recType == Nif::RC_NiPoint3Interpolator) + mData = Vec3Interpolator(static_cast(ctrl->mInterpolator.getPtr())); + } + else if (!ctrl->mData.empty()) + mData = Vec3Interpolator(ctrl->mData->mKeyList, osg::Vec3f(1, 1, 1)); } MaterialColorController::MaterialColorController(const MaterialColorController ©, const osg::CopyOp ©op) @@ -499,8 +511,8 @@ FlipController::FlipController(const Nif::NiFlipController *ctrl, const std::vec , mDelta(ctrl->mDelta) , mTextures(textures) { - if (!ctrl->mInterpolator.empty()) - mData = ctrl->mInterpolator.getPtr(); + if (!ctrl->mInterpolator.empty() && ctrl->mInterpolator->recType == Nif::RC_NiFloatInterpolator) + mData = static_cast(ctrl->mInterpolator.getPtr()); } FlipController::FlipController(int texSlot, float delta, const std::vector >& textures) diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index c79c6a70d1..af658c0bd5 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -72,7 +72,8 @@ namespace NifOsg std::is_same, std::is_same, std::is_same, - std::is_same + std::is_same, + std::is_same >, std::is_same >, @@ -192,6 +193,7 @@ namespace NifOsg using FloatInterpolator = ValueInterpolator; using Vec3Interpolator = ValueInterpolator; using Vec4Interpolator = ValueInterpolator; + using ByteInterpolator = ValueInterpolator; class ControllerFunction : public SceneUtil::ControllerFunction { @@ -289,12 +291,13 @@ namespace NifOsg { private: std::vector mData; - unsigned int mMask; + ByteInterpolator mInterpolator; + unsigned int mMask{0u}; bool calculate(float time) const; public: - VisController(const Nif::NiVisData *data, unsigned int mask); + VisController(const Nif::NiVisController* ctrl, unsigned int mask); VisController(); VisController(const VisController& copy, const osg::CopyOp& copyop); @@ -310,8 +313,7 @@ namespace NifOsg double mStartingTime{0}; public: - RollController(const Nif::NiFloatData *data); - RollController(const Nif::NiFloatInterpolator* interpolator); + RollController(const Nif::NiRollController* interpolator); RollController() = default; RollController(const RollController& copy, const osg::CopyOp& copyop); @@ -326,8 +328,7 @@ namespace NifOsg FloatInterpolator mData; osg::ref_ptr mBaseMaterial; public: - AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial); - AlphaController(const Nif::NiFloatInterpolator* interpolator, const osg::Material* baseMaterial); + AlphaController(const Nif::NiAlphaController* ctrl, const osg::Material* baseMaterial); AlphaController(); AlphaController(const AlphaController& copy, const osg::CopyOp& copyop); @@ -348,8 +349,7 @@ namespace NifOsg Specular = 2, Emissive = 3 }; - MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial); - MaterialColorController(const Nif::NiPoint3Interpolator* interpolator, TargetColor color, const osg::Material* baseMaterial); + MaterialColorController(const Nif::NiMaterialColorController* ctrl, const osg::Material* baseMaterial); MaterialColorController(); MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop); diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 5db3e9280c..918e0ee2b3 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -246,7 +246,7 @@ namespace NifOsg // This is used to queue emitters that weren't attached to their node yet. std::vector>> mEmitterQueue; - static void loadKf(Nif::NIFFilePtr nif, SceneUtil::KeyframeHolder& target) + void loadKf(Nif::NIFFilePtr nif, SceneUtil::KeyframeHolder& target) const { const Nif::NiSequenceStreamHelper *seq = nullptr; const size_t numRoots = nif->numRoots(); @@ -292,9 +292,15 @@ namespace NifOsg const Nif::NiStringExtraData *strdata = static_cast(extra.getPtr()); const Nif::NiKeyframeController *key = static_cast(ctrl.getPtr()); - if (key->data.empty() && key->interpolator.empty()) + if (key->mData.empty() && key->mInterpolator.empty()) continue; + if (!key->mInterpolator.empty() && key->mInterpolator->recType != Nif::RC_NiTransformInterpolator) + { + Log(Debug::Error) << "Unsupported interpolator type for NiKeyframeController " << key->recIndex << " in " << mFilename; + continue; + } + osg::ref_ptr callback = new NifOsg::KeyframeController(key); setupController(key, callback, /*animflags*/0); @@ -827,8 +833,13 @@ namespace NifOsg if (ctrl->recType == Nif::RC_NiKeyframeController) { const Nif::NiKeyframeController *key = static_cast(ctrl.getPtr()); - if (key->data.empty() && key->interpolator.empty()) + if (key->mData.empty() && key->mInterpolator.empty()) continue; + if (!key->mInterpolator.empty() && key->mInterpolator->recType != Nif::RC_NiTransformInterpolator) + { + Log(Debug::Error) << "Unsupported interpolator type for NiKeyframeController " << key->recIndex << " in " << mFilename; + continue; + } osg::ref_ptr callback = new KeyframeController(key); setupController(key, callback, animflags); node->addUpdateCallback(callback); @@ -847,22 +858,28 @@ namespace NifOsg else if (ctrl->recType == Nif::RC_NiVisController) { const Nif::NiVisController *visctrl = static_cast(ctrl.getPtr()); - if (visctrl->data.empty()) + if (visctrl->mData.empty() && visctrl->mInterpolator.empty()) continue; - osg::ref_ptr callback(new VisController(visctrl->data.getPtr(), Loader::getHiddenNodeMask())); + if (!visctrl->mInterpolator.empty() && visctrl->mInterpolator->recType != Nif::RC_NiBoolInterpolator) + { + Log(Debug::Error) << "Unsupported interpolator type for NiVisController " << visctrl->recIndex << " in " << mFilename; + continue; + } + osg::ref_ptr callback(new VisController(visctrl, Loader::getHiddenNodeMask())); setupController(visctrl, callback, animflags); node->addUpdateCallback(callback); } else if (ctrl->recType == Nif::RC_NiRollController) { const Nif::NiRollController *rollctrl = static_cast(ctrl.getPtr()); - if (rollctrl->data.empty() && rollctrl->interpolator.empty()) + if (rollctrl->mData.empty() && rollctrl->mInterpolator.empty()) continue; - osg::ref_ptr callback; - if (!rollctrl->interpolator.empty()) - callback = new RollController(rollctrl->interpolator.getPtr()); - else // if (!rollctrl->data.empty()) - callback = new RollController(rollctrl->data.getPtr()); + if (!rollctrl->mInterpolator.empty() && rollctrl->mInterpolator->recType != Nif::RC_NiFloatInterpolator) + { + Log(Debug::Error) << "Unsupported interpolator type for NiRollController " << rollctrl->recIndex << " in " << mFilename; + continue; + } + osg::ref_ptr callback = new RollController(rollctrl); setupController(rollctrl, callback, animflags); node->addUpdateCallback(callback); isAnimated = true; @@ -888,29 +905,31 @@ namespace NifOsg if (ctrl->recType == Nif::RC_NiAlphaController) { const Nif::NiAlphaController* alphactrl = static_cast(ctrl.getPtr()); - if (alphactrl->data.empty() && alphactrl->interpolator.empty()) + if (alphactrl->mData.empty() && alphactrl->mInterpolator.empty()) continue; - osg::ref_ptr osgctrl; - if (!alphactrl->interpolator.empty()) - osgctrl = new AlphaController(alphactrl->interpolator.getPtr(), baseMaterial); - else // if (!alphactrl->data.empty()) - osgctrl = new AlphaController(alphactrl->data.getPtr(), baseMaterial); + if (!alphactrl->mInterpolator.empty() && alphactrl->mInterpolator->recType != Nif::RC_NiFloatInterpolator) + { + Log(Debug::Error) << "Unsupported interpolator type for NiAlphaController " << alphactrl->recIndex << " in " << mFilename; + continue; + } + osg::ref_ptr osgctrl = new AlphaController(alphactrl, baseMaterial); setupController(alphactrl, osgctrl, animflags); composite->addController(osgctrl); } else if (ctrl->recType == Nif::RC_NiMaterialColorController) { const Nif::NiMaterialColorController* matctrl = static_cast(ctrl.getPtr()); - if (matctrl->data.empty() && matctrl->interpolator.empty()) + if (matctrl->mData.empty() && matctrl->mInterpolator.empty()) continue; - auto targetColor = static_cast(matctrl->targetColor); + auto targetColor = static_cast(matctrl->mTargetColor); if (mVersion <= Nif::NIFFile::NIFVersion::VER_MW && targetColor == MaterialColorController::TargetColor::Specular) continue; - osg::ref_ptr osgctrl; - if (!matctrl->interpolator.empty()) - osgctrl = new MaterialColorController(matctrl->interpolator.getPtr(), targetColor, baseMaterial); - else // if (!matctrl->data.empty()) - osgctrl = new MaterialColorController(matctrl->data.getPtr(), targetColor, baseMaterial); + if (!matctrl->mInterpolator.empty() && matctrl->mInterpolator->recType != Nif::RC_NiPoint3Interpolator) + { + Log(Debug::Error) << "Unsupported interpolator type for NiMaterialColorController " << matctrl->recIndex << " in " << mFilename; + continue; + } + osg::ref_ptr osgctrl = new MaterialColorController(matctrl, baseMaterial); setupController(matctrl, osgctrl, animflags); composite->addController(osgctrl); } @@ -928,6 +947,11 @@ namespace NifOsg if (ctrl->recType == Nif::RC_NiFlipController) { const Nif::NiFlipController* flipctrl = static_cast(ctrl.getPtr()); + if (!flipctrl->mInterpolator.empty() && flipctrl->mInterpolator->recType != Nif::RC_NiFloatInterpolator) + { + Log(Debug::Error) << "Unsupported interpolator type for NiFlipController " << flipctrl->recIndex << " in " << mFilename; + continue; + } std::vector > textures; // inherit wrap settings from the target slot