Merge branch 'nifctrl' into 'master'

Further NIF controller updates

See merge request OpenMW/openmw!2415
make_linux_ci_do_zoomies
psi29a 2 years ago
commit 553fa8cc58

@ -113,7 +113,7 @@ namespace Nif
void NiMaterialColorController::read(NIFStream *nif)
{
NiSingleInterpController::read(nif);
NiPoint3InterpController::read(nif);
// Two bits that correspond to the controlled material color.
// 00: Ambient
// 01: Diffuse
@ -129,7 +129,7 @@ namespace Nif
void NiMaterialColorController::post(NIFFile *nif)
{
NiSingleInterpController::post(nif);
NiPoint3InterpController::post(nif);
mData.post(nif);
}
@ -241,16 +241,16 @@ namespace Nif
{
NiInterpController::read(nif);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_OB_OLD)
/*bool updateNormals = !!*/nif->getUShort();
data.read(nif);
mUpdateNormals = nif->getUShort() & 1;
mData.read(nif);
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() <= NIFFile::NIFVersion::VER_OB)
{
interpolators.read(nif);
mInterpolators.read(nif);
if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0) && nif->getBethVersion() > 9)
{
unsigned int numUnknown = nif->getUInt();
@ -259,9 +259,16 @@ namespace Nif
}
else
{
// TODO: handle weighted interpolators
unsigned int numInterps = nif->getUInt();
nif->skip(8 * numInterps);
std::vector<NiInterpolatorPtr> interpolators;
size_t numInterps = nif->getUInt();
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)
{
NiInterpController::post(nif);
data.post(nif);
interpolators.post(nif);
mData.post(nif);
mInterpolators.post(nif);
}
void NiVisController::read(NIFStream *nif)

@ -47,6 +47,15 @@ struct NiSingleInterpController : public NiInterpController
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
{
enum BSPArrayController {
@ -106,7 +115,7 @@ struct NiParticleSystemController : public Controller
};
using NiBSPArrayController = NiParticleSystemController;
struct NiMaterialColorController : public NiSingleInterpController
struct NiMaterialColorController : public NiPoint3InterpController
{
NiPosDataPtr mData;
unsigned int mTargetColor;
@ -172,12 +181,6 @@ struct NiMultiTargetTransformController : public NiInterpController
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
{
NiFloatDataPtr mData;
@ -196,8 +199,11 @@ struct NiRollController : public NiSingleInterpController
struct NiGeomMorpherController : public NiInterpController
{
NiMorphDataPtr data;
NiFloatInterpolatorList interpolators;
bool mUpdateNormals{false};
bool mAlwaysActive{false};
NiMorphDataPtr mData;
NiInterpolatorList mInterpolators;
std::vector<float> mWeights;
void read(NIFStream *nif) override;
void post(NIFFile *nif) override;

@ -152,7 +152,6 @@ struct bhkSerializable;
struct hkPackedNiTriStripsData;
struct NiAccumulator;
struct NiInterpolator;
struct NiFloatInterpolator;
using NodePtr = RecordPtrT<Node>;
using ExtraPtr = RecordPtrT<Extra>;
@ -188,7 +187,7 @@ using NodeList = RecordListT<Node>;
using PropertyList = RecordListT<Property>;
using ExtraList = RecordListT<Extra>;
using NiSourceTextureList = RecordListT<NiSourceTexture>;
using NiFloatInterpolatorList = RecordListT<NiFloatInterpolator>;
using NiInterpolatorList = RecordListT<NiInterpolator>;
using NiTriStripsDataList = RecordListT<NiTriStripsData>;
using bhkShapeList = RecordListT<bhkShape>;
using bhkSerializableList = RecordListT<bhkSerializable>;

@ -196,26 +196,31 @@ GeomMorpherController::GeomMorpherController(const GeomMorpherController &copy,
: Controller(copy)
, SceneUtil::NodeCallback<GeomMorpherController, SceneUtil::MorphGeometry*>(copy, copyop)
, mKeyFrames(copy.mKeyFrames)
, mWeights(copy.mWeights)
{
}
GeomMorpherController::GeomMorpherController(const Nif::NiGeomMorpherController* ctrl)
{
if (ctrl->interpolators.length() == 0)
if (ctrl->mInterpolators.length() == 0)
{
if (ctrl->data.empty())
return;
for (const auto& morph : ctrl->data->mMorphs)
mKeyFrames.emplace_back(morph.mKeyFrames);
if (!ctrl->mData.empty())
{
for (const auto& morph : ctrl->mData->mMorphs)
mKeyFrames.emplace_back(morph.mKeyFrames);
}
return;
}
else
mKeyFrames.resize(ctrl->mInterpolators.length());
mWeights = ctrl->mWeights;
for (size_t i = 0; i < ctrl->mInterpolators.length(); ++i)
{
for (size_t i = 0; i < ctrl->interpolators.length(); ++i)
if (!ctrl->mInterpolators[i].empty() && ctrl->mInterpolators[i]->recType == Nif::RC_NiFloatInterpolator)
{
if (!ctrl->interpolators[i].empty())
mKeyFrames.emplace_back(ctrl->interpolators[i].getPtr());
else
mKeyFrames.emplace_back();
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)
return;
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)
{
float val = 0;
if (!(*it).empty())
{
val = it->interpKey(input);
if (i < mWeights.size())
val *= mWeights[i];
}
SceneUtil::MorphGeometry::MorphTarget& target = node->getMorphTarget(i);
if (target.getWeight() != val)

@ -225,6 +225,7 @@ namespace NifOsg
private:
std::vector<FloatInterpolator> mKeyFrames;
std::vector<float> mWeights;
};
#ifdef _MSC_VER

@ -1357,7 +1357,7 @@ namespace NifOsg
if(ctrl->recType == Nif::RC_NiGeomMorpherController)
{
const Nif::NiGeomMorpherController* nimorphctrl = static_cast<const Nif::NiGeomMorpherController*>(ctrl.getPtr());
if (nimorphctrl->data.empty())
if (nimorphctrl->mData.empty())
continue;
drawable = handleMorphGeometry(nimorphctrl, geom, parentNode, composite, boundTextures, animflags);
@ -1378,7 +1378,7 @@ namespace NifOsg
osg::ref_ptr<SceneUtil::MorphGeometry> morphGeom = new SceneUtil::MorphGeometry;
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())
return morphGeom;
if (morphs[0].mVertices.size() != static_cast<const osg::Vec3Array*>(sourceGeometry->getVertexArray())->size())

Loading…
Cancel
Save