00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_TRACK_KEYFRAMER_H
00027 #define NL_TRACK_KEYFRAMER_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "3d/track.h"
00031 #include "3d/key.h"
00032 #include <map>
00033 #include <memory>
00034 #include "nel/misc/matrix.h"
00035
00036
00037
00038 namespace NL3D
00039 {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00060 template<class CKeyT>
00061 class ITrackKeyFramer : public ITrack, public UTrackKeyframer
00062 {
00063 public:
00064
00065 typedef std::map <TAnimationTime, CKeyT> TMapTimeCKey;
00066
00067
00069 ITrackKeyFramer ()
00070 {
00071 _Dirty= false;
00072 _RangeLock= true;
00073 _LoopMode= false;
00074 }
00075
00076
00078 ~ITrackKeyFramer ()
00079 {
00080 }
00081
00090 void addKey (const CKeyT &key, TAnimationTime time)
00091 {
00092
00093 _MapKey.insert (TMapTimeCKey::value_type (time, key));
00094
00095
00096 _Dirty= true;
00097 }
00098
00100 void unlockRange(TAnimationTime begin, TAnimationTime end)
00101 {
00102 _RangeLock= false;
00103 _RangeBegin= begin;
00104 _RangeEnd= end;
00105 _Dirty= true;
00106 }
00107
00109 void lockRange()
00110 {
00111 _RangeLock= true;
00112 _Dirty= true;
00113 }
00114
00116 bool isRangeLocked() const {return _RangeLock;}
00117
00118
00120 TAnimationTime getRangeDelta() const
00121 {
00122
00123 testAndClean();
00124
00125 return _RangeDelta;
00126 }
00127
00128
00130 void setLoopMode(bool loop) {_LoopMode= loop; _Dirty= true;}
00131
00133 virtual bool getLoopMode() const {return _LoopMode;}
00134
00135
00137 virtual void eval (const TAnimationTime& inDate)
00138 {
00139 float date= inDate;
00140 const CKeyT *previous=NULL;
00141 const CKeyT *next=NULL;
00142 TAnimationTime datePrevious = 0;
00143 TAnimationTime dateNext = 0;
00144
00145
00146 testAndClean();
00147
00148
00149 if(_MapKey.empty())
00150 return;
00151
00152
00153
00154 if(_LoopMode && _MapKey.size()>1 )
00155 {
00156 nlassert(_LoopEnd > _LoopStart);
00157
00158
00159 if( date<_LoopStart || date>=_LoopEnd )
00160 {
00161 double d= (date-_LoopStart)*_OOTotalRange;
00162
00163
00164 d= date- floor(d)*_TotalRange;
00165 date= (float)d;
00166
00167
00168 if(date<_LoopStart || date >= _LoopEnd)
00169 date= _LoopStart;
00170 }
00171 }
00172
00173
00174
00175 TMapTimeCKey::iterator ite=_MapKey.upper_bound (date);
00176
00177
00178 if (ite!=_MapKey.end())
00179 {
00180
00181 next= &(ite->second);
00182 dateNext=ite->first;
00183 }
00184
00185 else if (_LoopMode && _MapKey.size()>1 )
00186 {
00187
00188 next= &(_MapKey.begin()->second);
00189
00190 dateNext= _LoopEnd;
00191 }
00192 else if (!_LoopMode && _MapKey.size()>=1 )
00193 {
00194
00195 TMapTimeCKey::iterator iteLast= ite;
00196 iteLast--;
00197 next= &(iteLast->second);
00198 }
00199
00200
00201
00202 if ((!_MapKey.empty())&&(ite!=_MapKey.begin()))
00203 {
00204 if (ite!=_MapKey.end())
00205 {
00206
00207 ite--;
00208 previous= &(ite->second);
00209 datePrevious=ite->first;
00210 }
00211 }
00212 else if (!_MapKey.empty())
00213 {
00214
00215 next= &(ite->second);
00216 dateNext=ite->first;
00217 }
00218
00219
00220 evalKey (previous, next, datePrevious, dateNext, date);
00221 }
00222
00223
00224 virtual TAnimationTime getBeginTime () const
00225 {
00226
00227 testAndClean();
00228
00229 return _RangeBegin;
00230 }
00231 virtual TAnimationTime getEndTime () const
00232 {
00233
00234 testAndClean();
00235
00236 return _RangeEnd;
00237 }
00238
00239
00241 virtual void serial (NLMISC::IStream& f) throw (NLMISC::EStream)
00242 {
00243
00244 (void)f.serialVersion (0);
00245
00246 f.serialCont(_MapKey);
00247 f.serial(_RangeLock, _RangeBegin, _RangeEnd);
00248 f.serial(_LoopMode);
00249
00250 if(f.isReading())
00251 _Dirty= true;
00252 }
00253
00257 void getKeysInRange(TAnimationTime t1, TAnimationTime t2, std::vector<TAnimationTime> &result);
00258
00259
00260 private:
00261 mutable bool _Dirty;
00262 bool _LoopMode;
00263 bool _RangeLock;
00264 float _RangeBegin;
00265 float _RangeEnd;
00266
00267 float _RangeDelta;
00268 float _LoopStart;
00269 float _LoopEnd;
00270 float _TotalRange;
00271 float _OOTotalRange;
00272
00273
00274
00275 void testAndClean() const
00276 {
00277 if(_Dirty)
00278 {
00279 ITrackKeyFramer<CKeyT> *self= const_cast<ITrackKeyFramer<CKeyT>*>(this);
00280 self->compile();
00281 _Dirty= false;
00282 }
00283 }
00284
00285
00286 protected:
00287 TMapTimeCKey _MapKey;
00288
00289
00291 float getCompiledRangeDelta()
00292 {
00293 return _RangeDelta;
00294 }
00295
00296
00302 virtual void compile ()
00303 {
00304 float timeFirstKey;
00305 float timeLastKey;
00306
00307
00308 if( !_MapKey.empty() )
00309 {
00310 TMapTimeCKey::const_iterator ite;
00311
00312
00313 ite=_MapKey.begin ();
00314 timeFirstKey= ite->first;
00315
00316
00317 ite=_MapKey.end ();
00318 ite--;
00319 timeLastKey= ite->first;
00320 }
00321 else
00322 {
00323 timeFirstKey= 0.0f;
00324 timeLastKey= 0.0f;
00325 }
00326
00327
00328
00329 if(_RangeLock)
00330 {
00331 _RangeBegin= timeFirstKey;
00332 _RangeEnd= timeLastKey;
00333 }
00334
00335
00336
00337 if(_RangeLock)
00338 {
00339 _RangeDelta= 0;
00340 }
00341 else
00342 {
00343 _RangeDelta= (_RangeEnd - _RangeBegin) - (timeLastKey - timeFirstKey);
00344 }
00345
00346
00347 _TotalRange= _RangeEnd - _RangeBegin;
00348 if(_TotalRange>0.0f)
00349 _OOTotalRange= 1.0f/_TotalRange;
00350
00351 _LoopStart= timeFirstKey;
00352 _LoopEnd= timeFirstKey + _TotalRange;
00353
00354
00355
00356 TMapTimeCKey::iterator it= _MapKey.begin();
00357 for(;it!=_MapKey.end();it++)
00358 {
00359 TMapTimeCKey::iterator next= it;
00360 next++;
00361 if(next!=_MapKey.end())
00362 it->second.OODeltaTime= 1.0f/(next->first - it->first);
00363 else if(_RangeDelta>0.0f)
00364
00365 it->second.OODeltaTime= 1.0f/_RangeDelta;
00366 else
00367 it->second.OODeltaTime= 0.0f;
00368 }
00369
00370 }
00371
00380 virtual void evalKey (const CKeyT* previous, const CKeyT* next,
00381 TAnimationTime datePrevious, TAnimationTime dateNext,
00382 TAnimationTime date ) =0;
00383
00384 };
00385
00386
00387
00388
00389
00390
00391
00392 template<class T, class TKeyVal> inline void copyToValue(T &value, const TKeyVal &keyval)
00393 {
00394 value = keyval;
00395 }
00396
00397
00398
00399 inline void copyToValue(NLMISC::CRGBA &col, const CVector &v)
00400 {
00401 sint i;
00402
00403 i= (sint)(v.x*255); NLMISC::clamp(i,0,255); col.R= (uint8) i;
00404 i= (sint)(v.y*255); NLMISC::clamp(i,0,255); col.G= (uint8) i;
00405 i= (sint)(v.z*255); NLMISC::clamp(i,0,255); col.B= (uint8) i;
00406 col.A=255;
00407 }
00408
00409
00410
00411 inline void copyToValue(sint32 &value, const float &f)
00412 {
00413 value= (sint32)floor(f+0.5f);
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00433 template<class CKeyT, class T>
00434 class CTrackKeyFramerConstNotBlendable : public ITrackKeyFramer<CKeyT>
00435 {
00436 public:
00437
00439 virtual const IAnimatedValue& getValue () const
00440 {
00441 return _Value;
00442 }
00443
00445 virtual void evalKey ( const CKeyT* previous, const CKeyT* next,
00446 TAnimationTime datePrevious, TAnimationTime dateNext,
00447 TAnimationTime date )
00448 {
00449
00450 if (previous)
00451 copyToValue(_Value.Value, previous->Value);
00452 else
00453 if (next)
00454 copyToValue(_Value.Value, next->Value);
00455 }
00456
00457 private:
00458 CAnimatedValueNotBlendable<T> _Value;
00459 };
00460
00461
00462
00470 template<class CKeyT, class T>
00471 class CTrackKeyFramerConstBlendable : public ITrackKeyFramer<CKeyT>
00472 {
00473 public:
00474
00476 virtual const IAnimatedValue& getValue () const
00477 {
00478 return _Value;
00479 }
00480
00482 virtual void evalKey ( const CKeyT* previous, const CKeyT* next,
00483 TAnimationTime datePrevious, TAnimationTime dateNext,
00484 TAnimationTime date )
00485 {
00486
00487 if (previous)
00488 copyToValue(_Value.Value, previous->Value);
00489 else
00490 if (next)
00491 copyToValue(_Value.Value, next->Value);
00492 }
00493
00494 private:
00495 CAnimatedValueBlendable<T> _Value;
00496 };
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00514 template<class CKeyT, class T>
00515 class CTrackKeyFramerLinear : public ITrackKeyFramer<CKeyT>
00516 {
00517 public:
00518
00520 virtual const IAnimatedValue& getValue () const
00521 {
00522 return _Value;
00523 }
00524
00526 virtual void evalKey ( const CKeyT* previous, const CKeyT* next,
00527 TAnimationTime datePrevious, TAnimationTime dateNext,
00528 TAnimationTime date )
00529 {
00530 if(previous && next)
00531 {
00532
00533 date-= datePrevious;
00534 date*= previous->OODeltaTime;
00535 NLMISC::clamp(date, 0,1);
00536
00537
00538 copyToValue(_Value.Value, previous->Value*(1.f-(float)date) + next->Value*(float)date);
00539 }
00540 else
00541 {
00542 if (previous)
00543 copyToValue(_Value.Value, previous->Value);
00544 else
00545 if (next)
00546 copyToValue(_Value.Value, next->Value);
00547 }
00548
00549 }
00550
00551 private:
00552 CAnimatedValueBlendable<T> _Value;
00553 };
00554
00555
00556
00557
00565 class CTrackKeyFramerLinear<CKeyQuat, CQuat> : public ITrackKeyFramer<CKeyQuat>
00566 {
00567 public:
00568
00570 virtual const IAnimatedValue& getValue () const
00571 {
00572 return _Value;
00573 }
00574
00576 virtual void evalKey ( const CKeyQuat* previous, const CKeyQuat* next,
00577 TAnimationTime datePrevious, TAnimationTime dateNext,
00578 TAnimationTime date )
00579 {
00580 if(previous && next)
00581 {
00582
00583 date-= datePrevious;
00584 date*= previous->OODeltaTime;
00585 NLMISC::clamp(date, 0,1);
00586 _Value.Value= CQuat::slerp(previous->Value, next->Value, date);
00587 }
00588 else
00589 {
00590 if (previous)
00591 _Value.Value=previous->Value;
00592 else
00593 if (next)
00594 _Value.Value=next->Value;
00595 }
00596 }
00597
00598 private:
00599 CAnimatedValueBlendable<CQuat> _Value;
00600 };
00601
00602
00603
00611 class CTrackKeyFramerLinear<CKeyRGBA, NLMISC::CRGBA>: public ITrackKeyFramer<CKeyRGBA>
00612 {
00613 public:
00614
00616 virtual const IAnimatedValue& getValue () const
00617 {
00618 return _Value;
00619 }
00620
00622 virtual void evalKey ( const CKeyRGBA* previous, const CKeyRGBA* next,
00623 TAnimationTime datePrevious, TAnimationTime dateNext,
00624 TAnimationTime date )
00625 {
00626 if(previous && next)
00627 {
00628
00629 date-= datePrevious;
00630 date*= previous->OODeltaTime;
00631 NLMISC::clamp(date, 0,1);
00632
00633
00634 _Value.Value.blendFromui(previous->Value, next->Value, (uint)(date*256));
00635 }
00636 else
00637 {
00638 if (previous)
00639 _Value.Value= previous->Value;
00640 else
00641 if (next)
00642 _Value.Value= next->Value;
00643 }
00644 }
00645
00646 private:
00647 CAnimatedValueBlendable<NLMISC::CRGBA> _Value;
00648 };
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 #include "track_tcb.h"
00661 #include "track_bezier.h"
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 class CTrackKeyFramerConstFloat : public CTrackKeyFramerConstBlendable<CKeyFloat,float>
00674 {
00675 public:
00676 NLMISC_DECLARE_CLASS (CTrackKeyFramerConstFloat);
00677 };
00678 class CTrackKeyFramerConstVector : public CTrackKeyFramerConstBlendable<CKeyVector, CVector>
00679 {
00680 public:
00681 NLMISC_DECLARE_CLASS (CTrackKeyFramerConstVector);
00682 };
00683 class CTrackKeyFramerConstQuat : public CTrackKeyFramerConstBlendable<CKeyQuat, CQuat>
00684 {
00685 public:
00686 NLMISC_DECLARE_CLASS (CTrackKeyFramerConstQuat);
00687 };
00688 class CTrackKeyFramerConstInt : public CTrackKeyFramerConstBlendable<CKeyInt, sint32>
00689 {
00690 public:
00691 NLMISC_DECLARE_CLASS (CTrackKeyFramerConstInt);
00692 };
00693 class CTrackKeyFramerConstRGBA : public CTrackKeyFramerConstBlendable<CKeyRGBA, NLMISC::CRGBA>
00694 {
00695 public:
00696 NLMISC_DECLARE_CLASS (CTrackKeyFramerConstRGBA);
00697 };
00698
00699 class CTrackKeyFramerConstString : public CTrackKeyFramerConstNotBlendable<CKeyString, std::string>
00700 {
00701 public:
00702 NLMISC_DECLARE_CLASS (CTrackKeyFramerConstString);
00703 };
00704 class CTrackKeyFramerConstBool : public CTrackKeyFramerConstNotBlendable<CKeyBool, bool>
00705 {
00706 public:
00707 NLMISC_DECLARE_CLASS (CTrackKeyFramerConstBool);
00708 };
00709
00710
00711
00712 class CTrackKeyFramerLinearFloat : public CTrackKeyFramerLinear<CKeyFloat, float>
00713 {
00714 public:
00715 NLMISC_DECLARE_CLASS (CTrackKeyFramerLinearFloat);
00716 };
00717 class CTrackKeyFramerLinearVector : public CTrackKeyFramerLinear<CKeyVector, CVector>
00718 {
00719 public:
00720 NLMISC_DECLARE_CLASS (CTrackKeyFramerLinearVector);
00721 };
00722 class CTrackKeyFramerLinearQuat : public CTrackKeyFramerLinear<CKeyQuat, CQuat>
00723 {
00724 public:
00725 NLMISC_DECLARE_CLASS (CTrackKeyFramerLinearQuat);
00726 };
00727 class CTrackKeyFramerLinearInt : public CTrackKeyFramerLinear<CKeyInt, sint32>
00728 {
00729 public:
00730 NLMISC_DECLARE_CLASS (CTrackKeyFramerLinearInt);
00731 };
00732 class CTrackKeyFramerLinearRGBA : public CTrackKeyFramerLinear<CKeyRGBA, NLMISC::CRGBA>
00733 {
00734 public:
00735 NLMISC_DECLARE_CLASS (CTrackKeyFramerLinearRGBA);
00736 };
00737
00738
00739
00740 class CTrackKeyFramerTCBFloat : public CTrackKeyFramerTCB<CKeyTCBFloat, float>
00741 {
00742 public:
00743 NLMISC_DECLARE_CLASS (CTrackKeyFramerTCBFloat);
00744 };
00745 class CTrackKeyFramerTCBVector : public CTrackKeyFramerTCB<CKeyTCBVector, CVector>
00746 {
00747 public:
00748 NLMISC_DECLARE_CLASS (CTrackKeyFramerTCBVector);
00749 };
00750 class CTrackKeyFramerTCBQuat : public CTrackKeyFramerTCB<CKeyTCBQuat, NLMISC::CAngleAxis>
00751 {
00752 public:
00753 NLMISC_DECLARE_CLASS (CTrackKeyFramerTCBQuat);
00754 };
00755 class CTrackKeyFramerTCBInt : public CTrackKeyFramerTCB<CKeyTCBFloat, sint32>
00756 {
00757 public:
00758 NLMISC_DECLARE_CLASS (CTrackKeyFramerTCBInt);
00759 };
00760 class CTrackKeyFramerTCBRGBA : public CTrackKeyFramerTCB<CKeyTCBVector, NLMISC::CRGBA>
00761 {
00762 public:
00763 NLMISC_DECLARE_CLASS (CTrackKeyFramerTCBRGBA);
00764 };
00765
00766
00767
00768 class CTrackKeyFramerBezierFloat : public CTrackKeyFramerBezier<CKeyBezierFloat, float>
00769 {
00770 public:
00771 NLMISC_DECLARE_CLASS (CTrackKeyFramerBezierFloat);
00772 };
00773 class CTrackKeyFramerBezierVector : public CTrackKeyFramerBezier<CKeyBezierVector, CVector>
00774 {
00775 public:
00776 NLMISC_DECLARE_CLASS (CTrackKeyFramerBezierVector);
00777 };
00778 class CTrackKeyFramerBezierQuat : public CTrackKeyFramerBezier<CKeyBezierQuat, CQuat>
00779 {
00780 public:
00781 NLMISC_DECLARE_CLASS (CTrackKeyFramerBezierQuat);
00782 };
00783 class CTrackKeyFramerBezierInt : public CTrackKeyFramerBezier<CKeyBezierFloat, sint32>
00784 {
00785 public:
00786 NLMISC_DECLARE_CLASS (CTrackKeyFramerBezierInt);
00787 };
00788 class CTrackKeyFramerBezierRGBA : public CTrackKeyFramerBezier<CKeyBezierVector, NLMISC::CRGBA>
00789 {
00790 public:
00791 NLMISC_DECLARE_CLASS (CTrackKeyFramerBezierRGBA);
00792 };
00793
00794
00795
00796
00797
00798 }
00799
00800
00801 #endif // NL_TRACK_KEYFRAMER_H
00802
00803