summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexei Dobrohotov <alexdobrohotov@yandex.ru>2021-12-23 23:38:57 +0300
committerAlexei Dobrohotov <alexdobrohotov@yandex.ru>2021-12-24 07:21:30 +0300
commit26dfce11148a421edd49918a1bc6ed382bb809a7 (patch)
treed0dfc32a1d0dc6d87a5274b98c2c3433399d0022
parent826553f2beedbcaab26bf225a9452b4d6a0dca21 (diff)
Rehash key group and morph loading (bug #6517)
-rw-r--r--CHANGELOG.md1
-rw-r--r--components/nif/data.cpp8
-rw-r--r--components/nif/nifkey.hpp71
3 files changed, 30 insertions, 50 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38cd1efca5..e4094f0ec2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -91,6 +91,7 @@
Bug #6451: Weapon summoned from Cast When Used item will have the name "None"
Bug #6473: Strings from NIF should be parsed only to first null terminator
Bug #6493: Unlocking owned but not locked or unlocked containers is considered a crime
+ Bug #6517: Rotations for KeyframeData in NIFs should be optional
Feature #890: OpenMW-CS: Column filtering
Feature #1465: "Reset" argument for AI functions
Feature #2554: Modifying an object triggers the instances table to scroll to the corresponding record
diff --git a/components/nif/data.cpp b/components/nif/data.cpp
index cac924733d..1b6d302d68 100644
--- a/components/nif/data.cpp
+++ b/components/nif/data.cpp
@@ -428,7 +428,7 @@ void NiMorphData::read(NIFStream *nif)
for(int i = 0;i < morphCount;i++)
{
mMorphs[i].mKeyFrames = std::make_shared<FloatKeyMap>();
- mMorphs[i].mKeyFrames->read(nif, true, /*morph*/true);
+ mMorphs[i].mKeyFrames->read(nif, /*morph*/true);
nif->getVector3s(mMorphs[i].mVertices, vertCount);
}
}
@@ -445,9 +445,9 @@ void NiKeyframeData::read(NIFStream *nif)
mXRotations = std::make_shared<FloatKeyMap>();
mYRotations = std::make_shared<FloatKeyMap>();
mZRotations = std::make_shared<FloatKeyMap>();
- mXRotations->read(nif, true);
- mYRotations->read(nif, true);
- mZRotations->read(nif, true);
+ mXRotations->read(nif);
+ mYRotations->read(nif);
+ mZRotations->read(nif);
}
mTranslations = std::make_shared<Vector3KeyMap>();
mTranslations->read(nif);
diff --git a/components/nif/nifkey.hpp b/components/nif/nifkey.hpp
index 91869ff849..f1b4f94d00 100644
--- a/components/nif/nifkey.hpp
+++ b/components/nif/nifkey.hpp
@@ -48,93 +48,72 @@ struct KeyMapT {
using ValueType = T;
using KeyType = KeyT<T>;
- unsigned int mInterpolationType = InterpolationType_Linear;
+ unsigned int mInterpolationType = InterpolationType_Unknown;
MapType mKeys;
//Read in a KeyGroup (see http://niftools.sourceforge.net/doc/nif/NiKeyframeData.html)
- void read(NIFStream *nif, bool force = false, bool morph = false)
+ void read(NIFStream *nif, bool morph = false)
{
assert(nif);
- mInterpolationType = InterpolationType_Unknown;
-
if (morph && nif->getVersion() >= NIFStream::generateVersion(10,1,0,106))
nif->getString(); // Frame name
size_t count = nif->getUInt();
- if (count == 0 && !force && !morph)
- return;
-
- if (morph && nif->getVersion() > NIFStream::generateVersion(10,1,0,0))
- {
- if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,104) &&
- nif->getVersion() <= NIFStream::generateVersion(20,1,0,2) && nif->getBethVersion() < 10)
- nif->getFloat(); // Legacy weight
- return;
- }
- mKeys.clear();
-
- mInterpolationType = nif->getUInt();
+ if (count != 0 || morph)
+ mInterpolationType = nif->getUInt();
KeyType key = {};
- NIFStream &nifReference = *nif;
- if (mInterpolationType == InterpolationType_Linear
- || mInterpolationType == InterpolationType_Constant)
+ if (mInterpolationType == InterpolationType_Linear || mInterpolationType == InterpolationType_Constant)
{
- for(size_t i = 0;i < count;i++)
+ for (size_t i = 0;i < count;i++)
{
float time = nif->getFloat();
- readValue(nifReference, key);
+ readValue(*nif, key);
mKeys[time] = key;
}
}
else if (mInterpolationType == InterpolationType_Quadratic)
{
- for(size_t i = 0;i < count;i++)
+ for (size_t i = 0;i < count;i++)
{
float time = nif->getFloat();
- readQuadratic(nifReference, key);
+ readQuadratic(*nif, key);
mKeys[time] = key;
}
}
else if (mInterpolationType == InterpolationType_TBC)
{
- for(size_t i = 0;i < count;i++)
+ for (size_t i = 0;i < count;i++)
{
float time = nif->getFloat();
- readTBC(nifReference, key);
+ readTBC(*nif, key);
mKeys[time] = key;
}
}
- //XYZ keys aren't actually read here.
- //data.hpp sees that the last type read was InterpolationType_XYZ and:
- // Eats a floating point number, then
- // Re-runs the read function 3 more times.
- // When it does that it's reading in a bunch of InterpolationType_Linear keys, not InterpolationType_XYZ.
- else if(mInterpolationType == InterpolationType_XYZ)
- {
- //Don't try to read XYZ keys into the wrong part
- if ( count != 1 )
- {
- std::stringstream error;
- error << "XYZ_ROTATION_KEY count should always be '1' . Retrieved Value: "
- << count;
- nif->file->fail(error.str());
- }
- }
- else if (mInterpolationType == InterpolationType_Unknown)
+ else if (mInterpolationType == InterpolationType_XYZ)
{
- if (count != 0)
- nif->file->fail("Interpolation type 0 doesn't work with keys");
+ //XYZ keys aren't actually read here.
+ //data.cpp sees that the last type read was InterpolationType_XYZ and:
+ // Eats a floating point number, then
+ // Re-runs the read function 3 more times.
+ // When it does that it's reading in a bunch of InterpolationType_Linear keys, not InterpolationType_XYZ.
}
- else
+ else if (count != 0 || morph)
{
std::stringstream error;
error << "Unhandled interpolation type: " << mInterpolationType;
nif->file->fail(error.str());
}
+
+ if (morph && nif->getVersion() > NIFStream::generateVersion(10,1,0,0))
+ {
+ if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,104) &&
+ nif->getVersion() <= NIFStream::generateVersion(20,1,0,2) && nif->getBethVersion() < 10)
+ nif->getFloat(); // Legacy weight
+ }
}
private: