From 7ecf01874300ef8415154774db3ed9c51ffef4f3 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Wed, 8 Feb 2023 22:58:47 +0300 Subject: [PATCH 1/3] Add NiBlendInterpolator --- components/nif/controller.cpp | 93 +++++++++++++++++++++++++++++++++++ components/nif/controller.hpp | 31 ++++++++++++ 2 files changed, 124 insertions(+) diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index 16d553cec8..47d1cbed8d 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -502,4 +502,97 @@ namespace Nif data.post(nif); } + void NiBlendInterpolator::read(NIFStream* nif) + { + if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 112)) + mManagerControlled = nif->getChar() & 1; + size_t numInterps = 0; + if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109)) + { + numInterps = nif->getUShort(); + mArrayGrowBy = nif->getUShort(); + } + else + { + numInterps = nif->getChar(); + if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 112)) + { + mWeightThreshold = nif->getFloat(); + if (!mManagerControlled) + { + mInterpCount = nif->getChar(); + mSingleIndex = nif->getChar(); + mHighPriority = nif->getChar(); + mNextHighPriority = nif->getChar(); + mSingleTime = nif->getFloat(); + mHighWeightsSum = nif->getFloat(); + mNextHighWeightsSum = nif->getFloat(); + mHighEaseSpinner = nif->getFloat(); + } + } + } + + if (!mManagerControlled) + { + mItems.resize(numInterps); + for (Item& item : mItems) + item.read(nif); + } + + if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 111)) + { + mManagerControlled = nif->getBoolean(); + mWeightThreshold = nif->getFloat(); + mOnlyUseHighestWeight = nif->getBoolean(); + if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109)) + { + mInterpCount = nif->getUShort(); + mSingleIndex = nif->getUShort(); + } + else + { + mInterpCount = nif->getChar(); + mSingleIndex = nif->getChar(); + } + if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 108)) + { + mSingleInterpolator.read(nif); + mSingleTime = nif->getFloat(); + } + if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109)) + { + mHighPriority = nif->getInt(); + mNextHighPriority = nif->getInt(); + } + else + { + mHighPriority = nif->getChar(); + mNextHighPriority = nif->getChar(); + } + } + } + + void NiBlendInterpolator::post(Reader& nif) + { + for (Item& item : mItems) + item.post(nif); + mSingleInterpolator.post(nif); + } + + void NiBlendInterpolator::Item::read(NIFStream* nif) + { + mInterpolator.read(nif); + mWeight = nif->getFloat(); + mNormalizedWeight = nif->getFloat(); + if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109)) + mPriority = nif->getInt(); + else + mPriority = nif->getChar(); + mEaseSpinner = nif->getFloat(); + } + + void NiBlendInterpolator::Item::post(Reader& nif) + { + mInterpolator.post(nif); + } } diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index a5213a9be7..d5b8fad4d3 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -345,5 +345,36 @@ namespace Nif void post(Reader& nif) override; }; + // Abstract + struct NiBlendInterpolator : public NiInterpolator + { + struct Item + { + NiInterpolatorPtr mInterpolator; + float mWeight, mNormalizedWeight; + int mPriority; + float mEaseSpinner; + + void read(NIFStream* nif); + void post(Reader& nif); + }; + + bool mManagerControlled{ false }; + bool mOnlyUseHighestWeight{ false }; + unsigned short mArrayGrowBy{ 0 }; + float mWeightThreshold; + unsigned short mInterpCount; + unsigned short mSingleIndex; + int mHighPriority, mNextHighPriority; + float mSingleTime; + float mHighWeightsSum, mNextHighWeightsSum; + float mHighEaseSpinner; + std::vector mItems; + NiInterpolatorPtr mSingleInterpolator; + + void read(NIFStream* nif) override; + void post(Reader& nif) override; + }; + } // Namespace #endif From 091fcd837ed8df652d8384ca6d100bb686087cc8 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Wed, 8 Feb 2023 23:13:36 +0300 Subject: [PATCH 2/3] Read all the NiBlendInterpolator record types --- components/nif/controller.cpp | 38 ++++++++++++++++++++++++++++++++++- components/nif/controller.hpp | 27 +++++++++++++++++++++++++ components/nif/niffile.cpp | 5 +++++ components/nif/record.hpp | 4 ++++ components/nif/recordptr.hpp | 2 ++ 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index 47d1cbed8d..dd4261edd7 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -43,7 +43,7 @@ namespace Nif if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 110)) { - nif->skip(4); // NiBlendInterpolator link + mBlendInterpolator.read(nif); mBlendIndex = nif->getUShort(); } if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 106) && nif->getBethVersion() > 0) @@ -73,6 +73,7 @@ namespace Nif { mInterpolator.post(nif); mController.post(nif); + mBlendInterpolator.post(nif); mStringPalette.post(nif); // TODO: probably should fill the strings with string palette contents here } @@ -595,4 +596,39 @@ namespace Nif { mInterpolator.post(nif); } + + void NiBlendBoolInterpolator::read(NIFStream* nif) + { + NiBlendInterpolator::read(nif); + mValue = nif->getChar() != 0; + } + + void NiBlendFloatInterpolator::read(NIFStream* nif) + { + NiBlendInterpolator::read(nif); + mValue = nif->getFloat(); + } + + void NiBlendPoint3Interpolator::read(NIFStream* nif) + { + NiBlendInterpolator::read(nif); + mValue = nif->getVector3(); + } + + void NiBlendTransformInterpolator::read(NIFStream* nif) + { + NiBlendInterpolator::read(nif); + if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109)) + { + mPosValue = nif->getVector3(); + mRotValue = nif->getQuaternion(); + mScaleValue = nif->getFloat(); + if (!nif->getBoolean()) + mPosValue = osg::Vec3f(); + if (!nif->getBoolean()) + mRotValue = osg::Quat(); + if (!nif->getBoolean()) + mScaleValue = 1.f; + } + } } diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index d5b8fad4d3..ff90f55dee 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -34,6 +34,7 @@ namespace Nif std::string mTargetName; NiInterpolatorPtr mInterpolator; ControllerPtr mController; + NiBlendInterpolatorPtr mBlendInterpolator; unsigned short mBlendIndex; unsigned char mPriority; NiStringPalettePtr mStringPalette; @@ -376,5 +377,31 @@ namespace Nif void post(Reader& nif) override; }; + struct NiBlendBoolInterpolator : public NiBlendInterpolator + { + char mValue; + void read(NIFStream* nif) override; + }; + + struct NiBlendFloatInterpolator : public NiBlendInterpolator + { + float mValue; + void read(NIFStream* nif) override; + }; + + struct NiBlendPoint3Interpolator : public NiBlendInterpolator + { + osg::Vec3f mValue; + void read(NIFStream* nif) override; + }; + + struct NiBlendTransformInterpolator : public NiBlendInterpolator + { + osg::Vec3f mPosValue; + osg::Quat mRotValue; + float mScaleValue; + void read(NIFStream* nif) override; + }; + } // Namespace #endif diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index fb3d92ff4f..ac5f3dfddc 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -175,6 +175,11 @@ namespace Nif { "NiSequence", &construct }, { "NiControllerSequence", &construct }, { "NiDefaultAVObjectPalette", &construct }, + { "NiBlendBoolInterpolator", &construct }, + { "NiBlendFloatInterpolator", &construct }, + { "NiBlendPoint3Interpolator", &construct }, + { "NiBlendTransformInterpolator", + &construct }, }; } diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 558066b8c6..bc2fa41409 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -152,6 +152,10 @@ namespace Nif RC_NiSequence, RC_NiControllerSequence, RC_NiDefaultAVObjectPalette, + RC_NiBlendBoolInterpolator, + RC_NiBlendFloatInterpolator, + RC_NiBlendPoint3Interpolator, + RC_NiBlendTransformInterpolator, }; /// Base class for all records diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index cb85763a22..b7ad9d3dbb 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -142,6 +142,7 @@ namespace Nif struct NiInterpolator; struct NiStringPalette; struct NiControllerManager; + struct NiBlendInterpolator; using NodePtr = RecordPtrT; using ExtraPtr = RecordPtrT; @@ -174,6 +175,7 @@ namespace Nif using NiInterpolatorPtr = RecordPtrT; using NiStringPalettePtr = RecordPtrT; using NiControllerManagerPtr = RecordPtrT; + using NiBlendInterpolatorPtr = RecordPtrT; using NodeList = RecordListT; using PropertyList = RecordListT; From d7834c43e5082aabb54a4d17981147a775c2f568 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Wed, 8 Feb 2023 23:35:22 +0300 Subject: [PATCH 3/3] Fill in NiControllerManager fields --- components/nif/controller.cpp | 12 +++++++++--- components/nif/controller.hpp | 3 +++ components/nif/recordptr.hpp | 4 ++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index dd4261edd7..32291b8c12 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -432,9 +432,15 @@ namespace Nif { Controller::read(nif); mCumulative = nif->getBoolean(); - unsigned int numSequences = nif->getUInt(); - nif->skip(4 * numSequences); // Controller sequences - nif->skip(4); // Object palette + readRecordList(nif, mSequences); + mObjectPalette.read(nif); + } + + void NiControllerManager::post(Reader& nif) + { + Controller::post(nif); + postRecordList(nif, mSequences); + mObjectPalette.post(nif); } void NiPoint3Interpolator::read(NIFStream* nif) diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index ff90f55dee..3f9c054906 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -296,7 +296,10 @@ namespace Nif struct NiControllerManager : public Controller { bool mCumulative; + NiControllerSequenceList mSequences; + NiDefaultAVObjectPalettePtr mObjectPalette; void read(NIFStream* nif) override; + void post(Reader& nif) override; }; struct NiInterpolator : public Record diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index b7ad9d3dbb..5fa0d7d203 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -143,6 +143,8 @@ namespace Nif struct NiStringPalette; struct NiControllerManager; struct NiBlendInterpolator; + struct NiDefaultAVObjectPalette; + struct NiControllerSequence; using NodePtr = RecordPtrT; using ExtraPtr = RecordPtrT; @@ -176,6 +178,7 @@ namespace Nif using NiStringPalettePtr = RecordPtrT; using NiControllerManagerPtr = RecordPtrT; using NiBlendInterpolatorPtr = RecordPtrT; + using NiDefaultAVObjectPalettePtr = RecordPtrT; using NodeList = RecordListT; using PropertyList = RecordListT; @@ -185,6 +188,7 @@ namespace Nif using NiTriStripsDataList = RecordListT; using bhkShapeList = RecordListT; using bhkSerializableList = RecordListT; + using NiControllerSequenceList = RecordListT; } // Namespace #endif