Go to the documentation of this file.00001 #ifndef OPENTISSUE_KINEMATICS_ANIMATION_ANIMATION_KEYFRAME_JOINT_CHANNELS_H
00002 #define OPENTISSUE_KINEMATICS_ANIMATION_ANIMATION_KEYFRAME_JOINT_CHANNELS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <vector>
00013
00014 namespace OpenTissue
00015 {
00016 namespace animation
00017 {
00018
00019
00023 template<typename skeleton_type_>
00024 class KeyframeJointChannels
00025 {
00026 public:
00027
00028 typedef skeleton_type_ skeleton_type;
00029 typedef typename skeleton_type::math_types math_types;
00030 typedef typename math_types::coordsys_type coordsys_type;
00031 typedef typename math_types::real_type real_type;
00032
00033 protected:
00034
00035 class Keyframe
00036 {
00037 public:
00038
00039 real_type m_time;
00040 coordsys_type m_value;
00041
00042 public:
00043
00044 Keyframe(real_type const & local_time, coordsys_type const & value)
00045 : m_time(local_time)
00046 , m_value(value)
00047 {}
00048 };
00049
00050 typedef std::vector<Keyframe> keyframe_container;
00051 typedef typename keyframe_container::iterator keyframe_iterator;
00052
00053 protected:
00054
00055 size_t m_bone_number;
00056 int m_next;
00057 int m_prev;
00058 keyframe_container m_keyframes;
00059
00060 public:
00061
00062 KeyframeJointChannels()
00063 : m_bone_number(~0)
00064 , m_next(-1)
00065 , m_prev(-1)
00066 {};
00067
00068 virtual ~KeyframeJointChannels(){}
00069
00070 public:
00071
00072 size_t const & get_bone_number() const {return m_bone_number;}
00073
00074 void set_bone_number(size_t const & number){ m_bone_number = number;}
00075
00076 void add_key(real_type const & local_time, coordsys_type const & value)
00077 {
00078
00079 if(m_keyframes.empty())
00080 {
00081 m_keyframes.push_back(Keyframe(local_time,value));
00082 return;
00083 }
00084
00085 if(m_keyframes.back().m_time < local_time)
00086 {
00087 m_keyframes.push_back(Keyframe(local_time,value));
00088 return;
00089 }
00090
00091
00092
00093 keyframe_iterator begin = m_keyframes.end();
00094 keyframe_iterator end = m_keyframes.end();
00095 keyframe_iterator prev = begin;
00096 keyframe_iterator next = prev+1;
00097
00098
00099 while( !((prev->m_time < local_time) && (local_time <= next->m_time)) )
00100 {
00101 ++prev;
00102 ++next;
00103 }
00104 assert(prev->m_time < local_time);
00105 assert(local_time <= next->m_time);
00106
00107
00108 if(next->m_time==local_time)
00109 {
00110 next->m_value = value;
00111 return;
00112 }
00113
00114 m_keyframes.insert(next,Keyframe(local_time,value));
00115 }
00116
00117 public:
00118
00126 coordsys_type get_value(real_type const & local_time)
00127 {
00128 int N = static_cast<int>( m_keyframes.size() );
00129
00130
00131 if(!N)
00132 return coordsys_type();
00133
00134
00135 if(local_time <= m_keyframes[0].m_time)
00136 return m_keyframes[0].m_value;
00137
00138 if(local_time >= m_keyframes[N-1].m_time)
00139 return m_keyframes[N-1].m_value;
00140
00141
00142 if(m_next==m_prev)
00143 {
00144 m_next = 1;
00145 m_prev = 0;
00146 }
00147
00148
00149
00150
00151
00152 while( m_next<N && local_time > m_keyframes[m_next].m_time )
00153 ++m_next;
00154
00155 while( m_next>1 && local_time <= m_keyframes[m_next-1].m_time )
00156 --m_next;
00157
00158 m_prev = m_next - 1;
00159
00160 assert(m_prev>=0);
00161 assert(m_next>=1);
00162 assert(m_next<N);
00163 assert(m_prev<(N-1));
00164
00165
00166 if(m_keyframes[m_next].m_time == local_time)
00167 return m_keyframes[m_next].m_value;
00168
00169
00170
00171 coordsys_type blended;
00172
00173 real_type weight = (local_time - m_keyframes[m_prev].m_time) / (m_keyframes[m_next].m_time - m_keyframes[m_prev].m_time);
00174 assert(weight>=0);
00175 assert(weight<=1);
00176
00177
00178 blended.T() = m_keyframes[m_prev].m_value.T()*(1-weight) + m_keyframes[m_next].m_value.T()*weight;
00179 blended.Q() = slerp(m_keyframes[m_prev].m_value.Q(), m_keyframes[m_next].m_value.Q(),weight);
00180
00181 return blended;
00182 };
00183
00189 real_type compute_duration()
00190 {
00191 if(m_keyframes.empty())
00192 return 0;
00193 return m_keyframes.back().m_time;
00194 };
00195
00196 };
00197
00198 }
00199 }
00200
00201
00202 #endif