mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 08:45:33 +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)
|
||||
{
|
||||
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 ©,
|
|||
: 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < ctrl->interpolators.length(); ++i)
|
||||
if (!ctrl->mData.empty())
|
||||
{
|
||||
if (!ctrl->interpolators[i].empty())
|
||||
mKeyFrames.emplace_back(ctrl->interpolators[i].getPtr());
|
||||
else
|
||||
mKeyFrames.emplace_back();
|
||||
for (const auto& morph : ctrl->mData->mMorphs)
|
||||
mKeyFrames.emplace_back(morph.mKeyFrames);
|
||||
}
|
||||
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)
|
||||
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…
Reference in a new issue