Rehash key group and morph loading (bug #6517)

pull/3225/head
Alexei Dobrohotov 2 years ago
parent 826553f2be
commit 26dfce1114

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

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

@ -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:

Loading…
Cancel
Save