mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 07:56:37 +00:00 
			
		
		
		
	Merge remote-tracking branch 'chris/animation'
This commit is contained in:
		
						commit
						20a263738a
					
				
					 3 changed files with 75 additions and 91 deletions
				
			
		|  | @ -49,44 +49,27 @@ bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTim | |||
| 
 | ||||
|         std::string::const_iterator strpos = iter->second.begin(); | ||||
|         std::string::const_iterator strend = iter->second.end(); | ||||
|         size_t strlen = strend-strpos; | ||||
| 
 | ||||
|         while(strpos != strend) | ||||
|         if(start.size() <= strlen && std::mismatch(strpos, strend, start.begin(), checklow()).first == strend) | ||||
|         { | ||||
|             size_t strlen = strend-strpos; | ||||
|             std::string::const_iterator striter; | ||||
| 
 | ||||
|             if(start.size() <= strlen && | ||||
|                ((striter=std::mismatch(strpos, strend, start.begin(), checklow()).first) == strend || | ||||
|                 *striter == '\r' || *striter == '\n')) | ||||
|             { | ||||
|                 times->mStart = iter->first; | ||||
|                 times->mLoopStart = iter->first; | ||||
|             } | ||||
|             else if(startloop.size() <= strlen && | ||||
|                     ((striter=std::mismatch(strpos, strend, startloop.begin(), checklow()).first) == strend || | ||||
|                      *striter == '\r' || *striter == '\n')) | ||||
|             { | ||||
|                 times->mLoopStart = iter->first; | ||||
|             } | ||||
|             else if(stoploop.size() <= strlen && | ||||
|                     ((striter=std::mismatch(strpos, strend, stoploop.begin(), checklow()).first) == strend || | ||||
|                      *striter == '\r' || *striter == '\n')) | ||||
|             { | ||||
|             times->mStart = iter->first; | ||||
|             times->mLoopStart = iter->first; | ||||
|         } | ||||
|         else if(startloop.size() <= strlen && std::mismatch(strpos, strend, startloop.begin(), checklow()).first == strend) | ||||
|         { | ||||
|             times->mLoopStart = iter->first; | ||||
|         } | ||||
|         else if(stoploop.size() <= strlen && std::mismatch(strpos, strend, stoploop.begin(), checklow()).first == strend) | ||||
|         { | ||||
|             times->mLoopStop = iter->first; | ||||
|         } | ||||
|         else if(stop.size() <= strlen && std::mismatch(strpos, strend, stop.begin(), checklow()).first == strend) | ||||
|         { | ||||
|             times->mStop = iter->first; | ||||
|             if(times->mLoopStop < 0.0f) | ||||
|                 times->mLoopStop = iter->first; | ||||
|             } | ||||
|             else if(stop.size() <= strlen && | ||||
|                     ((striter=std::mismatch(strpos, strend, stop.begin(), checklow()).first) == strend || | ||||
|                      *striter == '\r' || *striter == '\n')) | ||||
|             { | ||||
|                 times->mStop = iter->first; | ||||
|                 if(times->mLoopStop < 0.0f) | ||||
|                     times->mLoopStop = iter->first; | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             strpos = std::find(strpos+1, strend, '\n'); | ||||
|             while(strpos != strend && *strpos == '\n') | ||||
|                 strpos++; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -104,17 +87,9 @@ void Animation::playGroup(std::string groupname, int mode, int loops) | |||
|         times.mStart = times.mLoopStart = 0.0f; | ||||
|         times.mLoopStop = times.mStop = 0.0f; | ||||
| 
 | ||||
|         if(mEntityList.mSkelBase) | ||||
|         { | ||||
|             Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates(); | ||||
|             Ogre::AnimationStateIterator as = aset->getAnimationStateIterator(); | ||||
|             while(as.hasMoreElements()) | ||||
|             { | ||||
|                 Ogre::AnimationState *state = as.getNext(); | ||||
|                 times.mLoopStop = times.mStop = state->getLength(); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         NifOgre::TextKeyMap::const_reverse_iterator iter = mTextKeys.rbegin(); | ||||
|         if(iter != mTextKeys.rend()) | ||||
|             times.mLoopStop = times.mStop = iter->first; | ||||
|     } | ||||
|     else if(!findGroupTimes(groupname, ×)) | ||||
|         throw std::runtime_error("Failed to find animation group "+groupname); | ||||
|  |  | |||
|  | @ -152,6 +152,28 @@ static void fail(const std::string &msg) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void insertTextKeys(const Nif::NiTextKeyExtraData *tk, TextKeyMap *textkeys) | ||||
| { | ||||
|     for(size_t i = 0;i < tk->list.size();i++) | ||||
|     { | ||||
|         const std::string &str = tk->list[i].text; | ||||
|         std::string::size_type pos = 0; | ||||
|         while(pos < str.length()) | ||||
|         { | ||||
|             while(pos < str.length() && ::isspace(str[pos])) | ||||
|                 pos++; | ||||
|             if(pos >= str.length()) | ||||
|                 break; | ||||
| 
 | ||||
|             std::string::size_type nextpos = std::min(str.find('\r', pos), str.find('\n', pos)); | ||||
|             textkeys->insert(std::make_pair(tk->list[i].time, str.substr(pos, nextpos-pos))); | ||||
| 
 | ||||
|             pos = nextpos; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void buildBones(Ogre::Skeleton *skel, const Nif::Node *node, std::vector<Nif::NiKeyframeController*> &ctrls, Ogre::Bone *parent=NULL) | ||||
| { | ||||
|     Ogre::Bone *bone; | ||||
|  | @ -279,18 +301,13 @@ void loadResource(Ogre::Resource *resource) | |||
|         { | ||||
|             float curtime = kfc->timeStop; | ||||
| 
 | ||||
| 
 | ||||
|             //Get latest time
 | ||||
|             if(quatiter != quatkeys.mKeys.end()){ | ||||
|             if(quatiter != quatkeys.mKeys.end()) | ||||
|                 curtime = std::min(curtime, quatiter->mTime); | ||||
|             } | ||||
|             if(traniter != trankeys.mKeys.end()){ | ||||
|             if(traniter != trankeys.mKeys.end()) | ||||
|                 curtime = std::min(curtime, traniter->mTime); | ||||
|                  | ||||
|             } | ||||
|             if(scaleiter != scalekeys.mKeys.end()){ | ||||
|             if(scaleiter != scalekeys.mKeys.end()) | ||||
|                 curtime = std::min(curtime, scaleiter->mTime); | ||||
|             } | ||||
| 
 | ||||
|             curtime = std::max(curtime, kfc->timeStart); | ||||
|             if(curtime >= kfc->timeStop) | ||||
|  | @ -299,15 +316,33 @@ void loadResource(Ogre::Resource *resource) | |||
|                 curtime = kfc->timeStop; | ||||
|             } | ||||
| 
 | ||||
|             bool rinterpolate = quatiter != quatkeys.mKeys.end() && quatiter != quatkeys.mKeys.begin()  && curtime != quatiter->mTime; | ||||
|             bool tinterpolate = traniter != trankeys.mKeys.end() && traniter != trankeys.mKeys.begin() && curtime != traniter->mTime; | ||||
|             bool sinterpolate = scaleiter != scalekeys.mKeys.end() && scaleiter != scalekeys.mKeys.begin() && curtime != scaleiter->mTime; | ||||
| 
 | ||||
|              | ||||
|             // Get the latest quaternions, translations, and scales for the
 | ||||
|             // current time
 | ||||
|             while(quatiter != quatkeys.mKeys.end() && curtime >= quatiter->mTime) | ||||
|             { | ||||
|                 lastquat = curquat; | ||||
|                 quatiter++; | ||||
|                 if(quatiter != quatkeys.mKeys.end()) | ||||
|                     curquat = startquat.Inverse() * quatiter->mValue ; | ||||
|             } | ||||
|             while(traniter != trankeys.mKeys.end() && curtime >= traniter->mTime) | ||||
|             { | ||||
|                 lasttrans = curtrans; | ||||
|                 traniter++; | ||||
|                 if(traniter != trankeys.mKeys.end()) | ||||
|                     curtrans = traniter->mValue - starttrans; | ||||
|             } | ||||
|             while(scaleiter != scalekeys.mKeys.end() && curtime >= scaleiter->mTime) | ||||
|             { | ||||
|                 lastscale = curscale; | ||||
|                 scaleiter++; | ||||
|                 if(scaleiter != scalekeys.mKeys.end()) | ||||
|                     curscale = Ogre::Vector3(scaleiter->mValue) / startscale; | ||||
|             } | ||||
| 
 | ||||
|             Ogre::TransformKeyFrame *kframe; | ||||
|             kframe = nodetrack->createNodeKeyFrame(curtime); | ||||
|             if(!rinterpolate) | ||||
|             if(quatiter == quatkeys.mKeys.end() || quatiter == quatkeys.mKeys.begin()) | ||||
|                 kframe->setRotation(curquat); | ||||
|             else | ||||
|             { | ||||
|  | @ -315,7 +350,7 @@ void loadResource(Ogre::Resource *resource) | |||
|                 float diff = (curtime-last->mTime) / (quatiter->mTime-last->mTime); | ||||
|                 kframe->setRotation(Ogre::Quaternion::nlerp(diff, lastquat, curquat)); | ||||
|             } | ||||
|             if(!tinterpolate) | ||||
|             if(traniter == trankeys.mKeys.end() || traniter == trankeys.mKeys.begin()) | ||||
|                 kframe->setTranslate(curtrans); | ||||
|             else | ||||
|             { | ||||
|  | @ -323,7 +358,7 @@ void loadResource(Ogre::Resource *resource) | |||
|                 float diff = (curtime-last->mTime) / (traniter->mTime-last->mTime); | ||||
|                 kframe->setTranslate(lasttrans + ((curtrans-lasttrans)*diff)); | ||||
|             } | ||||
|             if(!sinterpolate) | ||||
|             if(scaleiter == scalekeys.mKeys.end() || scaleiter == scalekeys.mKeys.begin()) | ||||
|                 kframe->setScale(curscale); | ||||
|             else | ||||
|             { | ||||
|  | @ -331,31 +366,6 @@ void loadResource(Ogre::Resource *resource) | |||
|                 float diff = (curtime-last->mTime) / (scaleiter->mTime-last->mTime); | ||||
|                 kframe->setScale(lastscale + ((curscale-lastscale)*diff)); | ||||
|             } | ||||
| 
 | ||||
|             // Get the latest quaternion, translation, and scale for the
 | ||||
|             // current time
 | ||||
|             while(quatiter != quatkeys.mKeys.end() && curtime >= quatiter->mTime) | ||||
|             { | ||||
|                 quatiter++; | ||||
|                 lastquat = curquat; | ||||
|                 if(quatiter != quatkeys.mKeys.end()) | ||||
|                     curquat = startquat.Inverse() * quatiter->mValue ; | ||||
|             } | ||||
|             while(traniter != trankeys.mKeys.end() && curtime >= traniter->mTime) | ||||
|             { | ||||
|                 traniter++; | ||||
|                 lasttrans = curtrans; | ||||
|                 if(traniter != trankeys.mKeys.end()) | ||||
|                     curtrans = traniter->mValue - starttrans; | ||||
|             } | ||||
|             while(scaleiter != scalekeys.mKeys.end() && curtime >= scaleiter->mTime) | ||||
|             { | ||||
|                 scaleiter++; | ||||
|                 lastscale = curscale; | ||||
|                 if(scaleiter != scalekeys.mKeys.end()) | ||||
|                     curscale = Ogre::Vector3(scaleiter->mValue) / startscale; | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
|     anim->optimise(); | ||||
|  | @ -371,8 +381,7 @@ bool createSkeleton(const std::string &name, const std::string &group, TextKeyMa | |||
|             if(e->recType == Nif::RC_NiTextKeyExtraData) | ||||
|             { | ||||
|                 const Nif::NiTextKeyExtraData *tk = static_cast<const Nif::NiTextKeyExtraData*>(e.getPtr()); | ||||
|                 for(size_t i = 0;i < tk->list.size();i++) | ||||
|                     (*textkeys)[tk->list[i].time] = tk->list[i].text; | ||||
|                 insertTextKeys(tk, textkeys); | ||||
|             } | ||||
|             e = e->extra; | ||||
|         } | ||||
|  |  | |||
|  | @ -59,7 +59,7 @@ namespace NifOgre | |||
| { | ||||
| 
 | ||||
| // FIXME: These should not be in NifOgre, it works agnostic of what model format is used
 | ||||
| typedef std::map<float,std::string> TextKeyMap; | ||||
| typedef std::multimap<float,std::string> TextKeyMap; | ||||
| struct EntityList { | ||||
|     std::vector<Ogre::Entity*> mEntities; | ||||
|     Ogre::Entity *mSkelBase; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue