mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 19:15:41 +00:00
Further controller updates
Correct NiMaterialColorController base class Load everything in NiGeomMorpherController Make a guess at how weighted interpolators might be supposed to work like
This commit is contained in:
parent
cd8b20439e
commit
7aee22be91
6 changed files with 60 additions and 38 deletions
|
@ -113,7 +113,7 @@ namespace Nif
|
||||||
|
|
||||||
void NiMaterialColorController::read(NIFStream *nif)
|
void NiMaterialColorController::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
NiSingleInterpController::read(nif);
|
NiPoint3InterpController::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
|
||||||
|
@ -129,7 +129,7 @@ namespace Nif
|
||||||
|
|
||||||
void NiMaterialColorController::post(NIFFile *nif)
|
void NiMaterialColorController::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
NiSingleInterpController::post(nif);
|
NiPoint3InterpController::post(nif);
|
||||||
mData.post(nif);
|
mData.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,16 +241,16 @@ namespace Nif
|
||||||
{
|
{
|
||||||
NiInterpController::read(nif);
|
NiInterpController::read(nif);
|
||||||
if (nif->getVersion() >= NIFFile::NIFVersion::VER_OB_OLD)
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_OB_OLD)
|
||||||
/*bool updateNormals = !!*/nif->getUShort();
|
mUpdateNormals = nif->getUShort() & 1;
|
||||||
data.read(nif);
|
mData.read(nif);
|
||||||
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
|
||||||
{
|
{
|
||||||
/*bool alwaysActive = */nif->getChar(); // Always 0
|
mAlwaysActive = nif->getChar();
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,106))
|
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,106))
|
||||||
{
|
{
|
||||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
||||||
{
|
{
|
||||||
interpolators.read(nif);
|
mInterpolators.read(nif);
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0) && nif->getBethVersion() > 9)
|
if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0) && nif->getBethVersion() > 9)
|
||||||
{
|
{
|
||||||
unsigned int numUnknown = nif->getUInt();
|
unsigned int numUnknown = nif->getUInt();
|
||||||
|
@ -259,9 +259,16 @@ namespace Nif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: handle weighted interpolators
|
std::vector<NiInterpolatorPtr> interpolators;
|
||||||
unsigned int numInterps = nif->getUInt();
|
size_t numInterps = nif->getUInt();
|
||||||
nif->skip(8 * numInterps);
|
interpolators.resize(numInterps);
|
||||||
|
mWeights.resize(numInterps);
|
||||||
|
for (size_t i = 0; i < numInterps; i++)
|
||||||
|
{
|
||||||
|
interpolators[i].read(nif);
|
||||||
|
mWeights[i] = nif->getFloat();
|
||||||
|
}
|
||||||
|
mInterpolators = interpolators;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,8 +277,8 @@ namespace Nif
|
||||||
void NiGeomMorpherController::post(NIFFile *nif)
|
void NiGeomMorpherController::post(NIFFile *nif)
|
||||||
{
|
{
|
||||||
NiInterpController::post(nif);
|
NiInterpController::post(nif);
|
||||||
data.post(nif);
|
mData.post(nif);
|
||||||
interpolators.post(nif);
|
mInterpolators.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiVisController::read(NIFStream *nif)
|
void NiVisController::read(NIFStream *nif)
|
||||||
|
|
|
@ -47,6 +47,15 @@ struct NiSingleInterpController : public NiInterpController
|
||||||
void post(NIFFile* nif) override;
|
void post(NIFFile* nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Base class for controllers that use a NiFloatInterpolator to animate their target.
|
||||||
|
struct NiFloatInterpController : public NiSingleInterpController { };
|
||||||
|
|
||||||
|
// Ditto for NiBoolInterpolator.
|
||||||
|
struct NiBoolInterpController : public NiSingleInterpController { };
|
||||||
|
|
||||||
|
// Ditto for NiPoint3Interpolator.
|
||||||
|
struct NiPoint3InterpController : public NiSingleInterpController { };
|
||||||
|
|
||||||
struct NiParticleSystemController : public Controller
|
struct NiParticleSystemController : public Controller
|
||||||
{
|
{
|
||||||
enum BSPArrayController {
|
enum BSPArrayController {
|
||||||
|
@ -106,7 +115,7 @@ struct NiParticleSystemController : public Controller
|
||||||
};
|
};
|
||||||
using NiBSPArrayController = NiParticleSystemController;
|
using NiBSPArrayController = NiParticleSystemController;
|
||||||
|
|
||||||
struct NiMaterialColorController : public NiSingleInterpController
|
struct NiMaterialColorController : public NiPoint3InterpController
|
||||||
{
|
{
|
||||||
NiPosDataPtr mData;
|
NiPosDataPtr mData;
|
||||||
unsigned int mTargetColor;
|
unsigned int mTargetColor;
|
||||||
|
@ -172,12 +181,6 @@ struct NiMultiTargetTransformController : public NiInterpController
|
||||||
void post(NIFFile *nif) override;
|
void post(NIFFile *nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for controllers that use a NiFloatInterpolator to animate their target.
|
|
||||||
struct NiFloatInterpController : public NiSingleInterpController { };
|
|
||||||
|
|
||||||
// Ditto for NiBoolInterpolator.
|
|
||||||
struct NiBoolInterpController : public NiSingleInterpController { };
|
|
||||||
|
|
||||||
struct NiAlphaController : public NiFloatInterpController
|
struct NiAlphaController : public NiFloatInterpController
|
||||||
{
|
{
|
||||||
NiFloatDataPtr mData;
|
NiFloatDataPtr mData;
|
||||||
|
@ -196,8 +199,11 @@ struct NiRollController : public NiSingleInterpController
|
||||||
|
|
||||||
struct NiGeomMorpherController : public NiInterpController
|
struct NiGeomMorpherController : public NiInterpController
|
||||||
{
|
{
|
||||||
NiMorphDataPtr data;
|
bool mUpdateNormals{false};
|
||||||
NiFloatInterpolatorList interpolators;
|
bool mAlwaysActive{false};
|
||||||
|
NiMorphDataPtr mData;
|
||||||
|
NiInterpolatorList mInterpolators;
|
||||||
|
std::vector<float> mWeights;
|
||||||
|
|
||||||
void read(NIFStream *nif) override;
|
void read(NIFStream *nif) override;
|
||||||
void post(NIFFile *nif) override;
|
void post(NIFFile *nif) override;
|
||||||
|
|
|
@ -152,7 +152,6 @@ struct bhkSerializable;
|
||||||
struct hkPackedNiTriStripsData;
|
struct hkPackedNiTriStripsData;
|
||||||
struct NiAccumulator;
|
struct NiAccumulator;
|
||||||
struct NiInterpolator;
|
struct NiInterpolator;
|
||||||
struct NiFloatInterpolator;
|
|
||||||
|
|
||||||
using NodePtr = RecordPtrT<Node>;
|
using NodePtr = RecordPtrT<Node>;
|
||||||
using ExtraPtr = RecordPtrT<Extra>;
|
using ExtraPtr = RecordPtrT<Extra>;
|
||||||
|
@ -188,7 +187,7 @@ 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>;
|
using NiInterpolatorList = RecordListT<NiInterpolator>;
|
||||||
using NiTriStripsDataList = RecordListT<NiTriStripsData>;
|
using NiTriStripsDataList = RecordListT<NiTriStripsData>;
|
||||||
using bhkShapeList = RecordListT<bhkShape>;
|
using bhkShapeList = RecordListT<bhkShape>;
|
||||||
using bhkSerializableList = RecordListT<bhkSerializable>;
|
using bhkSerializableList = RecordListT<bhkSerializable>;
|
||||||
|
|
|
@ -196,26 +196,31 @@ GeomMorpherController::GeomMorpherController(const GeomMorpherController ©,
|
||||||
: Controller(copy)
|
: Controller(copy)
|
||||||
, SceneUtil::NodeCallback<GeomMorpherController, SceneUtil::MorphGeometry*>(copy, copyop)
|
, SceneUtil::NodeCallback<GeomMorpherController, SceneUtil::MorphGeometry*>(copy, copyop)
|
||||||
, mKeyFrames(copy.mKeyFrames)
|
, mKeyFrames(copy.mKeyFrames)
|
||||||
|
, mWeights(copy.mWeights)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GeomMorpherController::GeomMorpherController(const Nif::NiGeomMorpherController* ctrl)
|
GeomMorpherController::GeomMorpherController(const Nif::NiGeomMorpherController* ctrl)
|
||||||
{
|
{
|
||||||
if (ctrl->interpolators.length() == 0)
|
if (ctrl->mInterpolators.length() == 0)
|
||||||
{
|
{
|
||||||
if (ctrl->data.empty())
|
if (!ctrl->mData.empty())
|
||||||
return;
|
|
||||||
for (const auto& morph : ctrl->data->mMorphs)
|
|
||||||
mKeyFrames.emplace_back(morph.mKeyFrames);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < ctrl->interpolators.length(); ++i)
|
|
||||||
{
|
{
|
||||||
if (!ctrl->interpolators[i].empty())
|
for (const auto& morph : ctrl->mData->mMorphs)
|
||||||
mKeyFrames.emplace_back(ctrl->interpolators[i].getPtr());
|
mKeyFrames.emplace_back(morph.mKeyFrames);
|
||||||
else
|
}
|
||||||
mKeyFrames.emplace_back();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mKeyFrames.resize(ctrl->mInterpolators.length());
|
||||||
|
mWeights = ctrl->mWeights;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ctrl->mInterpolators.length(); ++i)
|
||||||
|
{
|
||||||
|
if (!ctrl->mInterpolators[i].empty() && ctrl->mInterpolators[i]->recType == Nif::RC_NiFloatInterpolator)
|
||||||
|
{
|
||||||
|
auto interpolator = static_cast<const Nif::NiFloatInterpolator*>(ctrl->mInterpolators[i].getPtr());
|
||||||
|
mKeyFrames[i] = FloatInterpolator(interpolator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,12 +232,16 @@ void GeomMorpherController::operator()(SceneUtil::MorphGeometry* node, osg::Node
|
||||||
if (mKeyFrames.size() <= 1)
|
if (mKeyFrames.size() <= 1)
|
||||||
return;
|
return;
|
||||||
float input = getInputValue(nv);
|
float input = getInputValue(nv);
|
||||||
int i = 1;
|
size_t i = 1;
|
||||||
for (std::vector<FloatInterpolator>::iterator it = mKeyFrames.begin()+1; it != mKeyFrames.end(); ++it,++i)
|
for (std::vector<FloatInterpolator>::iterator it = mKeyFrames.begin()+1; it != mKeyFrames.end(); ++it,++i)
|
||||||
{
|
{
|
||||||
float val = 0;
|
float val = 0;
|
||||||
if (!(*it).empty())
|
if (!(*it).empty())
|
||||||
|
{
|
||||||
val = it->interpKey(input);
|
val = it->interpKey(input);
|
||||||
|
if (i < mWeights.size())
|
||||||
|
val *= mWeights[i];
|
||||||
|
}
|
||||||
|
|
||||||
SceneUtil::MorphGeometry::MorphTarget& target = node->getMorphTarget(i);
|
SceneUtil::MorphGeometry::MorphTarget& target = node->getMorphTarget(i);
|
||||||
if (target.getWeight() != val)
|
if (target.getWeight() != val)
|
||||||
|
|
|
@ -225,6 +225,7 @@ namespace NifOsg
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<FloatInterpolator> mKeyFrames;
|
std::vector<FloatInterpolator> mKeyFrames;
|
||||||
|
std::vector<float> mWeights;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
|
@ -1357,7 +1357,7 @@ namespace NifOsg
|
||||||
if(ctrl->recType == Nif::RC_NiGeomMorpherController)
|
if(ctrl->recType == Nif::RC_NiGeomMorpherController)
|
||||||
{
|
{
|
||||||
const Nif::NiGeomMorpherController* nimorphctrl = static_cast<const Nif::NiGeomMorpherController*>(ctrl.getPtr());
|
const Nif::NiGeomMorpherController* nimorphctrl = static_cast<const Nif::NiGeomMorpherController*>(ctrl.getPtr());
|
||||||
if (nimorphctrl->data.empty())
|
if (nimorphctrl->mData.empty())
|
||||||
continue;
|
continue;
|
||||||
drawable = handleMorphGeometry(nimorphctrl, geom, parentNode, composite, boundTextures, animflags);
|
drawable = handleMorphGeometry(nimorphctrl, geom, parentNode, composite, boundTextures, animflags);
|
||||||
|
|
||||||
|
@ -1378,7 +1378,7 @@ namespace NifOsg
|
||||||
osg::ref_ptr<SceneUtil::MorphGeometry> morphGeom = new SceneUtil::MorphGeometry;
|
osg::ref_ptr<SceneUtil::MorphGeometry> morphGeom = new SceneUtil::MorphGeometry;
|
||||||
morphGeom->setSourceGeometry(sourceGeometry);
|
morphGeom->setSourceGeometry(sourceGeometry);
|
||||||
|
|
||||||
const std::vector<Nif::NiMorphData::MorphData>& morphs = morpher->data.getPtr()->mMorphs;
|
const std::vector<Nif::NiMorphData::MorphData>& morphs = morpher->mData.getPtr()->mMorphs;
|
||||||
if (morphs.empty())
|
if (morphs.empty())
|
||||||
return morphGeom;
|
return morphGeom;
|
||||||
if (morphs[0].mVertices.size() != static_cast<const osg::Vec3Array*>(sourceGeometry->getVertexArray())->size())
|
if (morphs[0].mVertices.size() != static_cast<const osg::Vec3Array*>(sourceGeometry->getVertexArray())->size())
|
||||||
|
|
Loading…
Reference in a new issue