mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 20:29:57 +00:00
Add support for NiRollController (feature #4675)
This commit is contained in:
parent
cb5a57e41b
commit
60f112d11c
8 changed files with 91 additions and 0 deletions
|
@ -33,6 +33,7 @@
|
||||||
Feature #3610: Option to invert X axis
|
Feature #3610: Option to invert X axis
|
||||||
Feature #4209: Editor: Faction rank sub-table
|
Feature #4209: Editor: Faction rank sub-table
|
||||||
Feature #4673: Weapon sheathing
|
Feature #4673: Weapon sheathing
|
||||||
|
Feature #4675: Support for NiRollController
|
||||||
Feature #4730: Native animated containers support
|
Feature #4730: Native animated containers support
|
||||||
Feature #4812: Support NiSwitchNode
|
Feature #4812: Support NiSwitchNode
|
||||||
Feature #4836: Daytime node switch
|
Feature #4836: Daytime node switch
|
||||||
|
|
|
@ -173,6 +173,18 @@ namespace Nif
|
||||||
data.post(nif);
|
data.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NiRollController::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
Controller::read(nif);
|
||||||
|
data.read(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiRollController::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
Controller::post(nif);
|
||||||
|
data.post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
void NiGeomMorpherController::read(NIFStream *nif)
|
void NiGeomMorpherController::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
Controller::read(nif);
|
Controller::read(nif);
|
||||||
|
|
|
@ -136,6 +136,15 @@ public:
|
||||||
void post(NIFFile *nif);
|
void post(NIFFile *nif);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NiRollController : public Controller
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NiFloatDataPtr data;
|
||||||
|
|
||||||
|
void read(NIFStream *nif);
|
||||||
|
void post(NIFFile *nif);
|
||||||
|
};
|
||||||
|
|
||||||
class NiGeomMorpherController : public Controller
|
class NiGeomMorpherController : public Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -73,6 +73,7 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
|
||||||
newFactory.insert(makeEntry("NiGeomMorpherController", &construct <NiGeomMorpherController> , RC_NiGeomMorpherController ));
|
newFactory.insert(makeEntry("NiGeomMorpherController", &construct <NiGeomMorpherController> , RC_NiGeomMorpherController ));
|
||||||
newFactory.insert(makeEntry("NiKeyframeController", &construct <NiKeyframeController> , RC_NiKeyframeController ));
|
newFactory.insert(makeEntry("NiKeyframeController", &construct <NiKeyframeController> , RC_NiKeyframeController ));
|
||||||
newFactory.insert(makeEntry("NiAlphaController", &construct <NiAlphaController> , RC_NiAlphaController ));
|
newFactory.insert(makeEntry("NiAlphaController", &construct <NiAlphaController> , RC_NiAlphaController ));
|
||||||
|
newFactory.insert(makeEntry("NiRollController", &construct <NiRollController> , RC_NiRollController ));
|
||||||
newFactory.insert(makeEntry("NiUVController", &construct <NiUVController> , RC_NiUVController ));
|
newFactory.insert(makeEntry("NiUVController", &construct <NiUVController> , RC_NiUVController ));
|
||||||
newFactory.insert(makeEntry("NiPathController", &construct <NiPathController> , RC_NiPathController ));
|
newFactory.insert(makeEntry("NiPathController", &construct <NiPathController> , RC_NiPathController ));
|
||||||
newFactory.insert(makeEntry("NiMaterialColorController", &construct <NiMaterialColorController> , RC_NiMaterialColorController ));
|
newFactory.insert(makeEntry("NiMaterialColorController", &construct <NiMaterialColorController> , RC_NiMaterialColorController ));
|
||||||
|
|
|
@ -60,6 +60,7 @@ enum RecordType
|
||||||
RC_NiGeomMorpherController,
|
RC_NiGeomMorpherController,
|
||||||
RC_NiKeyframeController,
|
RC_NiKeyframeController,
|
||||||
RC_NiAlphaController,
|
RC_NiAlphaController,
|
||||||
|
RC_NiRollController,
|
||||||
RC_NiUVController,
|
RC_NiUVController,
|
||||||
RC_NiPathController,
|
RC_NiPathController,
|
||||||
RC_NiMaterialColorController,
|
RC_NiMaterialColorController,
|
||||||
|
|
|
@ -309,6 +309,46 @@ void VisController::operator() (osg::Node* node, osg::NodeVisitor* nv)
|
||||||
traverse(node, nv);
|
traverse(node, nv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RollController::RollController(const Nif::NiFloatData *data)
|
||||||
|
: mData(data->mKeyList, 1.f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RollController::RollController()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RollController::RollController(const RollController ©, const osg::CopyOp ©op)
|
||||||
|
: osg::NodeCallback(copy, copyop)
|
||||||
|
, Controller(copy)
|
||||||
|
, mData(copy.mData)
|
||||||
|
, mStartingTime(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RollController::operator() (osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
traverse(node, nv);
|
||||||
|
|
||||||
|
if (hasInput())
|
||||||
|
{
|
||||||
|
double newTime = nv->getFrameStamp()->getSimulationTime();
|
||||||
|
double duration = newTime - mStartingTime;
|
||||||
|
mStartingTime = newTime;
|
||||||
|
|
||||||
|
float value = mData.interpKey(getInputValue(nv));
|
||||||
|
osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node);
|
||||||
|
osg::Matrix matrix = transform->getMatrix();
|
||||||
|
|
||||||
|
// Rotate around "roll" axis.
|
||||||
|
// Note: in original game rotation speed is the framerate-dependent in a very tricky way.
|
||||||
|
// Do not replicate this behaviour until we will really need it.
|
||||||
|
// For now consider controller's current value as an angular speed in radians per 1/60 seconds.
|
||||||
|
matrix = osg::Matrix::rotate(value * duration * 60.f, 0, 0, 1) * matrix;
|
||||||
|
transform->setMatrix(matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AlphaController::AlphaController(const Nif::NiFloatData *data)
|
AlphaController::AlphaController(const Nif::NiFloatData *data)
|
||||||
: mData(data->mKeyList, 1.f)
|
: mData(data->mKeyList, 1.f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -246,6 +246,22 @@ namespace NifOsg
|
||||||
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv);
|
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RollController : public osg::NodeCallback, public SceneUtil::Controller
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
FloatInterpolator mData;
|
||||||
|
double mStartingTime;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RollController(const Nif::NiFloatData *data);
|
||||||
|
RollController();
|
||||||
|
RollController(const RollController& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
|
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv);
|
||||||
|
|
||||||
|
META_Object(NifOsg, RollController)
|
||||||
|
};
|
||||||
|
|
||||||
class AlphaController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller
|
class AlphaController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -697,6 +697,10 @@ namespace NifOsg
|
||||||
{
|
{
|
||||||
handleVisController(static_cast<const Nif::NiVisController*>(ctrl.getPtr()), transformNode, animflags);
|
handleVisController(static_cast<const Nif::NiVisController*>(ctrl.getPtr()), transformNode, animflags);
|
||||||
}
|
}
|
||||||
|
else if (ctrl->recType == Nif::RC_NiRollController)
|
||||||
|
{
|
||||||
|
handleRollController(static_cast<const Nif::NiRollController*>(ctrl.getPtr()), transformNode, animflags);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Log(Debug::Info) << "Unhandled controller " << ctrl->recName << " on node " << nifNode->recIndex << " in " << mFilename;
|
Log(Debug::Info) << "Unhandled controller " << ctrl->recName << " on node " << nifNode->recIndex << " in " << mFilename;
|
||||||
}
|
}
|
||||||
|
@ -709,6 +713,13 @@ namespace NifOsg
|
||||||
node->addUpdateCallback(callback);
|
node->addUpdateCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleRollController(const Nif::NiRollController* rollctrl, osg::Node* node, int animflags)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<RollController> callback(new RollController(rollctrl->data.getPtr()));
|
||||||
|
setupController(rollctrl, callback, animflags);
|
||||||
|
node->addUpdateCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void handleMaterialControllers(const Nif::Property *materialProperty, SceneUtil::CompositeStateSetUpdater* composite, int animflags)
|
void handleMaterialControllers(const Nif::Property *materialProperty, SceneUtil::CompositeStateSetUpdater* composite, int animflags)
|
||||||
{
|
{
|
||||||
for (Nif::ControllerPtr ctrl = materialProperty->controller; !ctrl.empty(); ctrl = ctrl->next)
|
for (Nif::ControllerPtr ctrl = materialProperty->controller; !ctrl.empty(); ctrl = ctrl->next)
|
||||||
|
|
Loading…
Reference in a new issue