Add basic NiPathController support (movement only)

pull/578/head
Capostrophic 5 years ago
parent 0e3ae38e49
commit 30fc2e3e5e

@ -123,12 +123,10 @@ namespace Nif
{
Controller::read(nif);
/*
int = 1
2xfloat
short = 0 or 1
*/
nif->skip(14);
bankDir = nif->getInt();
maxBankAngle = nif->getFloat();
smoothing = nif->getFloat();
followAxis = nif->getShort();
posData.read(nif);
floatData.read(nif);
}

@ -96,6 +96,20 @@ public:
NiPosDataPtr posData;
NiFloatDataPtr floatData;
enum Flags
{
Flag_OpenCurve = 0x020,
Flag_AllowFlip = 0x040,
Flag_Bank = 0x080,
Flag_ConstVelocity = 0x100,
Flag_Follow = 0x200,
Flag_FlipFollowAxis = 0x400
};
int bankDir;
float maxBankAngle, smoothing;
short followAxis;
void read(NIFStream *nif);
void post(NIFFile *nif);
};

@ -521,4 +521,50 @@ void ParticleSystemController::operator() (osg::Node* node, osg::NodeVisitor* nv
traverse(node, nv);
}
PathController::PathController(const PathController &copy, const osg::CopyOp &copyop)
: osg::NodeCallback(copy, copyop)
, Controller(copy)
, mPath(copy.mPath)
, mPercent(copy.mPercent)
, mFlags(copy.mFlags)
{
}
PathController::PathController(const Nif::NiPathController* ctrl)
: mPath(ctrl->posData->mKeyList, osg::Vec3f())
, mPercent(ctrl->floatData->mKeyList, 1.f)
, mFlags(ctrl->flags)
{
}
float PathController::getPercent(float time) const
{
float percent = mPercent.interpKey(time);
if (percent < 0.f)
percent = std::fmod(percent, 1.f) + 1.f;
else if (percent > 1.f)
percent = std::fmod(percent, 1.f);
return percent;
}
void PathController::operator() (osg::Node* node, osg::NodeVisitor* nv)
{
if (mPath.empty() || mPercent.empty() || !hasInput())
{
traverse(node, nv);
return;
}
osg::MatrixTransform* trans = static_cast<osg::MatrixTransform*>(node);
osg::Matrix mat = trans->getMatrix();
float time = getInputValue(nv);
float percent = getPercent(time);
osg::Vec3f pos(mPath.interpKey(percent));
mat.setTrans(pos);
trans->setMatrix(mat);
traverse(node, nv);
}
}

@ -342,6 +342,25 @@ namespace NifOsg
float mEmitStop;
};
class PathController : public osg::NodeCallback, public SceneUtil::Controller
{
public:
PathController(const Nif::NiPathController* ctrl);
PathController() = default;
PathController(const PathController& copy, const osg::CopyOp& copyop);
META_Object(NifOsg, PathController)
virtual void operator() (osg::Node*, osg::NodeVisitor*);
private:
Vec3Interpolator mPath;
FloatInterpolator mPercent;
int mFlags{0};
float getPercent(float time) const;
};
}
#endif

@ -752,6 +752,17 @@ namespace NifOsg
node->addUpdateCallback(callback);
}
}
else if (ctrl->recType == Nif::RC_NiPathController)
{
const Nif::NiPathController *path = static_cast<const Nif::NiPathController*>(ctrl.getPtr());
if (!path->posData.empty() && !path->floatData.empty())
{
osg::ref_ptr<PathController> callback(new PathController(path));
setupController(path, callback, animflags);
node->addUpdateCallback(callback);
}
}
else if (ctrl->recType == Nif::RC_NiVisController)
{
handleVisController(static_cast<const Nif::NiVisController*>(ctrl.getPtr()), node, animflags);
@ -780,6 +791,17 @@ namespace NifOsg
transformNode->addUpdateCallback(callback);
}
}
else if (ctrl->recType == Nif::RC_NiPathController)
{
const Nif::NiPathController *path = static_cast<const Nif::NiPathController*>(ctrl.getPtr());
if (!path->posData.empty() && !path->floatData.empty())
{
osg::ref_ptr<PathController> callback(new PathController(path));
setupController(path, callback, animflags);
transformNode->addUpdateCallback(callback);
}
}
else if (ctrl->recType == Nif::RC_NiVisController)
{
handleVisController(static_cast<const Nif::NiVisController*>(ctrl.getPtr()), transformNode, animflags);

Loading…
Cancel
Save