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