forked from teamnwah/openmw-tes3coop
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
|
struct NiKeyframeData : public Record
|
||||||
{
|
{
|
||||||
QuaternionKeyMap mRotations;
|
QuaternionKeyMap mRotations;
|
||||||
//\FIXME mXYZ_Keys are read, but not used.
|
|
||||||
FloatKeyMap mXYZ_Keys;
|
FloatKeyMap mXRotations;
|
||||||
|
FloatKeyMap mYRotations;
|
||||||
|
FloatKeyMap mZRotations;
|
||||||
|
|
||||||
Vector3KeyMap mTranslations;
|
Vector3KeyMap mTranslations;
|
||||||
FloatKeyMap mScales;
|
FloatKeyMap mScales;
|
||||||
|
|
||||||
|
@ -362,12 +365,9 @@ struct NiKeyframeData : public Record
|
||||||
{
|
{
|
||||||
//Chomp unused float
|
//Chomp unused float
|
||||||
nif->getFloat();
|
nif->getFloat();
|
||||||
for(size_t i=0;i<3;++i)
|
mXRotations.read(nif, true);
|
||||||
{
|
mYRotations.read(nif, true);
|
||||||
//Read concatenates items together.
|
mZRotations.read(nif, true);
|
||||||
mXYZ_Keys.read(nif,true);
|
|
||||||
}
|
|
||||||
nif->file->warn("XYZ_ROTATION_KEY read, but not used!");
|
|
||||||
}
|
}
|
||||||
mTranslations.read(nif);
|
mTranslations.read(nif);
|
||||||
mScales.read(nif);
|
mScales.read(nif);
|
||||||
|
|
|
@ -49,9 +49,7 @@ struct KeyMapT {
|
||||||
if(count == 0 && !force)
|
if(count == 0 && !force)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//If we aren't forcing things, make sure that read clears any previous keys
|
mKeys.clear();
|
||||||
if(!force)
|
|
||||||
mKeys.clear();
|
|
||||||
|
|
||||||
mInterpolationType = nif->getUInt();
|
mInterpolationType = nif->getUInt();
|
||||||
|
|
||||||
|
@ -88,7 +86,7 @@ struct KeyMapT {
|
||||||
//XYZ keys aren't actually read here.
|
//XYZ keys aren't actually read here.
|
||||||
//data.hpp sees that the last type read was sXYZInterpolation and:
|
//data.hpp sees that the last type read was sXYZInterpolation and:
|
||||||
// Eats a floating point number, then
|
// 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.
|
// When it does that it's reading in a bunch of sLinearInterpolation keys, not sXYZInterpolation.
|
||||||
else if(mInterpolationType == sXYZInterpolation)
|
else if(mInterpolationType == sXYZInterpolation)
|
||||||
{
|
{
|
||||||
|
|
|
@ -442,6 +442,9 @@ public:
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const Nif::QuaternionKeyMap* mRotations;
|
const Nif::QuaternionKeyMap* mRotations;
|
||||||
|
const Nif::FloatKeyMap* mXRotations;
|
||||||
|
const Nif::FloatKeyMap* mYRotations;
|
||||||
|
const Nif::FloatKeyMap* mZRotations;
|
||||||
const Nif::Vector3KeyMap* mTranslations;
|
const Nif::Vector3KeyMap* mTranslations;
|
||||||
const Nif::FloatKeyMap* mScales;
|
const Nif::FloatKeyMap* mScales;
|
||||||
Nif::NIFFilePtr mNif; // Hold a SharedPtr to make sure key lists stay valid
|
Nif::NIFFilePtr mNif; // Hold a SharedPtr to make sure key lists stay valid
|
||||||
|
@ -472,11 +475,25 @@ public:
|
||||||
return keys.rbegin()->second.mValue;
|
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:
|
public:
|
||||||
/// @note The NiKeyFrameData must be valid as long as this KeyframeController exists.
|
/// @note The NiKeyFrameData must be valid as long as this KeyframeController exists.
|
||||||
Value(Ogre::Node *target, const Nif::NIFFilePtr& nif, const Nif::NiKeyframeData *data)
|
Value(Ogre::Node *target, const Nif::NIFFilePtr& nif, const Nif::NiKeyframeData *data)
|
||||||
: NodeTargetValue<Ogre::Real>(target)
|
: NodeTargetValue<Ogre::Real>(target)
|
||||||
, mRotations(&data->mRotations)
|
, mRotations(&data->mRotations)
|
||||||
|
, mXRotations(&data->mXRotations)
|
||||||
|
, mYRotations(&data->mYRotations)
|
||||||
|
, mZRotations(&data->mZRotations)
|
||||||
, mTranslations(&data->mTranslations)
|
, mTranslations(&data->mTranslations)
|
||||||
, mScales(&data->mScales)
|
, mScales(&data->mScales)
|
||||||
, mNif(nif)
|
, mNif(nif)
|
||||||
|
@ -486,6 +503,8 @@ public:
|
||||||
{
|
{
|
||||||
if(mRotations->mKeys.size() > 0)
|
if(mRotations->mKeys.size() > 0)
|
||||||
return interpKey(mRotations->mKeys, time);
|
return interpKey(mRotations->mKeys, time);
|
||||||
|
else if (!mXRotations->mKeys.empty() || !mYRotations->mKeys.empty() || !mZRotations->mKeys.empty())
|
||||||
|
return getXYZRotation(time);
|
||||||
return mNode->getOrientation();
|
return mNode->getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,6 +532,8 @@ public:
|
||||||
{
|
{
|
||||||
if(mRotations->mKeys.size() > 0)
|
if(mRotations->mKeys.size() > 0)
|
||||||
mNode->setOrientation(interpKey(mRotations->mKeys, time));
|
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)
|
if(mTranslations->mKeys.size() > 0)
|
||||||
mNode->setPosition(interpKey(mTranslations->mKeys, time));
|
mNode->setPosition(interpKey(mTranslations->mKeys, time));
|
||||||
if(mScales->mKeys.size() > 0)
|
if(mScales->mKeys.size() > 0)
|
||||||
|
|
Loading…
Reference in a new issue