# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

track_bezier.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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 // Bezier Keyframer.
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                         // lerp from previous to cur.
00075                         date-= datePrevious;
00076                         date*= previous->OODeltaTime;
00077                         NLMISC::clamp(date, 0,1);
00078 
00079                         // Bezier interpolation.
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                         // compute Bezier control points from tangents.
00088                         TKeyValueType   cp0, cp1;
00089 
00090                         // NB: loop case: dateNext is always > datePrevious....
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                 // Nothing else to do!! Tangents are given from user.
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                         // lerp from previous to cur.
00154                         date-= datePrevious;
00155                         date*= previous->OODeltaTime;
00156                         NLMISC::clamp(date, 0,1);
00157 
00158                         // quad slerp.
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                 // makeclosest quaternions, Tangents Precompute.
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();                            // first key.
00186                 itNext= it;     itNext++;                               // second key.
00187                 itPrev= _MapKey.end();                          // end key.
00188 
00189                 // Compute all keys.
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                         // compute prev / next.
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                         // Compute A.
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                         // Next key!!
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 };