mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-30 11:06:43 +00:00
Read a few more NIF types
NiFloatInterpolator, NiPoint3Interpolator, NiTransformInterpolator, NiBoolInterpolator Update a few existing controller records Update NiSkinInstance
This commit is contained in:
parent
ed8342ebc9
commit
f3f5dcb016
10 changed files with 299 additions and 21 deletions
|
@ -92,6 +92,8 @@ namespace Nif
|
||||||
void NiMaterialColorController::read(NIFStream *nif)
|
void NiMaterialColorController::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
Controller::read(nif);
|
Controller::read(nif);
|
||||||
|
if (nif->getVersion() > NIFStream::generateVersion(10,1,0,103))
|
||||||
|
interpolator.read(nif);
|
||||||
// Two bits that correspond to the controlled material color.
|
// Two bits that correspond to the controlled material color.
|
||||||
// 00: Ambient
|
// 00: Ambient
|
||||||
// 01: Diffuse
|
// 01: Diffuse
|
||||||
|
@ -101,12 +103,14 @@ namespace Nif
|
||||||
targetColor = nif->getUShort() & 3;
|
targetColor = nif->getUShort() & 3;
|
||||||
else
|
else
|
||||||
targetColor = (flags >> 4) & 3;
|
targetColor = (flags >> 4) & 3;
|
||||||
|
if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103))
|
||||||
data.read(nif);
|
data.read(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiMaterialColorController::post(NIFFile *nif)
|
void NiMaterialColorController::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
Controller::post(nif);
|
Controller::post(nif);
|
||||||
|
interpolator.post(nif);
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,25 +165,33 @@ namespace Nif
|
||||||
void NiKeyframeController::read(NIFStream *nif)
|
void NiKeyframeController::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
Controller::read(nif);
|
Controller::read(nif);
|
||||||
|
if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103))
|
||||||
data.read(nif);
|
data.read(nif);
|
||||||
|
else
|
||||||
|
interpolator.read(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiKeyframeController::post(NIFFile *nif)
|
void NiKeyframeController::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
Controller::post(nif);
|
Controller::post(nif);
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
|
interpolator.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiFloatInterpController::read(NIFStream *nif)
|
void NiFloatInterpController::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
Controller::read(nif);
|
Controller::read(nif);
|
||||||
|
if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103))
|
||||||
data.read(nif);
|
data.read(nif);
|
||||||
|
else
|
||||||
|
interpolator.read(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiFloatInterpController::post(NIFFile *nif)
|
void NiFloatInterpController::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
Controller::post(nif);
|
Controller::post(nif);
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
|
interpolator.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiGeomMorpherController::read(NIFStream *nif)
|
void NiGeomMorpherController::read(NIFStream *nif)
|
||||||
|
@ -189,13 +201,33 @@ namespace Nif
|
||||||
/*bool updateNormals = !!*/nif->getUShort();
|
/*bool updateNormals = !!*/nif->getUShort();
|
||||||
data.read(nif);
|
data.read(nif);
|
||||||
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
|
||||||
|
{
|
||||||
/*bool alwaysActive = */nif->getChar(); // Always 0
|
/*bool alwaysActive = */nif->getChar(); // Always 0
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,106))
|
||||||
|
{
|
||||||
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
||||||
|
{
|
||||||
|
interpolators.read(nif);
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0) && nif->getBethVersion() > 9)
|
||||||
|
{
|
||||||
|
unsigned int numUnknown = nif->getUInt();
|
||||||
|
nif->skip(4 * numUnknown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int numInterps = nif->getUInt();
|
||||||
|
nif->skip(8 * numInterps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiGeomMorpherController::post(NIFFile *nif)
|
void NiGeomMorpherController::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
Controller::post(nif);
|
Controller::post(nif);
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
|
interpolators.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiVisController::read(NIFStream *nif)
|
void NiVisController::read(NIFStream *nif)
|
||||||
|
@ -213,6 +245,8 @@ namespace Nif
|
||||||
void NiFlipController::read(NIFStream *nif)
|
void NiFlipController::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
Controller::read(nif);
|
Controller::read(nif);
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0))
|
||||||
|
mInterpolator.read(nif);
|
||||||
mTexSlot = nif->getUInt();
|
mTexSlot = nif->getUInt();
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103))
|
if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103))
|
||||||
{
|
{
|
||||||
|
@ -225,6 +259,7 @@ namespace Nif
|
||||||
void NiFlipController::post(NIFFile *nif)
|
void NiFlipController::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
Controller::post(nif);
|
Controller::post(nif);
|
||||||
|
mInterpolator.post(nif);
|
||||||
mSources.post(nif);
|
mSources.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,4 +269,59 @@ namespace Nif
|
||||||
nif->getUInt(); // Zero
|
nif->getUInt(); // Zero
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NiPoint3Interpolator::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
defaultVal = nif->getVector3();
|
||||||
|
data.read(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiPoint3Interpolator::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
data.post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiBoolInterpolator::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
defaultVal = nif->getBoolean();
|
||||||
|
data.read(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiBoolInterpolator::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
data.post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiFloatInterpolator::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
defaultVal = nif->getFloat();
|
||||||
|
data.read(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiFloatInterpolator::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
data.post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiTransformInterpolator::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
defaultPos = nif->getVector3();
|
||||||
|
defaultRot = nif->getQuaternion();
|
||||||
|
defaultScale = nif->getFloat();
|
||||||
|
if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,109))
|
||||||
|
{
|
||||||
|
if (!nif->getBoolean())
|
||||||
|
defaultPos = osg::Vec3f();
|
||||||
|
if (!nif->getBoolean())
|
||||||
|
defaultRot = osg::Quat();
|
||||||
|
if (!nif->getBoolean())
|
||||||
|
defaultScale = 1.f;
|
||||||
|
}
|
||||||
|
data.read(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiTransformInterpolator::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
data.post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ using NiBSPArrayController = NiParticleSystemController;
|
||||||
class NiMaterialColorController : public Controller
|
class NiMaterialColorController : public Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
NiPoint3InterpolatorPtr interpolator;
|
||||||
NiPosDataPtr data;
|
NiPosDataPtr data;
|
||||||
unsigned int targetColor;
|
unsigned int targetColor;
|
||||||
|
|
||||||
|
@ -138,6 +139,7 @@ class NiKeyframeController : public Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NiKeyframeDataPtr data;
|
NiKeyframeDataPtr data;
|
||||||
|
NiTransformInterpolatorPtr interpolator;
|
||||||
|
|
||||||
void read(NIFStream *nif) override;
|
void read(NIFStream *nif) override;
|
||||||
void post(NIFFile *nif) override;
|
void post(NIFFile *nif) override;
|
||||||
|
@ -146,6 +148,7 @@ public:
|
||||||
struct NiFloatInterpController : public Controller
|
struct NiFloatInterpController : public Controller
|
||||||
{
|
{
|
||||||
NiFloatDataPtr data;
|
NiFloatDataPtr data;
|
||||||
|
NiFloatInterpolatorPtr interpolator;
|
||||||
|
|
||||||
void read(NIFStream *nif) override;
|
void read(NIFStream *nif) override;
|
||||||
void post(NIFFile *nif) override;
|
void post(NIFFile *nif) override;
|
||||||
|
@ -158,6 +161,7 @@ class NiGeomMorpherController : public Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NiMorphDataPtr data;
|
NiMorphDataPtr data;
|
||||||
|
NiFloatInterpolatorList interpolators;
|
||||||
|
|
||||||
void read(NIFStream *nif) override;
|
void read(NIFStream *nif) override;
|
||||||
void post(NIFFile *nif) override;
|
void post(NIFFile *nif) override;
|
||||||
|
@ -175,6 +179,7 @@ public:
|
||||||
class NiFlipController : public Controller
|
class NiFlipController : public Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
NiFloatInterpolatorPtr mInterpolator;
|
||||||
int mTexSlot; // NiTexturingProperty::TextureType
|
int mTexSlot; // NiTexturingProperty::TextureType
|
||||||
float mDelta; // Time between two flips. delta = (start_time - stop_time) / num_sources
|
float mDelta; // Time between two flips. delta = (start_time - stop_time) / num_sources
|
||||||
NiSourceTextureList mSources;
|
NiSourceTextureList mSources;
|
||||||
|
@ -188,5 +193,42 @@ struct bhkBlendController : public Controller
|
||||||
void read(NIFStream *nif) override;
|
void read(NIFStream *nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Interpolator : public Record { };
|
||||||
|
|
||||||
|
struct NiPoint3Interpolator : public Interpolator
|
||||||
|
{
|
||||||
|
osg::Vec3f defaultVal;
|
||||||
|
NiPosDataPtr data;
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
void post(NIFFile *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NiBoolInterpolator : public Interpolator
|
||||||
|
{
|
||||||
|
bool defaultVal;
|
||||||
|
NiBoolDataPtr data;
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
void post(NIFFile *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NiFloatInterpolator : public Interpolator
|
||||||
|
{
|
||||||
|
float defaultVal;
|
||||||
|
NiFloatDataPtr data;
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
void post(NIFFile *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NiTransformInterpolator : public Interpolator
|
||||||
|
{
|
||||||
|
osg::Vec3f defaultPos;
|
||||||
|
osg::Quat defaultRot;
|
||||||
|
float defaultScale;
|
||||||
|
NiKeyframeDataPtr data;
|
||||||
|
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
void post(NIFFile *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,8 @@ namespace Nif
|
||||||
void NiSkinInstance::read(NIFStream *nif)
|
void NiSkinInstance::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
data.read(nif);
|
data.read(nif);
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,101))
|
||||||
|
partitions.read(nif);
|
||||||
root.read(nif);
|
root.read(nif);
|
||||||
bones.read(nif);
|
bones.read(nif);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +15,7 @@ void NiSkinInstance::read(NIFStream *nif)
|
||||||
void NiSkinInstance::post(NIFFile *nif)
|
void NiSkinInstance::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
|
partitions.post(nif);
|
||||||
root.post(nif);
|
root.post(nif);
|
||||||
bones.post(nif);
|
bones.post(nif);
|
||||||
|
|
||||||
|
@ -418,7 +421,7 @@ void NiMorphData::read(NIFStream *nif)
|
||||||
for(int i = 0;i < morphCount;i++)
|
for(int i = 0;i < morphCount;i++)
|
||||||
{
|
{
|
||||||
mMorphs[i].mKeyFrames = std::make_shared<FloatKeyMap>();
|
mMorphs[i].mKeyFrames = std::make_shared<FloatKeyMap>();
|
||||||
mMorphs[i].mKeyFrames->read(nif, true);
|
mMorphs[i].mKeyFrames->read(nif, true, /*morph*/true);
|
||||||
nif->getVector3s(mMorphs[i].mVertices, vertCount);
|
nif->getVector3s(mMorphs[i].mVertices, vertCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,11 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
|
||||||
factory["NiTransformData"] = {&construct <NiKeyframeData> , RC_NiKeyframeData };
|
factory["NiTransformData"] = {&construct <NiKeyframeData> , RC_NiKeyframeData };
|
||||||
factory["BSFadeNode"] = {&construct <NiNode> , RC_NiNode };
|
factory["BSFadeNode"] = {&construct <NiNode> , RC_NiNode };
|
||||||
factory["bhkBlendController"] = {&construct <bhkBlendController> , RC_bhkBlendController };
|
factory["bhkBlendController"] = {&construct <bhkBlendController> , RC_bhkBlendController };
|
||||||
|
factory["NiFloatInterpolator"] = {&construct <NiFloatInterpolator> , RC_NiFloatInterpolator };
|
||||||
|
factory["NiBoolInterpolator"] = {&construct <NiBoolInterpolator> , RC_NiBoolInterpolator };
|
||||||
|
factory["NiPoint3Interpolator"] = {&construct <NiPoint3Interpolator> , RC_NiPoint3Interpolator };
|
||||||
|
factory["NiTransformController"] = {&construct <NiKeyframeController> , RC_NiKeyframeController };
|
||||||
|
factory["NiTransformInterpolator"] = {&construct <NiTransformInterpolator> , RC_NiTransformInterpolator };
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,16 +52,27 @@ struct KeyMapT {
|
||||||
MapType mKeys;
|
MapType mKeys;
|
||||||
|
|
||||||
//Read in a KeyGroup (see http://niftools.sourceforge.net/doc/nif/NiKeyframeData.html)
|
//Read in a KeyGroup (see http://niftools.sourceforge.net/doc/nif/NiKeyframeData.html)
|
||||||
void read(NIFStream *nif, bool force=false)
|
void read(NIFStream *nif, bool force = false, bool morph = false)
|
||||||
{
|
{
|
||||||
assert(nif);
|
assert(nif);
|
||||||
|
|
||||||
mInterpolationType = InterpolationType_Unknown;
|
mInterpolationType = InterpolationType_Unknown;
|
||||||
|
|
||||||
|
if (morph && nif->getVersion() >= NIFStream::generateVersion(10,1,0,106))
|
||||||
|
nif->getString(); // Frame name
|
||||||
|
|
||||||
size_t count = nif->getUInt();
|
size_t count = nif->getUInt();
|
||||||
if(count == 0 && !force)
|
if (count == 0 && !force && !morph)
|
||||||
return;
|
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();
|
mKeys.clear();
|
||||||
|
|
||||||
mInterpolationType = nif->getUInt();
|
mInterpolationType = nif->getUInt();
|
||||||
|
|
|
@ -115,7 +115,11 @@ enum RecordType
|
||||||
RC_NiSkinPartition,
|
RC_NiSkinPartition,
|
||||||
RC_BSXFlags,
|
RC_BSXFlags,
|
||||||
RC_BSBound,
|
RC_BSBound,
|
||||||
RC_bhkBlendController
|
RC_bhkBlendController,
|
||||||
|
RC_NiFloatInterpolator,
|
||||||
|
RC_NiPoint3Interpolator,
|
||||||
|
RC_NiBoolInterpolator,
|
||||||
|
RC_NiTransformInterpolator,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for all records
|
/// Base class for all records
|
||||||
|
|
|
@ -145,6 +145,9 @@ struct NiParticleModifier;
|
||||||
struct NiLinesData;
|
struct NiLinesData;
|
||||||
struct NiBoolData;
|
struct NiBoolData;
|
||||||
struct NiSkinPartition;
|
struct NiSkinPartition;
|
||||||
|
struct NiFloatInterpolator;
|
||||||
|
struct NiPoint3Interpolator;
|
||||||
|
struct NiTransformInterpolator;
|
||||||
|
|
||||||
using NodePtr = RecordPtrT<Node>;
|
using NodePtr = RecordPtrT<Node>;
|
||||||
using ExtraPtr = RecordPtrT<Extra>;
|
using ExtraPtr = RecordPtrT<Extra>;
|
||||||
|
@ -170,11 +173,15 @@ using NiPalettePtr = RecordPtrT<NiPalette>;
|
||||||
using NiParticleModifierPtr = RecordPtrT<NiParticleModifier>;
|
using NiParticleModifierPtr = RecordPtrT<NiParticleModifier>;
|
||||||
using NiBoolDataPtr = RecordPtrT<NiBoolData>;
|
using NiBoolDataPtr = RecordPtrT<NiBoolData>;
|
||||||
using NiSkinPartitionPtr = RecordPtrT<NiSkinPartition>;
|
using NiSkinPartitionPtr = RecordPtrT<NiSkinPartition>;
|
||||||
|
using NiFloatInterpolatorPtr = RecordPtrT<NiFloatInterpolator>;
|
||||||
|
using NiPoint3InterpolatorPtr = RecordPtrT<NiPoint3Interpolator>;
|
||||||
|
using NiTransformInterpolatorPtr = RecordPtrT<NiTransformInterpolator>;
|
||||||
|
|
||||||
using NodeList = RecordListT<Node>;
|
using NodeList = RecordListT<Node>;
|
||||||
using PropertyList = RecordListT<Property>;
|
using PropertyList = RecordListT<Property>;
|
||||||
using ExtraList = RecordListT<Extra>;
|
using ExtraList = RecordListT<Extra>;
|
||||||
using NiSourceTextureList = RecordListT<NiSourceTexture>;
|
using NiSourceTextureList = RecordListT<NiSourceTexture>;
|
||||||
|
using NiFloatInterpolatorList = RecordListT<NiFloatInterpolator>;
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -92,6 +92,26 @@ KeyframeController::KeyframeController(const Nif::NiKeyframeData *data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyframeController::KeyframeController(const Nif::NiTransformInterpolator* interpolator)
|
||||||
|
: mRotations(interpolator->data->mRotations, interpolator->defaultRot)
|
||||||
|
, mXRotations(interpolator->data->mXRotations, 0.f)
|
||||||
|
, mYRotations(interpolator->data->mYRotations, 0.f)
|
||||||
|
, mZRotations(interpolator->data->mZRotations, 0.f)
|
||||||
|
, mTranslations(interpolator->data->mTranslations, interpolator->defaultPos)
|
||||||
|
, mScales(interpolator->data->mScales, interpolator->defaultScale)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeController::KeyframeController(const float scale, const osg::Vec3f& pos, const osg::Quat& rot)
|
||||||
|
: mRotations(Nif::QuaternionKeyMapPtr(), rot)
|
||||||
|
, mXRotations(Nif::FloatKeyMapPtr(), 0.f)
|
||||||
|
, mYRotations(Nif::FloatKeyMapPtr(), 0.f)
|
||||||
|
, mZRotations(Nif::FloatKeyMapPtr(), 0.f)
|
||||||
|
, mTranslations(Nif::Vector3KeyMapPtr(), pos)
|
||||||
|
, mScales(Nif::FloatKeyMapPtr(), scale)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
osg::Quat KeyframeController::getXYZRotation(float time) const
|
osg::Quat KeyframeController::getXYZRotation(float time) const
|
||||||
{
|
{
|
||||||
float xrot = 0, yrot = 0, zrot = 0;
|
float xrot = 0, yrot = 0, zrot = 0;
|
||||||
|
@ -313,6 +333,11 @@ RollController::RollController(const Nif::NiFloatData *data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RollController::RollController(const Nif::NiFloatInterpolator* interpolator)
|
||||||
|
: mData(interpolator)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RollController::RollController(const RollController ©, const osg::CopyOp ©op)
|
RollController::RollController(const RollController ©, const osg::CopyOp ©op)
|
||||||
: osg::NodeCallback(copy, copyop)
|
: osg::NodeCallback(copy, copyop)
|
||||||
, Controller(copy)
|
, Controller(copy)
|
||||||
|
@ -344,6 +369,10 @@ void RollController::operator() (osg::Node* node, osg::NodeVisitor* nv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AlphaController::AlphaController()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
AlphaController::AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial)
|
AlphaController::AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial)
|
||||||
: mData(data->mKeyList, 1.f)
|
: mData(data->mKeyList, 1.f)
|
||||||
, mBaseMaterial(baseMaterial)
|
, mBaseMaterial(baseMaterial)
|
||||||
|
@ -351,7 +380,9 @@ AlphaController::AlphaController(const Nif::NiFloatData *data, const osg::Materi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaController::AlphaController()
|
AlphaController::AlphaController(const Nif::NiFloatInterpolator* interpolator, const osg::Material* baseMaterial)
|
||||||
|
: mData(interpolator)
|
||||||
|
, mBaseMaterial(baseMaterial)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +410,10 @@ void AlphaController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialColorController::MaterialColorController()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MaterialColorController::MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial)
|
MaterialColorController::MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial)
|
||||||
: mData(data->mKeyList, osg::Vec3f(1,1,1))
|
: mData(data->mKeyList, osg::Vec3f(1,1,1))
|
||||||
, mTargetColor(color)
|
, mTargetColor(color)
|
||||||
|
@ -386,7 +421,10 @@ MaterialColorController::MaterialColorController(const Nif::NiPosData *data, Tar
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialColorController::MaterialColorController()
|
MaterialColorController::MaterialColorController(const Nif::NiPoint3Interpolator* interpolator, TargetColor color, const osg::Material* baseMaterial)
|
||||||
|
: mData(interpolator)
|
||||||
|
, mTargetColor(color)
|
||||||
|
, mBaseMaterial(baseMaterial)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +486,8 @@ FlipController::FlipController(const Nif::NiFlipController *ctrl, const std::vec
|
||||||
, mDelta(ctrl->mDelta)
|
, mDelta(ctrl->mDelta)
|
||||||
, mTextures(textures)
|
, mTextures(textures)
|
||||||
{
|
{
|
||||||
|
if (!ctrl->mInterpolator.empty())
|
||||||
|
mData = ctrl->mInterpolator.getPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
FlipController::FlipController(int texSlot, float delta, const std::vector<osg::ref_ptr<osg::Texture2D> >& textures)
|
FlipController::FlipController(int texSlot, float delta, const std::vector<osg::ref_ptr<osg::Texture2D> >& textures)
|
||||||
|
@ -463,14 +503,19 @@ FlipController::FlipController(const FlipController ©, const osg::CopyOp &co
|
||||||
, mTexSlot(copy.mTexSlot)
|
, mTexSlot(copy.mTexSlot)
|
||||||
, mDelta(copy.mDelta)
|
, mDelta(copy.mDelta)
|
||||||
, mTextures(copy.mTextures)
|
, mTextures(copy.mTextures)
|
||||||
|
, mData(copy.mData)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlipController::apply(osg::StateSet* stateset, osg::NodeVisitor* nv)
|
void FlipController::apply(osg::StateSet* stateset, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
if (hasInput() && mDelta != 0 && !mTextures.empty())
|
if (hasInput() && !mTextures.empty())
|
||||||
{
|
{
|
||||||
int curTexture = int(getInputValue(nv) / mDelta) % mTextures.size();
|
int curTexture = 0;
|
||||||
|
if (mDelta != 0)
|
||||||
|
curTexture = int(getInputValue(nv) / mDelta) % mTextures.size();
|
||||||
|
else
|
||||||
|
curTexture = int(mData.interpKey(getInputValue(nv))) % mTextures.size();
|
||||||
stateset->setTextureAttribute(mTexSlot, mTextures[curTexture]);
|
stateset->setTextureAttribute(mTexSlot, mTextures[curTexture]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,8 @@ namespace NifOsg
|
||||||
using ValueT = typename MapT::ValueType;
|
using ValueT = typename MapT::ValueType;
|
||||||
|
|
||||||
ValueInterpolator() = default;
|
ValueInterpolator() = default;
|
||||||
|
ValueInterpolator(const Nif::NiFloatInterpolator* interpolator) = delete;
|
||||||
|
ValueInterpolator(const Nif::NiPoint3Interpolator* interpolator) = delete;
|
||||||
|
|
||||||
ValueInterpolator(std::shared_ptr<const MapT> keys, ValueT defaultVal = ValueT())
|
ValueInterpolator(std::shared_ptr<const MapT> keys, ValueT defaultVal = ValueT())
|
||||||
: mKeys(keys)
|
: mKeys(keys)
|
||||||
|
@ -161,6 +163,34 @@ namespace NifOsg
|
||||||
using Vec3Interpolator = ValueInterpolator<Nif::Vector3KeyMap>;
|
using Vec3Interpolator = ValueInterpolator<Nif::Vector3KeyMap>;
|
||||||
using Vec4Interpolator = ValueInterpolator<Nif::Vector4KeyMap>;
|
using Vec4Interpolator = ValueInterpolator<Nif::Vector4KeyMap>;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline FloatInterpolator::ValueInterpolator(const Nif::NiFloatInterpolator* interpolator)
|
||||||
|
: mDefaultVal(interpolator->defaultVal)
|
||||||
|
{
|
||||||
|
if (interpolator->data.empty())
|
||||||
|
return;
|
||||||
|
mKeys = interpolator->data->mKeyList;
|
||||||
|
if (mKeys)
|
||||||
|
{
|
||||||
|
mLastLowKey = mKeys->mKeys.end();
|
||||||
|
mLastHighKey = mKeys->mKeys.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline Vec3Interpolator::ValueInterpolator(const Nif::NiPoint3Interpolator* interpolator)
|
||||||
|
: mDefaultVal(interpolator->defaultVal)
|
||||||
|
{
|
||||||
|
if (interpolator->data.empty())
|
||||||
|
return;
|
||||||
|
mKeys = interpolator->data->mKeyList;
|
||||||
|
if (mKeys)
|
||||||
|
{
|
||||||
|
mLastLowKey = mKeys->mKeys.end();
|
||||||
|
mLastHighKey = mKeys->mKeys.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ControllerFunction : public SceneUtil::ControllerFunction
|
class ControllerFunction : public SceneUtil::ControllerFunction
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -203,7 +233,14 @@ namespace NifOsg
|
||||||
class KeyframeController : public osg::NodeCallback, public SceneUtil::Controller
|
class KeyframeController : public osg::NodeCallback, public SceneUtil::Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// This is used if there's no interpolator but there is data (Morrowind meshes).
|
||||||
KeyframeController(const Nif::NiKeyframeData *data);
|
KeyframeController(const Nif::NiKeyframeData *data);
|
||||||
|
// This is used if the interpolator has data.
|
||||||
|
KeyframeController(const Nif::NiTransformInterpolator* interpolator);
|
||||||
|
// This is used if there are default values available (e.g. from a data-less interpolator).
|
||||||
|
// If there's neither keyframe data nor an interpolator a KeyframeController must not be created.
|
||||||
|
KeyframeController(const float scale, const osg::Vec3f& pos, const osg::Quat& rot);
|
||||||
|
|
||||||
KeyframeController();
|
KeyframeController();
|
||||||
KeyframeController(const KeyframeController& copy, const osg::CopyOp& copyop);
|
KeyframeController(const KeyframeController& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
|
@ -272,6 +309,7 @@ namespace NifOsg
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RollController(const Nif::NiFloatData *data);
|
RollController(const Nif::NiFloatData *data);
|
||||||
|
RollController(const Nif::NiFloatInterpolator* interpolator);
|
||||||
RollController() = default;
|
RollController() = default;
|
||||||
RollController(const RollController& copy, const osg::CopyOp& copyop);
|
RollController(const RollController& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
|
@ -287,6 +325,7 @@ namespace NifOsg
|
||||||
osg::ref_ptr<const osg::Material> mBaseMaterial;
|
osg::ref_ptr<const osg::Material> mBaseMaterial;
|
||||||
public:
|
public:
|
||||||
AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial);
|
AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial);
|
||||||
|
AlphaController(const Nif::NiFloatInterpolator* interpolator, const osg::Material* baseMaterial);
|
||||||
AlphaController();
|
AlphaController();
|
||||||
AlphaController(const AlphaController& copy, const osg::CopyOp& copyop);
|
AlphaController(const AlphaController& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
|
@ -308,6 +347,7 @@ namespace NifOsg
|
||||||
Emissive = 3
|
Emissive = 3
|
||||||
};
|
};
|
||||||
MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial);
|
MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial);
|
||||||
|
MaterialColorController(const Nif::NiPoint3Interpolator* interpolator, TargetColor color, const osg::Material* baseMaterial);
|
||||||
MaterialColorController();
|
MaterialColorController();
|
||||||
MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop);
|
MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
|
@ -329,6 +369,7 @@ namespace NifOsg
|
||||||
int mTexSlot{0};
|
int mTexSlot{0};
|
||||||
float mDelta{0.f};
|
float mDelta{0.f};
|
||||||
std::vector<osg::ref_ptr<osg::Texture2D> > mTextures;
|
std::vector<osg::ref_ptr<osg::Texture2D> > mTextures;
|
||||||
|
FloatInterpolator mData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FlipController(const Nif::NiFlipController* ctrl, const std::vector<osg::ref_ptr<osg::Texture2D> >& textures);
|
FlipController(const Nif::NiFlipController* ctrl, const std::vector<osg::ref_ptr<osg::Texture2D> >& textures);
|
||||||
|
|
|
@ -281,10 +281,10 @@ namespace NifOsg
|
||||||
const Nif::NiStringExtraData *strdata = static_cast<const Nif::NiStringExtraData*>(extra.getPtr());
|
const Nif::NiStringExtraData *strdata = static_cast<const Nif::NiStringExtraData*>(extra.getPtr());
|
||||||
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
|
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
|
||||||
|
|
||||||
if(key->data.empty())
|
if (key->data.empty() && key->interpolator.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
osg::ref_ptr<NifOsg::KeyframeController> callback(new NifOsg::KeyframeController(key->data.getPtr()));
|
osg::ref_ptr<NifOsg::KeyframeController> callback(handleKeyframeController(key));
|
||||||
callback->setFunction(std::shared_ptr<NifOsg::ControllerFunction>(new NifOsg::ControllerFunction(key)));
|
callback->setFunction(std::shared_ptr<NifOsg::ControllerFunction>(new NifOsg::ControllerFunction(key)));
|
||||||
|
|
||||||
if (!target.mKeyframeControllers.emplace(strdata->string, callback).second)
|
if (!target.mKeyframeControllers.emplace(strdata->string, callback).second)
|
||||||
|
@ -725,6 +725,24 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static osg::ref_ptr<KeyframeController> handleKeyframeController(const Nif::NiKeyframeController* keyctrl)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<NifOsg::KeyframeController> ctrl;
|
||||||
|
if (!keyctrl->interpolator.empty())
|
||||||
|
{
|
||||||
|
const Nif::NiTransformInterpolator* interp = keyctrl->interpolator.getPtr();
|
||||||
|
if (!interp->data.empty())
|
||||||
|
ctrl = new NifOsg::KeyframeController(interp);
|
||||||
|
else
|
||||||
|
ctrl = new NifOsg::KeyframeController(interp->defaultScale, interp->defaultPos, interp->defaultRot);
|
||||||
|
}
|
||||||
|
else if (!keyctrl->data.empty())
|
||||||
|
{
|
||||||
|
ctrl = new NifOsg::KeyframeController(keyctrl->data.getPtr());
|
||||||
|
}
|
||||||
|
return ctrl;
|
||||||
|
}
|
||||||
|
|
||||||
void handleNodeControllers(const Nif::Node* nifNode, osg::Node* node, int animflags, bool& isAnimated)
|
void handleNodeControllers(const Nif::Node* nifNode, osg::Node* node, int animflags, bool& isAnimated)
|
||||||
{
|
{
|
||||||
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)
|
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)
|
||||||
|
@ -734,9 +752,9 @@ namespace NifOsg
|
||||||
if (ctrl->recType == Nif::RC_NiKeyframeController)
|
if (ctrl->recType == Nif::RC_NiKeyframeController)
|
||||||
{
|
{
|
||||||
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
|
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
|
||||||
if (key->data.empty())
|
if (key->data.empty() && key->interpolator.empty())
|
||||||
continue;
|
continue;
|
||||||
osg::ref_ptr<KeyframeController> callback(new KeyframeController(key->data.getPtr()));
|
osg::ref_ptr<KeyframeController> callback(handleKeyframeController(key));
|
||||||
setupController(key, callback, animflags);
|
setupController(key, callback, animflags);
|
||||||
node->addUpdateCallback(callback);
|
node->addUpdateCallback(callback);
|
||||||
isAnimated = true;
|
isAnimated = true;
|
||||||
|
@ -763,9 +781,13 @@ namespace NifOsg
|
||||||
else if (ctrl->recType == Nif::RC_NiRollController)
|
else if (ctrl->recType == Nif::RC_NiRollController)
|
||||||
{
|
{
|
||||||
const Nif::NiRollController *rollctrl = static_cast<const Nif::NiRollController*>(ctrl.getPtr());
|
const Nif::NiRollController *rollctrl = static_cast<const Nif::NiRollController*>(ctrl.getPtr());
|
||||||
if (rollctrl->data.empty())
|
if (rollctrl->data.empty() && rollctrl->interpolator.empty())
|
||||||
continue;
|
continue;
|
||||||
osg::ref_ptr<RollController> callback(new RollController(rollctrl->data.getPtr()));
|
osg::ref_ptr<RollController> callback;
|
||||||
|
if (!rollctrl->interpolator.empty())
|
||||||
|
callback = new RollController(rollctrl->interpolator.getPtr());
|
||||||
|
else // if (!rollctrl->data.empty())
|
||||||
|
callback = new RollController(rollctrl->data.getPtr());
|
||||||
setupController(rollctrl, callback, animflags);
|
setupController(rollctrl, callback, animflags);
|
||||||
node->addUpdateCallback(callback);
|
node->addUpdateCallback(callback);
|
||||||
isAnimated = true;
|
isAnimated = true;
|
||||||
|
@ -791,19 +813,27 @@ namespace NifOsg
|
||||||
if (ctrl->recType == Nif::RC_NiAlphaController)
|
if (ctrl->recType == Nif::RC_NiAlphaController)
|
||||||
{
|
{
|
||||||
const Nif::NiAlphaController* alphactrl = static_cast<const Nif::NiAlphaController*>(ctrl.getPtr());
|
const Nif::NiAlphaController* alphactrl = static_cast<const Nif::NiAlphaController*>(ctrl.getPtr());
|
||||||
if (alphactrl->data.empty())
|
if (alphactrl->data.empty() && alphactrl->interpolator.empty())
|
||||||
continue;
|
continue;
|
||||||
osg::ref_ptr<AlphaController> osgctrl(new AlphaController(alphactrl->data.getPtr(), baseMaterial));
|
osg::ref_ptr<AlphaController> osgctrl;
|
||||||
|
if (!alphactrl->interpolator.empty())
|
||||||
|
osgctrl = new AlphaController(alphactrl->interpolator.getPtr(), baseMaterial);
|
||||||
|
else // if (!alphactrl->data.empty())
|
||||||
|
osgctrl = new AlphaController(alphactrl->data.getPtr(), baseMaterial);
|
||||||
setupController(alphactrl, osgctrl, animflags);
|
setupController(alphactrl, osgctrl, animflags);
|
||||||
composite->addController(osgctrl);
|
composite->addController(osgctrl);
|
||||||
}
|
}
|
||||||
else if (ctrl->recType == Nif::RC_NiMaterialColorController)
|
else if (ctrl->recType == Nif::RC_NiMaterialColorController)
|
||||||
{
|
{
|
||||||
const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
|
const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
|
||||||
if (matctrl->data.empty())
|
if (matctrl->data.empty() && matctrl->interpolator.empty())
|
||||||
continue;
|
continue;
|
||||||
|
osg::ref_ptr<MaterialColorController> osgctrl;
|
||||||
auto targetColor = static_cast<MaterialColorController::TargetColor>(matctrl->targetColor);
|
auto targetColor = static_cast<MaterialColorController::TargetColor>(matctrl->targetColor);
|
||||||
osg::ref_ptr<MaterialColorController> osgctrl(new MaterialColorController(matctrl->data.getPtr(), targetColor, baseMaterial));
|
if (!matctrl->interpolator.empty())
|
||||||
|
osgctrl = new MaterialColorController(matctrl->interpolator.getPtr(), targetColor, baseMaterial);
|
||||||
|
else // if (!matctrl->data.empty())
|
||||||
|
osgctrl = new MaterialColorController(matctrl->data.getPtr(), targetColor, baseMaterial);
|
||||||
setupController(matctrl, osgctrl, animflags);
|
setupController(matctrl, osgctrl, animflags);
|
||||||
composite->addController(osgctrl);
|
composite->addController(osgctrl);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue