diff --git a/components/nif/data.cpp b/components/nif/data.cpp index 1b6d302d68..36a123fdfa 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -439,9 +439,8 @@ void NiKeyframeData::read(NIFStream *nif) mRotations->read(nif); if(mRotations->mInterpolationType == InterpolationType_XYZ) { - //Chomp unused float if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,0)) - nif->getFloat(); + mAxisOrder = static_cast(nif->getInt()); mXRotations = std::make_shared(); mYRotations = std::make_shared(); mZRotations = std::make_shared(); diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 70171ac47c..919e442665 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -240,6 +240,21 @@ struct NiKeyframeData : public Record Vector3KeyMapPtr mTranslations; FloatKeyMapPtr mScales; + enum class AxisOrder + { + Order_XYZ = 0, + Order_XZY = 1, + Order_YZX = 2, + Order_YXZ = 3, + Order_ZXY = 4, + Order_ZYX = 5, + Order_XYX = 6, + Order_YZY = 7, + Order_ZXZ = 8 + }; + + AxisOrder mAxisOrder{AxisOrder::Order_XYZ}; + void read(NIFStream *nif) override; }; diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 07134532e9..91bd94c74f 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -79,6 +79,7 @@ KeyframeController::KeyframeController(const KeyframeController ©, const osg , mZRotations(copy.mZRotations) , mTranslations(copy.mTranslations) , mScales(copy.mScales) + , mAxisOrder(copy.mAxisOrder) { } @@ -95,6 +96,7 @@ KeyframeController::KeyframeController(const Nif::NiKeyframeController *keyctrl) mZRotations = FloatInterpolator(interp->data->mZRotations); mTranslations = Vec3Interpolator(interp->data->mTranslations, interp->defaultPos); mScales = FloatInterpolator(interp->data->mScales, interp->defaultScale); + mAxisOrder = interp->data->mAxisOrder; } else { @@ -112,6 +114,7 @@ KeyframeController::KeyframeController(const Nif::NiKeyframeController *keyctrl) mZRotations = FloatInterpolator(keydata->mZRotations); mTranslations = Vec3Interpolator(keydata->mTranslations); mScales = FloatInterpolator(keydata->mScales, 1.f); + mAxisOrder = keydata->mAxisOrder; } } @@ -124,10 +127,31 @@ osg::Quat KeyframeController::getXYZRotation(float time) const yrot = mYRotations.interpKey(time); if (!mZRotations.empty()) zrot = mZRotations.interpKey(time); - osg::Quat xr(xrot, osg::Vec3f(1,0,0)); - osg::Quat yr(yrot, osg::Vec3f(0,1,0)); - osg::Quat zr(zrot, osg::Vec3f(0,0,1)); - return (xr*yr*zr); + osg::Quat xr(xrot, osg::X_AXIS); + osg::Quat yr(yrot, osg::Y_AXIS); + osg::Quat zr(zrot, osg::Z_AXIS); + switch (mAxisOrder) + { + case Nif::NiKeyframeData::AxisOrder::Order_XYZ: + return xr * yr * zr; + case Nif::NiKeyframeData::AxisOrder::Order_XZY: + return xr * zr * yr; + case Nif::NiKeyframeData::AxisOrder::Order_YZX: + return yr * zr * xr; + case Nif::NiKeyframeData::AxisOrder::Order_YXZ: + return yr * xr * zr; + case Nif::NiKeyframeData::AxisOrder::Order_ZXY: + return zr * xr * yr; + case Nif::NiKeyframeData::AxisOrder::Order_ZYX: + return zr * yr * xr; + case Nif::NiKeyframeData::AxisOrder::Order_XYX: + return xr * yr * xr; + case Nif::NiKeyframeData::AxisOrder::Order_YZY: + return yr * zr * yr; + case Nif::NiKeyframeData::AxisOrder::Order_ZXZ: + return zr * xr * zr; + } + return xr * yr * zr; } osg::Vec3f KeyframeController::getTranslation(float time) const diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index a5f887ebe6..acd96afd1e 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -255,6 +255,8 @@ namespace NifOsg Vec3Interpolator mTranslations; FloatInterpolator mScales; + Nif::NiKeyframeData::AxisOrder mAxisOrder{Nif::NiKeyframeData::AxisOrder::Order_XYZ}; + osg::Quat getXYZRotation(float time) const; };