mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-10 06:44:29 +00:00
Use text keys for each animation
This commit is contained in:
parent
4054934f16
commit
1e38e381a4
@ -21,8 +21,6 @@ Animation::Animation(const MWWorld::Ptr &ptr)
|
|||||||
, mStartPosition(0.0f)
|
, mStartPosition(0.0f)
|
||||||
, mLastPosition(0.0f)
|
, mLastPosition(0.0f)
|
||||||
, mTime(0.0f)
|
, mTime(0.0f)
|
||||||
, mCurGroup(mTextKeys.end())
|
|
||||||
, mNextGroup(mTextKeys.end())
|
|
||||||
, mSkipFrame(false)
|
, mSkipFrame(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -48,19 +46,27 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
|
|||||||
mEntityList = NifOgre::NIFLoader::createEntities(mInsert, model);
|
mEntityList = NifOgre::NIFLoader::createEntities(mInsert, model);
|
||||||
if(mEntityList.mSkelBase)
|
if(mEntityList.mSkelBase)
|
||||||
{
|
{
|
||||||
|
Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
|
||||||
|
Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator();
|
||||||
|
while(asiter.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::AnimationState *state = asiter.getNext();
|
||||||
|
state->setEnabled(false);
|
||||||
|
state->setLoop(false);
|
||||||
|
}
|
||||||
|
|
||||||
Ogre::SkeletonInstance *skelinst = mEntityList.mSkelBase->getSkeleton();
|
Ogre::SkeletonInstance *skelinst = mEntityList.mSkelBase->getSkeleton();
|
||||||
// Would be nice if Ogre::SkeletonInstance allowed access to the 'master' Ogre::SkeletonPtr.
|
// Would be nice if Ogre::SkeletonInstance allowed access to the 'master' Ogre::SkeletonPtr.
|
||||||
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
|
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
|
||||||
Ogre::SkeletonPtr skel = skelMgr.getByName(skelinst->getName());
|
Ogre::SkeletonPtr skel = skelMgr.getByName(skelinst->getName());
|
||||||
Ogre::Skeleton::BoneIterator iter = skel->getBoneIterator();
|
Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
|
||||||
while(iter.hasMoreElements())
|
while(boneiter.hasMoreElements())
|
||||||
{
|
{
|
||||||
Ogre::Bone *bone = iter.getNext();
|
Ogre::Bone *bone = boneiter.peekNext();
|
||||||
const Ogre::Any &data = bone->getUserObjectBindings().getUserAny(NifOgre::sTextKeyExtraDataID);
|
const Ogre::Any &data = bone->getUserObjectBindings().getUserAny(NifOgre::sTextKeyExtraDataID);
|
||||||
if(!data.isEmpty())
|
if(!data.isEmpty())
|
||||||
{
|
{
|
||||||
mTextKeys = Ogre::any_cast<NifOgre::TextKeyMap>(data);
|
mTextKeys["all"] = Ogre::any_cast<NifOgre::TextKeyMap>(data);
|
||||||
mNextGroup = mCurGroup = GroupTimes(mTextKeys.begin());
|
|
||||||
|
|
||||||
mAccumRoot = skelinst->getRootBone();
|
mAccumRoot = skelinst->getRootBone();
|
||||||
mAccumRoot->setManuallyControlled(true);
|
mAccumRoot->setManuallyControlled(true);
|
||||||
@ -70,17 +76,19 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
|
|||||||
mLastPosition = mStartPosition;
|
mLastPosition = mStartPosition;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
boneiter.moveNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mTextKeys.size() > 0)
|
if(boneiter.hasMoreElements())
|
||||||
{
|
{
|
||||||
Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates();
|
asiter = aset->getAnimationStateIterator();
|
||||||
Ogre::AnimationStateIterator as = aset->getAnimationStateIterator();
|
while(asiter.hasMoreElements())
|
||||||
while(as.hasMoreElements())
|
|
||||||
{
|
{
|
||||||
Ogre::AnimationState *state = as.getNext();
|
Ogre::AnimationState *state = asiter.getNext();
|
||||||
state->setEnabled(false);
|
Ogre::UserObjectBindings &bindings = boneiter.peekNext()->getUserObjectBindings();
|
||||||
state->setLoop(false);
|
const Ogre::Any &data = bindings.getUserAny(std::string(NifOgre::sTextKeyExtraDataID)+"@"+state->getAnimationName());
|
||||||
|
if(!data.isEmpty())
|
||||||
|
mTextKeys[state->getAnimationName()] = Ogre::any_cast<NifOgre::TextKeyMap>(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,13 +135,28 @@ void Animation::resetPosition(float time)
|
|||||||
|
|
||||||
bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTimes *times)
|
bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTimes *times)
|
||||||
{
|
{
|
||||||
|
const NifOgre::TextKeyMap &textkeys = mTextKeys[groupname];
|
||||||
|
if(textkeys.size() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(groupname == "all")
|
||||||
|
{
|
||||||
|
times->mStart = times->mLoopStart = textkeys.begin();
|
||||||
|
times->mLoopStop = times->mStop = textkeys.end();
|
||||||
|
times->mLoopStop--; times->mStop--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string start = groupname+": start";
|
const std::string start = groupname+": start";
|
||||||
const std::string startloop = groupname+": loop start";
|
const std::string startloop = groupname+": loop start";
|
||||||
const std::string stop = groupname+": stop";
|
const std::string stop = groupname+": stop";
|
||||||
const std::string stoploop = groupname+": loop stop";
|
const std::string stoploop = groupname+": loop stop";
|
||||||
|
|
||||||
|
times->mStart = times->mLoopStart =
|
||||||
|
times->mStop = times->mLoopStop = textkeys.end();
|
||||||
|
|
||||||
NifOgre::TextKeyMap::const_iterator iter;
|
NifOgre::TextKeyMap::const_iterator iter;
|
||||||
for(iter = mTextKeys.begin();iter != mTextKeys.end();iter++)
|
for(iter = textkeys.begin();iter != textkeys.end();iter++)
|
||||||
{
|
{
|
||||||
if(start == iter->second)
|
if(start == iter->second)
|
||||||
{
|
{
|
||||||
@ -147,9 +170,9 @@ bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTim
|
|||||||
else if(stop == iter->second)
|
else if(stop == iter->second)
|
||||||
{
|
{
|
||||||
times->mStop = iter;
|
times->mStop = iter;
|
||||||
if(times->mLoopStop == mTextKeys.end())
|
if(times->mLoopStop == textkeys.end())
|
||||||
times->mLoopStop = iter;
|
times->mLoopStop = iter;
|
||||||
return (times->mStart != mTextKeys.end());
|
return (times->mStart != textkeys.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,23 +182,14 @@ bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTim
|
|||||||
|
|
||||||
void Animation::playGroup(std::string groupname, int mode, int loops)
|
void Animation::playGroup(std::string groupname, int mode, int loops)
|
||||||
{
|
{
|
||||||
GroupTimes times(mTextKeys.end());
|
GroupTimes times;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(mTextKeys.size() == 0)
|
|
||||||
throw std::runtime_error("Trying to animate an unanimate object");
|
|
||||||
|
|
||||||
std::transform(groupname.begin(), groupname.end(), groupname.begin(), ::tolower);
|
std::transform(groupname.begin(), groupname.end(), groupname.begin(), ::tolower);
|
||||||
times.mAnimState = mEntityList.mSkelBase->getAnimationState(groupname);
|
times.mAnimState = mEntityList.mSkelBase->getAnimationState(groupname);
|
||||||
times.mLoops = loops;
|
times.mLoops = loops;
|
||||||
|
|
||||||
if(groupname == "all")
|
if(!findGroupTimes(groupname, ×))
|
||||||
{
|
|
||||||
times.mStart = times.mLoopStart = mTextKeys.begin();
|
|
||||||
times.mLoopStop = times.mStop = mTextKeys.end();
|
|
||||||
times.mLoopStop--; times.mStop--;
|
|
||||||
}
|
|
||||||
else if(!findGroupTimes(groupname, ×))
|
|
||||||
throw std::runtime_error("Failed to find animation group "+groupname);
|
throw std::runtime_error("Failed to find animation group "+groupname);
|
||||||
}
|
}
|
||||||
catch(std::exception &e) {
|
catch(std::exception &e) {
|
||||||
@ -190,7 +204,7 @@ void Animation::playGroup(std::string groupname, int mode, int loops)
|
|||||||
if(mCurGroup.mAnimState)
|
if(mCurGroup.mAnimState)
|
||||||
mCurGroup.mAnimState->setEnabled(false);
|
mCurGroup.mAnimState->setEnabled(false);
|
||||||
mCurGroup = times;
|
mCurGroup = times;
|
||||||
mNextGroup = GroupTimes(mTextKeys.end());
|
mNextGroup = GroupTimes();
|
||||||
mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart)->first;
|
mTime = ((mode==2) ? mCurGroup.mLoopStart : mCurGroup.mStart)->first;
|
||||||
mCurGroup.mAnimState->setEnabled(true);
|
mCurGroup.mAnimState->setEnabled(true);
|
||||||
resetPosition(mTime);
|
resetPosition(mTime);
|
||||||
@ -226,9 +240,9 @@ void Animation::runAnimation(float timepassed)
|
|||||||
mTime = mTime - mCurGroup.mStop->first + mNextGroup.mStart->first;
|
mTime = mTime - mCurGroup.mStop->first + mNextGroup.mStart->first;
|
||||||
mCurGroup.mAnimState->setEnabled(false);
|
mCurGroup.mAnimState->setEnabled(false);
|
||||||
mCurGroup = mNextGroup;
|
mCurGroup = mNextGroup;
|
||||||
mNextGroup = GroupTimes(mTextKeys.end());
|
mNextGroup = GroupTimes();
|
||||||
mCurGroup.mAnimState->setEnabled(true);
|
mCurGroup.mAnimState->setEnabled(true);
|
||||||
resetPosition(mNextGroup.mStart->first);
|
resetPosition(mCurGroup.mStart->first);
|
||||||
goto recheck;
|
goto recheck;
|
||||||
}
|
}
|
||||||
mTime = mCurGroup.mStop->first;
|
mTime = mCurGroup.mStop->first;
|
||||||
|
@ -19,9 +19,8 @@ class Animation
|
|||||||
Ogre::AnimationState *mAnimState;
|
Ogre::AnimationState *mAnimState;
|
||||||
size_t mLoops;
|
size_t mLoops;
|
||||||
|
|
||||||
GroupTimes(NifOgre::TextKeyMap::const_iterator iter)
|
GroupTimes()
|
||||||
: mStart(iter), mStop(iter), mLoopStart(iter), mLoopStop(iter),
|
: mAnimState(NULL), mLoops(0)
|
||||||
mAnimState(NULL), mLoops(0)
|
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ protected:
|
|||||||
Ogre::SceneNode* mInsert;
|
Ogre::SceneNode* mInsert;
|
||||||
|
|
||||||
NifOgre::EntityList mEntityList;
|
NifOgre::EntityList mEntityList;
|
||||||
NifOgre::TextKeyMap mTextKeys;
|
std::map<std::string,NifOgre::TextKeyMap> mTextKeys;
|
||||||
Ogre::Bone *mAccumRoot;
|
Ogre::Bone *mAccumRoot;
|
||||||
Ogre::Bone *mNonAccumRoot;
|
Ogre::Bone *mNonAccumRoot;
|
||||||
Ogre::Vector3 mStartPosition;
|
Ogre::Vector3 mStartPosition;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user