mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
Implement XYZ rotation keys support (Fixes #1067)
This commit is contained in:
parent
65536f0857
commit
5a25649076
3 changed files with 31 additions and 12 deletions
|
@ -350,8 +350,11 @@ struct NiMorphData : public Record
|
|||
struct NiKeyframeData : public Record
|
||||
{
|
||||
QuaternionKeyMap mRotations;
|
||||
//\FIXME mXYZ_Keys are read, but not used.
|
||||
FloatKeyMap mXYZ_Keys;
|
||||
|
||||
FloatKeyMap mXRotations;
|
||||
FloatKeyMap mYRotations;
|
||||
FloatKeyMap mZRotations;
|
||||
|
||||
Vector3KeyMap mTranslations;
|
||||
FloatKeyMap mScales;
|
||||
|
||||
|
@ -362,12 +365,9 @@ struct NiKeyframeData : public Record
|
|||
{
|
||||
//Chomp unused float
|
||||
nif->getFloat();
|
||||
for(size_t i=0;i<3;++i)
|
||||
{
|
||||
//Read concatenates items together.
|
||||
mXYZ_Keys.read(nif,true);
|
||||
}
|
||||
nif->file->warn("XYZ_ROTATION_KEY read, but not used!");
|
||||
mXRotations.read(nif, true);
|
||||
mYRotations.read(nif, true);
|
||||
mZRotations.read(nif, true);
|
||||
}
|
||||
mTranslations.read(nif);
|
||||
mScales.read(nif);
|
||||
|
|
|
@ -49,9 +49,7 @@ struct KeyMapT {
|
|||
if(count == 0 && !force)
|
||||
return;
|
||||
|
||||
//If we aren't forcing things, make sure that read clears any previous keys
|
||||
if(!force)
|
||||
mKeys.clear();
|
||||
mKeys.clear();
|
||||
|
||||
mInterpolationType = nif->getUInt();
|
||||
|
||||
|
@ -88,7 +86,7 @@ struct KeyMapT {
|
|||
//XYZ keys aren't actually read here.
|
||||
//data.hpp sees that the last type read was sXYZInterpolation and:
|
||||
// Eats a floating point number, then
|
||||
// Re-runs the read function 3 more times, with force enabled so that the previous values aren't cleared.
|
||||
// Re-runs the read function 3 more times.
|
||||
// When it does that it's reading in a bunch of sLinearInterpolation keys, not sXYZInterpolation.
|
||||
else if(mInterpolationType == sXYZInterpolation)
|
||||
{
|
||||
|
|
|
@ -442,6 +442,9 @@ public:
|
|||
{
|
||||
private:
|
||||
const Nif::QuaternionKeyMap* mRotations;
|
||||
const Nif::FloatKeyMap* mXRotations;
|
||||
const Nif::FloatKeyMap* mYRotations;
|
||||
const Nif::FloatKeyMap* mZRotations;
|
||||
const Nif::Vector3KeyMap* mTranslations;
|
||||
const Nif::FloatKeyMap* mScales;
|
||||
Nif::NIFFilePtr mNif; // Hold a SharedPtr to make sure key lists stay valid
|
||||
|
@ -472,11 +475,25 @@ public:
|
|||
return keys.rbegin()->second.mValue;
|
||||
}
|
||||
|
||||
Ogre::Quaternion getXYZRotation(float time) const
|
||||
{
|
||||
float xrot = interpKey(mXRotations->mKeys, time);
|
||||
float yrot = interpKey(mYRotations->mKeys, time);
|
||||
float zrot = interpKey(mZRotations->mKeys, time);
|
||||
Ogre::Quaternion xr(Ogre::Radian(xrot), Ogre::Vector3::UNIT_X);
|
||||
Ogre::Quaternion yr(Ogre::Radian(yrot), Ogre::Vector3::UNIT_Y);
|
||||
Ogre::Quaternion zr(Ogre::Radian(zrot), Ogre::Vector3::UNIT_Z);
|
||||
return (xr*yr*zr);
|
||||
}
|
||||
|
||||
public:
|
||||
/// @note The NiKeyFrameData must be valid as long as this KeyframeController exists.
|
||||
Value(Ogre::Node *target, const Nif::NIFFilePtr& nif, const Nif::NiKeyframeData *data)
|
||||
: NodeTargetValue<Ogre::Real>(target)
|
||||
, mRotations(&data->mRotations)
|
||||
, mXRotations(&data->mXRotations)
|
||||
, mYRotations(&data->mYRotations)
|
||||
, mZRotations(&data->mZRotations)
|
||||
, mTranslations(&data->mTranslations)
|
||||
, mScales(&data->mScales)
|
||||
, mNif(nif)
|
||||
|
@ -486,6 +503,8 @@ public:
|
|||
{
|
||||
if(mRotations->mKeys.size() > 0)
|
||||
return interpKey(mRotations->mKeys, time);
|
||||
else if (!mXRotations->mKeys.empty() || !mYRotations->mKeys.empty() || !mZRotations->mKeys.empty())
|
||||
return getXYZRotation(time);
|
||||
return mNode->getOrientation();
|
||||
}
|
||||
|
||||
|
@ -513,6 +532,8 @@ public:
|
|||
{
|
||||
if(mRotations->mKeys.size() > 0)
|
||||
mNode->setOrientation(interpKey(mRotations->mKeys, time));
|
||||
else if (!mXRotations->mKeys.empty() || !mYRotations->mKeys.empty() || !mZRotations->mKeys.empty())
|
||||
mNode->setOrientation(getXYZRotation(time));
|
||||
if(mTranslations->mKeys.size() > 0)
|
||||
mNode->setPosition(interpKey(mTranslations->mKeys, time));
|
||||
if(mScales->mKeys.size() > 0)
|
||||
|
|
Loading…
Reference in a new issue