00001
00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024
00025
00026
00027 #ifndef NL_TRACK_KEYFRAMER_H
00028 #error "internal file included from track_keyframer.h"
00029 #endif
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 00048 template<class CKeyT, class T>
00049 class CTrackKeyFramerBezier : public ITrackKeyFramer<CKeyT>
00050 {
00051 public:
00052
00054 virtual const IAnimatedValue& getValue () const
00055 {
00056 return _Value;
00057 }
00058
00059 protected:
00060
00061 typedef typename CKeyT::TValueType TKeyValueType;
00062
00063
00065
00066
00068 virtual void evalKey ( const CKeyT* previous, const CKeyT* next,
00069 CAnimationTime datePrevious, CAnimationTime dateNext,
00070 CAnimationTime date )
00071 {
00072 if(previous && next && !previous->Step)
00073 {
00074
00075 date-= datePrevious;
00076 date*= previous->OODeltaTime;
00077 NLMISC::clamp(date, 0,1);
00078
00079
00080 float s= date;
00081 float s2 = s * s;
00082 float s3 = s2 * s;
00083 float u = 1.0f - s;
00084 float u2 = u * u;
00085 float u3 = u2 * u;
00086
00087
00088 TKeyValueType cp0, cp1;
00089
00090
00091 cp0 = previous->Value + previous->OutTan * (dateNext-datePrevious) / 3.0f;
00092 cp1 = next->Value + next->InTan * (dateNext-datePrevious) / 3.0f;
00093
00094 copyToValue(_Value.Value, previous->Value*u3 + cp0*3.0f*u2*s
00095 + cp1*3.0f*u*s2 + next->Value*s3);
00096 }
00097 else
00098 {
00099 if (previous)
00100 copyToValue(_Value.Value, previous->Value);
00101 else
00102 if (next)
00103 copyToValue(_Value.Value, next->Value);
00104 }
00105 }
00106
00108 virtual void compile()
00109 {
00110 ITrackKeyFramer<CKeyT>::compile();
00111
00112
00113 }
00114
00115
00116
00117 private:
00118 CAnimatedValueBlendable<T> _Value;
00119 };
00120
00121
00122
00123 00131 class CTrackKeyFramerBezier<CKeyBezierQuat, CQuat> : public ITrackKeyFramer<CKeyBezierQuat>
00132 {
00133 public:
00134
00136 virtual const IAnimatedValue& getValue () const
00137 {
00138 return _Value;
00139 }
00140
00141 protected:
00142
00144
00145
00147 virtual void evalKey ( const CKeyBezierQuat* previous, const CKeyBezierQuat* next,
00148 CAnimationTime datePrevious, CAnimationTime dateNext,
00149 CAnimationTime date )
00150 {
00151 if(previous && next)
00152 {
00153
00154 date-= datePrevious;
00155 date*= previous->OODeltaTime;
00156 NLMISC::clamp(date, 0,1);
00157
00158
00159 _Value.Value = CQuat::squad(previous->Value, previous->A, next->A, next->Value, date);
00160 }
00161 else
00162 {
00163 if (previous)
00164 copyToValue(_Value.Value, previous->Value);
00165 else
00166 if (next)
00167 copyToValue(_Value.Value, next->Value);
00168 }
00169 }
00170
00172 virtual void compile()
00173 {
00174 ITrackKeyFramer<CKeyBezierQuat>::compile();
00175
00176
00177 sint nKeys= _MapKey.size();
00178 if(nKeys<=1)
00179 return;
00180
00181 TMapTimeCKey::iterator it;
00182 TMapTimeCKey::iterator itNext;
00183 TMapTimeCKey::iterator itPrev;
00184
00185 it= _MapKey.begin();
00186 itNext= it; itNext++;
00187 itPrev= _MapKey.end();
00188
00189
00190 for(;it!=_MapKey.end();)
00191 {
00192
00193 CKeyBezierQuat &key= it->second;
00194 CQuat &cur= key.Value;
00195
00196 if(itPrev!= _MapKey.end())
00197 {
00198 cur.makeClosest(itPrev->second.Value);
00199 }
00200
00201 CQuat prev, next;
00202
00203
00204 if(itPrev!= _MapKey.end())
00205 prev= itPrev->second.Value;
00206 else
00207 prev= itNext->second.Value;
00208 if(itNext!= _MapKey.end())
00209 next= itNext->second.Value;
00210 else
00211 next= itPrev->second.Value;
00212
00213
00214 CQuat qm,qp,r;
00215
00216 qm = CQuat::lnDif(cur, prev);
00217 qp = CQuat::lnDif(cur, next);
00218 r = -.25f*(qm+qp);
00219 key.A= cur*(r.exp());
00220
00221
00222 itPrev= it;
00223 it++;
00224
00225 if(itNext!= _MapKey.end())
00226 itNext++;
00227 }
00228
00229 }
00230
00231
00232
00233 private:
00234 CAnimatedValueBlendable<CQuat> _Value;
00235 };