mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-04 02:41:19 +00:00
Add basic NiPathController support (movement only)
This commit is contained in:
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 ©, const osg::CopyOp ©op)
|
||||
: 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…
Reference in New Issue
Block a user