Add XYZ rotation axis order support

C++20
Alexei Dobrohotov 3 years ago
parent 76ba5025e3
commit 54df5031b7

@ -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<AxisOrder>(nif->getInt());
mXRotations = std::make_shared<FloatKeyMap>();
mYRotations = std::make_shared<FloatKeyMap>();
mZRotations = std::make_shared<FloatKeyMap>();

@ -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;
};

@ -79,6 +79,7 @@ KeyframeController::KeyframeController(const KeyframeController &copy, 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

@ -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;
};

Loading…
Cancel
Save