OSDN Git Service

a47c9e3d1cb26380df6eb2b8f7108e764492a380
[moflib/moflib.git] / moflib-1.0 / moflib / moflib / mof / Interpolation.hpp
1  #pragma once
2  #include "mof/Vector2D.hpp"
3  #include "mof/stream/Manipulator.hpp"
4  #include <map>
5  #include <algorithm>
6  
7  namespace mof{
8  
9         template <typename T>
10         T stepInterpolate(const std::map<mof::FrameNumber , T>& map , mof::FrameNumber current ){
11                 if(map.empty())throw std::invalid_argument("the map is empty");
12                 for(
13                         typename std::map<mof::FrameNumber , T>::const_reverse_iterator itr = map.rbegin() ;
14                         itr != map.rend() ; 
15                         ++itr
16                 ){
17                         if(itr->first <= current)return itr->second;
18                 }
19                 return map.begin()->second;//default
20         }
21   
22         template<class T> inline
23         T calcLinerInterpolationValue( float blending , const T& prevObj , const T& nextObj){
24                 return (1 - blending) * prevObj + blending * nextObj;
25         }       
26    
27     //\8cë\8d·\92á\8c¸\82Ì\82½\82ß\82Ì\93Á\8eê\89»
28     /*template<> inline
29         Vector2D calcLinerInterpolationValue( float blending , const Vector2D& prev , const Vector2D& next )
30     {
31                 return mof::Vector2D
32         (
33              prev.x != next.x ? (1 - blending) * prev.x + blending * next.x : prev.x , 
34              prev.y != next.y ? (1 - blending) * prev.y + blending * next.y : prev.y  
35         );
36         }*/     
37
38         template <typename T>
39         T linerInterpolate(const std::map<mof::FrameNumber , T>& map , mof::FrameNumber current ){
40                 if(map.empty())throw std::invalid_argument("the map is empty");
41                 typename std::map<mof::FrameNumber , T>::const_iterator n = map.find(current);
42                 if(n != map.end())return n->second;// just key frame
43                 
44                 //\92¼\91O\81A\92¼\8cã\82Ì\83L\81[\82ð\8c\9f\8dõ
45                 mof::FrameNumber prevKeyFrame = current;
46                 bool foundPrev = false;
47                 T prevObj;
48                 mof::FrameNumber nextKeyFrame = current;
49                 bool foundNext = false;
50                 T nextObj;
51                 
52                 for(
53                                 typename std::map<mof::FrameNumber , T>::const_iterator itr = map.begin() ;
54                                 itr != map.end() ;
55                                 ++itr
56                         ){
57                         if(itr->first < current && (!foundPrev || itr->first > prevKeyFrame)){
58                                 foundPrev = true;
59                                 prevKeyFrame = itr->first;
60                                 prevObj = itr->second;
61                         }
62                         else if(itr->first > current && (!foundNext || itr->first < nextKeyFrame)){
63                                 foundNext = true;
64                                 nextKeyFrame = itr->first;
65                                 nextObj = itr->second;
66                         }
67                         
68                 }
69                 
70                 assert(foundPrev || foundNext);
71                 if(!foundPrev && foundNext)return nextObj;//\92¼\91O\82Ì\83L\81[\82Í\8c©\82Â\82©\82ç\82È\82©\82Á\82½
72                 else if(foundPrev && !foundNext)return prevObj;//\92¼\8cã\82Ì\83L\81[\82Í\8c©\82Â\82©\82ç\82È\82©\82Á\82½
73                 float blending = static_cast<float>(current - prevKeyFrame) / static_cast<float>(nextKeyFrame - prevKeyFrame);
74                 return calcLinerInterpolationValue<T>(blending , prevObj ,  nextObj);
75         }
76  
77  } //namespace mof
78  
79