|
|
@ -20,8 +20,7 @@
|
|
|
|
#include <components/misc/constants.hpp>
|
|
|
|
#include <components/misc/constants.hpp>
|
|
|
|
#include <components/misc/resourcehelpers.hpp>
|
|
|
|
#include <components/misc/resourcehelpers.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
#include <components/nifosg/nifloader.hpp> // KeyframeHolder
|
|
|
|
#include <components/sceneutil/keyframe.hpp>
|
|
|
|
#include <components/nifosg/controller.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <components/vfs/manager.hpp>
|
|
|
|
#include <components/vfs/manager.hpp>
|
|
|
|
|
|
|
|
|
|
|
@ -148,7 +147,7 @@ namespace
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
float calcAnimVelocity(const NifOsg::TextKeyMap& keys, NifOsg::KeyframeController *nonaccumctrl,
|
|
|
|
float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController *nonaccumctrl,
|
|
|
|
const osg::Vec3f& accum, const std::string &groupname)
|
|
|
|
const osg::Vec3f& accum, const std::string &groupname)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const std::string start = groupname+": start";
|
|
|
|
const std::string start = groupname+": start";
|
|
|
@ -530,13 +529,13 @@ namespace MWRender
|
|
|
|
|
|
|
|
|
|
|
|
struct Animation::AnimSource
|
|
|
|
struct Animation::AnimSource
|
|
|
|
{
|
|
|
|
{
|
|
|
|
osg::ref_ptr<const NifOsg::KeyframeHolder> mKeyframes;
|
|
|
|
osg::ref_ptr<const SceneUtil::KeyframeHolder> mKeyframes;
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::map<std::string, osg::ref_ptr<NifOsg::KeyframeController> > ControllerMap;
|
|
|
|
typedef std::map<std::string, osg::ref_ptr<SceneUtil::KeyframeController> > ControllerMap;
|
|
|
|
|
|
|
|
|
|
|
|
ControllerMap mControllerMap[Animation::sNumBlendMasks];
|
|
|
|
ControllerMap mControllerMap[Animation::sNumBlendMasks];
|
|
|
|
|
|
|
|
|
|
|
|
const NifOsg::TextKeyMap& getTextKeys() const;
|
|
|
|
const SceneUtil::TextKeyMap& getTextKeys() const;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void UpdateVfxCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
|
|
|
void UpdateVfxCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
|
|
@ -688,7 +687,7 @@ namespace MWRender
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const NifOsg::TextKeyMap &Animation::AnimSource::getTextKeys() const
|
|
|
|
const SceneUtil::TextKeyMap &Animation::AnimSource::getTextKeys() const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return mKeyframes->mTextKeys;
|
|
|
|
return mKeyframes->mTextKeys;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -729,8 +728,6 @@ namespace MWRender
|
|
|
|
|
|
|
|
|
|
|
|
if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0)
|
|
|
|
if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0)
|
|
|
|
kfname.replace(kfname.size()-4, 4, ".kf");
|
|
|
|
kfname.replace(kfname.size()-4, 4, ".kf");
|
|
|
|
else
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addSingleAnimSource(kfname, baseModel);
|
|
|
|
addSingleAnimSource(kfname, baseModel);
|
|
|
|
|
|
|
|
|
|
|
@ -753,7 +750,7 @@ namespace MWRender
|
|
|
|
|
|
|
|
|
|
|
|
const NodeMap& nodeMap = getNodeMap();
|
|
|
|
const NodeMap& nodeMap = getNodeMap();
|
|
|
|
|
|
|
|
|
|
|
|
for (NifOsg::KeyframeHolder::KeyframeControllerMap::const_iterator it = animsrc->mKeyframes->mKeyframeControllers.begin();
|
|
|
|
for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = animsrc->mKeyframes->mKeyframeControllers.begin();
|
|
|
|
it != animsrc->mKeyframes->mKeyframeControllers.end(); ++it)
|
|
|
|
it != animsrc->mKeyframes->mKeyframeControllers.end(); ++it)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::string bonename = Misc::StringUtils::lowerCase(it->first);
|
|
|
|
std::string bonename = Misc::StringUtils::lowerCase(it->first);
|
|
|
@ -769,7 +766,7 @@ namespace MWRender
|
|
|
|
size_t blendMask = detectBlendMask(node);
|
|
|
|
size_t blendMask = detectBlendMask(node);
|
|
|
|
|
|
|
|
|
|
|
|
// clone the controller, because each Animation needs its own ControllerSource
|
|
|
|
// clone the controller, because each Animation needs its own ControllerSource
|
|
|
|
osg::ref_ptr<NifOsg::KeyframeController> cloned = new NifOsg::KeyframeController(*it->second, osg::CopyOp::SHALLOW_COPY);
|
|
|
|
osg::ref_ptr<SceneUtil::KeyframeController> cloned = osg::clone(it->second.get(), osg::CopyOp::SHALLOW_COPY);
|
|
|
|
cloned->setSource(mAnimationTimePtr[blendMask]);
|
|
|
|
cloned->setSource(mAnimationTimePtr[blendMask]);
|
|
|
|
|
|
|
|
|
|
|
|
animsrc->mControllerMap[blendMask].insert(std::make_pair(bonename, cloned));
|
|
|
|
animsrc->mControllerMap[blendMask].insert(std::make_pair(bonename, cloned));
|
|
|
@ -810,7 +807,7 @@ namespace MWRender
|
|
|
|
AnimSourceList::const_iterator iter(mAnimSources.begin());
|
|
|
|
AnimSourceList::const_iterator iter(mAnimSources.begin());
|
|
|
|
for(;iter != mAnimSources.end();++iter)
|
|
|
|
for(;iter != mAnimSources.end();++iter)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys();
|
|
|
|
if (keys.hasGroupStart(anim))
|
|
|
|
if (keys.hasGroupStart(anim))
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -822,7 +819,7 @@ namespace MWRender
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter)
|
|
|
|
for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys();
|
|
|
|
|
|
|
|
|
|
|
|
const auto found = keys.findGroupStart(groupname);
|
|
|
|
const auto found = keys.findGroupStart(groupname);
|
|
|
|
if(found != keys.end())
|
|
|
|
if(found != keys.end())
|
|
|
@ -835,7 +832,7 @@ namespace MWRender
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter)
|
|
|
|
for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys();
|
|
|
|
|
|
|
|
|
|
|
|
for(auto iterKey = keys.begin(); iterKey != keys.end(); ++iterKey)
|
|
|
|
for(auto iterKey = keys.begin(); iterKey != keys.end(); ++iterKey)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -847,8 +844,8 @@ namespace MWRender
|
|
|
|
return -1.f;
|
|
|
|
return -1.f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Animation::handleTextKey(AnimState &state, const std::string &groupname, NifOsg::TextKeyMap::ConstIterator key,
|
|
|
|
void Animation::handleTextKey(AnimState &state, const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key,
|
|
|
|
const NifOsg::TextKeyMap& map)
|
|
|
|
const SceneUtil::TextKeyMap& map)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const std::string &evt = key->second;
|
|
|
|
const std::string &evt = key->second;
|
|
|
|
|
|
|
|
|
|
|
@ -911,7 +908,7 @@ namespace MWRender
|
|
|
|
AnimSourceList::reverse_iterator iter(mAnimSources.rbegin());
|
|
|
|
AnimSourceList::reverse_iterator iter(mAnimSources.rbegin());
|
|
|
|
for(;iter != mAnimSources.rend();++iter)
|
|
|
|
for(;iter != mAnimSources.rend();++iter)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const NifOsg::TextKeyMap &textkeys = (*iter)->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &textkeys = (*iter)->getTextKeys();
|
|
|
|
if(reset(state, textkeys, groupname, start, stop, startpoint, loopfallback))
|
|
|
|
if(reset(state, textkeys, groupname, start, stop, startpoint, loopfallback))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
state.mSource = *iter;
|
|
|
|
state.mSource = *iter;
|
|
|
@ -956,7 +953,7 @@ namespace MWRender
|
|
|
|
resetActiveGroups();
|
|
|
|
resetActiveGroups();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Animation::reset(AnimState &state, const NifOsg::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, bool loopfallback)
|
|
|
|
bool Animation::reset(AnimState &state, const SceneUtil::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, bool loopfallback)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Look for text keys in reverse. This normally wouldn't matter, but for some reason undeadwolf_2.nif has two
|
|
|
|
// Look for text keys in reverse. This normally wouldn't matter, but for some reason undeadwolf_2.nif has two
|
|
|
|
// separate walkforward keys, and the last one is supposed to be used.
|
|
|
|
// separate walkforward keys, and the last one is supposed to be used.
|
|
|
@ -1186,7 +1183,7 @@ namespace MWRender
|
|
|
|
AnimSourceList::const_reverse_iterator animsrc(mAnimSources.rbegin());
|
|
|
|
AnimSourceList::const_reverse_iterator animsrc(mAnimSources.rbegin());
|
|
|
|
for(;animsrc != mAnimSources.rend();++animsrc)
|
|
|
|
for(;animsrc != mAnimSources.rend();++animsrc)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const NifOsg::TextKeyMap &keys = (*animsrc)->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &keys = (*animsrc)->getTextKeys();
|
|
|
|
if (keys.hasGroupStart(groupname))
|
|
|
|
if (keys.hasGroupStart(groupname))
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1194,7 +1191,7 @@ namespace MWRender
|
|
|
|
return 0.0f;
|
|
|
|
return 0.0f;
|
|
|
|
|
|
|
|
|
|
|
|
float velocity = 0.0f;
|
|
|
|
float velocity = 0.0f;
|
|
|
|
const NifOsg::TextKeyMap &keys = (*animsrc)->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &keys = (*animsrc)->getTextKeys();
|
|
|
|
|
|
|
|
|
|
|
|
const AnimSource::ControllerMap& ctrls = (*animsrc)->mControllerMap[0];
|
|
|
|
const AnimSource::ControllerMap& ctrls = (*animsrc)->mControllerMap[0];
|
|
|
|
for (AnimSource::ControllerMap::const_iterator it = ctrls.begin(); it != ctrls.end(); ++it)
|
|
|
|
for (AnimSource::ControllerMap::const_iterator it = ctrls.begin(); it != ctrls.end(); ++it)
|
|
|
@ -1215,7 +1212,7 @@ namespace MWRender
|
|
|
|
|
|
|
|
|
|
|
|
while(!(velocity > 1.0f) && ++animiter != mAnimSources.rend())
|
|
|
|
while(!(velocity > 1.0f) && ++animiter != mAnimSources.rend())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const NifOsg::TextKeyMap &keys2 = (*animiter)->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &keys2 = (*animiter)->getTextKeys();
|
|
|
|
|
|
|
|
|
|
|
|
const AnimSource::ControllerMap& ctrls2 = (*animiter)->mControllerMap[0];
|
|
|
|
const AnimSource::ControllerMap& ctrls2 = (*animiter)->mControllerMap[0];
|
|
|
|
for (AnimSource::ControllerMap::const_iterator it = ctrls2.begin(); it != ctrls2.end(); ++it)
|
|
|
|
for (AnimSource::ControllerMap::const_iterator it = ctrls2.begin(); it != ctrls2.end(); ++it)
|
|
|
@ -1265,7 +1262,7 @@ namespace MWRender
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const NifOsg::TextKeyMap &textkeys = state.mSource->getTextKeys();
|
|
|
|
const SceneUtil::TextKeyMap &textkeys = state.mSource->getTextKeys();
|
|
|
|
auto textkey = textkeys.upperBound(state.getTime());
|
|
|
|
auto textkey = textkeys.upperBound(state.getTime());
|
|
|
|
|
|
|
|
|
|
|
|
float timepassed = duration * state.mSpeedMult;
|
|
|
|
float timepassed = duration * state.mSpeedMult;
|
|
|
@ -1839,7 +1836,7 @@ namespace MWRender
|
|
|
|
osg::Callback* cb = node->getUpdateCallback();
|
|
|
|
osg::Callback* cb = node->getUpdateCallback();
|
|
|
|
while (cb)
|
|
|
|
while (cb)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (dynamic_cast<NifOsg::KeyframeController*>(cb))
|
|
|
|
if (dynamic_cast<SceneUtil::KeyframeController*>(cb))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
foundKeyframeCtrl = true;
|
|
|
|
foundKeyframeCtrl = true;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|