mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 10:15:33 +00:00
Rewrite NiBlendInterpolator+friends loading
This commit is contained in:
parent
956ede52fb
commit
a224bea6d4
5 changed files with 142 additions and 143 deletions
|
@ -540,71 +540,63 @@ namespace 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))
|
||||
nif->read(mFlags);
|
||||
mItems.resize(nif->get<uint8_t>());
|
||||
nif->read(mWeightThreshold);
|
||||
if (!(mFlags & Flag_ManagerControlled))
|
||||
{
|
||||
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();
|
||||
}
|
||||
mInterpCount = nif->get<uint8_t>();
|
||||
mSingleIndex = nif->get<uint8_t>();
|
||||
mHighPriority = nif->get<int8_t>();
|
||||
mNextHighPriority = nif->get<int8_t>();
|
||||
nif->read(mSingleTime);
|
||||
nif->read(mHighWeightsSum);
|
||||
nif->read(mNextHighWeightsSum);
|
||||
nif->read(mHighEaseSpinner);
|
||||
for (Item& item : mItems)
|
||||
item.read(nif);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mManagerControlled)
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 110))
|
||||
{
|
||||
mItems.resize(numInterps);
|
||||
mItems.resize(nif->get<uint8_t>());
|
||||
for (Item& item : mItems)
|
||||
item.read(nif);
|
||||
if (nif->get<bool>())
|
||||
mFlags |= Flag_ManagerControlled;
|
||||
nif->read(mWeightThreshold);
|
||||
if (nif->get<bool>())
|
||||
mFlags |= Flag_OnlyUseHighestWeight;
|
||||
mInterpCount = nif->get<uint8_t>();
|
||||
mSingleIndex = nif->get<uint8_t>();
|
||||
mSingleInterpolator.read(nif);
|
||||
nif->read(mSingleTime);
|
||||
mHighPriority = nif->get<int8_t>();
|
||||
mNextHighPriority = nif->get<int8_t>();
|
||||
return;
|
||||
}
|
||||
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 111))
|
||||
mItems.resize(nif->get<uint16_t>());
|
||||
nif->read(mArrayGrowBy);
|
||||
for (Item& item : mItems)
|
||||
item.read(nif);
|
||||
if (nif->get<bool>())
|
||||
mFlags |= Flag_ManagerControlled;
|
||||
nif->read(mWeightThreshold);
|
||||
if (nif->get<bool>())
|
||||
mFlags |= Flag_OnlyUseHighestWeight;
|
||||
nif->read(mInterpCount);
|
||||
nif->read(mSingleIndex);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 108))
|
||||
{
|
||||
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();
|
||||
}
|
||||
mSingleInterpolator.read(nif);
|
||||
nif->read(mSingleTime);
|
||||
}
|
||||
nif->read(mHighPriority);
|
||||
nif->read(mNextHighPriority);
|
||||
}
|
||||
|
||||
void NiBlendInterpolator::post(Reader& nif)
|
||||
|
@ -617,13 +609,13 @@ namespace 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();
|
||||
nif->read(mWeight);
|
||||
nif->read(mNormalizedWeight);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 110))
|
||||
mPriority = nif->get<int8_t>();
|
||||
else
|
||||
mPriority = nif->getChar();
|
||||
mEaseSpinner = nif->getFloat();
|
||||
nif->read(mPriority);
|
||||
nif->read(mEaseSpinner);
|
||||
}
|
||||
|
||||
void NiBlendInterpolator::Item::post(Reader& nif)
|
||||
|
@ -631,38 +623,4 @@ 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();
|
||||
nif->read(mRotValue);
|
||||
mScaleValue = nif->getFloat();
|
||||
if (!nif->getBoolean())
|
||||
mPosValue = osg::Vec3f();
|
||||
if (!nif->getBoolean())
|
||||
mRotValue = osg::Quat();
|
||||
if (!nif->getBoolean())
|
||||
mScaleValue = 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,8 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008-2010 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: https://openmw.org/
|
||||
|
||||
This file (controller.h) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
https://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
#ifndef OPENMW_COMPONENTS_NIF_CONTROLLER_HPP
|
||||
#define OPENMW_COMPONENTS_NIF_CONTROLLER_HPP
|
||||
|
||||
#include "base.hpp"
|
||||
#include "niftypes.hpp"
|
||||
#include "property.hpp"
|
||||
|
||||
namespace Nif
|
||||
|
@ -378,24 +356,29 @@ namespace Nif
|
|||
// Abstract
|
||||
struct NiBlendInterpolator : public NiInterpolator
|
||||
{
|
||||
enum Flags
|
||||
{
|
||||
Flag_ManagerControlled = 0x1,
|
||||
Flag_OnlyUseHighestWeight = 0x2,
|
||||
};
|
||||
|
||||
struct Item
|
||||
{
|
||||
NiInterpolatorPtr mInterpolator;
|
||||
float mWeight, mNormalizedWeight;
|
||||
int mPriority;
|
||||
int32_t mPriority;
|
||||
float mEaseSpinner;
|
||||
|
||||
void read(NIFStream* nif);
|
||||
void post(Reader& nif);
|
||||
};
|
||||
|
||||
bool mManagerControlled{ false };
|
||||
bool mOnlyUseHighestWeight{ false };
|
||||
unsigned short mArrayGrowBy{ 0 };
|
||||
uint8_t mFlags{ 0 };
|
||||
uint16_t mArrayGrowBy{ 0 };
|
||||
float mWeightThreshold;
|
||||
unsigned short mInterpCount;
|
||||
unsigned short mSingleIndex;
|
||||
int mHighPriority, mNextHighPriority;
|
||||
uint16_t mInterpCount;
|
||||
uint16_t mSingleIndex;
|
||||
int32_t mHighPriority, mNextHighPriority;
|
||||
float mSingleTime;
|
||||
float mHighWeightsSum, mNextHighWeightsSum;
|
||||
float mHighEaseSpinner;
|
||||
|
@ -406,31 +389,37 @@ namespace Nif
|
|||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiBlendBoolInterpolator : public NiBlendInterpolator
|
||||
template <typename T>
|
||||
struct TypedNiBlendInterpolator : public NiBlendInterpolator
|
||||
{
|
||||
char mValue;
|
||||
void read(NIFStream* nif) override;
|
||||
T mValue;
|
||||
|
||||
void read(NIFStream* nif) override
|
||||
{
|
||||
NiBlendInterpolator::read(nif);
|
||||
|
||||
nif->read(mValue);
|
||||
}
|
||||
};
|
||||
|
||||
struct NiBlendFloatInterpolator : public NiBlendInterpolator
|
||||
template <>
|
||||
struct TypedNiBlendInterpolator<NiQuatTransform> : public NiBlendInterpolator
|
||||
{
|
||||
float mValue;
|
||||
void read(NIFStream* nif) override;
|
||||
NiQuatTransform mValue;
|
||||
|
||||
void read(NIFStream* nif) override
|
||||
{
|
||||
NiBlendInterpolator::read(nif);
|
||||
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109))
|
||||
nif->read(mValue);
|
||||
}
|
||||
};
|
||||
|
||||
struct NiBlendPoint3Interpolator : public NiBlendInterpolator
|
||||
{
|
||||
osg::Vec3f mValue;
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
using NiBlendBoolInterpolator = TypedNiBlendInterpolator<uint8_t>;
|
||||
using NiBlendFloatInterpolator = TypedNiBlendInterpolator<float>;
|
||||
using NiBlendPoint3Interpolator = TypedNiBlendInterpolator<osg::Vec3f>;
|
||||
using NiBlendTransformInterpolator = TypedNiBlendInterpolator<NiQuatTransform>;
|
||||
|
||||
struct NiBlendTransformInterpolator : public NiBlendInterpolator
|
||||
{
|
||||
osg::Vec3f mPosValue;
|
||||
osg::Quat mRotValue;
|
||||
float mScaleValue;
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
} // Namespace
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -137,6 +137,22 @@ namespace Nif
|
|||
read(transform.mScale);
|
||||
}
|
||||
|
||||
template <>
|
||||
void NIFStream::read<NiQuatTransform>(NiQuatTransform& transform)
|
||||
{
|
||||
read(transform.mTranslation);
|
||||
read(transform.mRotation);
|
||||
read(transform.mScale);
|
||||
if (getVersion() >= generateVersion(10, 1, 0, 110))
|
||||
return;
|
||||
if (!get<bool>())
|
||||
transform.mTranslation = osg::Vec3f();
|
||||
if (!get<bool>())
|
||||
transform.mRotation = osg::Quat();
|
||||
if (!get<bool>())
|
||||
transform.mScale = 1.f;
|
||||
}
|
||||
|
||||
template <>
|
||||
void NIFStream::read<bool>(bool& data)
|
||||
{
|
||||
|
@ -197,6 +213,12 @@ namespace Nif
|
|||
readRange(*this, dest, size);
|
||||
}
|
||||
|
||||
template <>
|
||||
void NIFStream::read<NiQuatTransform>(NiQuatTransform* dest, size_t size)
|
||||
{
|
||||
readRange(*this, dest, size);
|
||||
}
|
||||
|
||||
template <>
|
||||
void NIFStream::read<bool>(bool* dest, size_t size)
|
||||
{
|
||||
|
|
|
@ -175,6 +175,8 @@ namespace Nif
|
|||
template <>
|
||||
void NIFStream::read<NiTransform>(NiTransform& transform);
|
||||
template <>
|
||||
void NIFStream::read<NiQuatTransform>(NiQuatTransform& transform);
|
||||
template <>
|
||||
void NIFStream::read<bool>(bool& data);
|
||||
template <>
|
||||
void NIFStream::read<std::string>(std::string& str);
|
||||
|
@ -194,6 +196,8 @@ namespace Nif
|
|||
template <>
|
||||
void NIFStream::read<NiTransform>(NiTransform* dest, size_t size);
|
||||
template <>
|
||||
void NIFStream::read<NiQuatTransform>(NiQuatTransform* dest, size_t size);
|
||||
template <>
|
||||
void NIFStream::read<bool>(bool* dest, size_t size);
|
||||
template <>
|
||||
void NIFStream::read<std::string>(std::string* dest, size_t size);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define OPENMW_COMPONENTS_NIF_NIFTYPES_HPP
|
||||
|
||||
#include <osg/Matrixf>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Vec3f>
|
||||
|
||||
// Common types used in NIF files
|
||||
|
@ -80,5 +81,30 @@ namespace Nif
|
|||
}
|
||||
};
|
||||
|
||||
struct NiQuatTransform
|
||||
{
|
||||
osg::Vec3f mTranslation;
|
||||
osg::Quat mRotation;
|
||||
float mScale;
|
||||
|
||||
osg::Matrixf toMatrix() const
|
||||
{
|
||||
osg::Matrixf transform(mRotation);
|
||||
transform.setTrans(mTranslation);
|
||||
for (int i = 0; i < 3; i++)
|
||||
transform(i, i) *= mScale;
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
bool isIdentity() const { return mTranslation == osg::Vec3f() && mRotation == osg::Quat() && mScale == 1.f; }
|
||||
|
||||
static const NiQuatTransform& getIdentity()
|
||||
{
|
||||
static const NiQuatTransform identity = { osg::Vec3f(), osg::Quat(), 1.f };
|
||||
return identity;
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue