00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _TIME_MAP_H
00021 #define _TIME_MAP_H
00022
00023 #include <iostream>
00024 #include <stdint.h>
00025 #include <math.h>
00026
00044 template < typename Entry > class TimeEntry
00045 {
00046 private:
00047 double position;
00048 bool is_editable;
00049
00050 public:
00051 virtual ~TimeEntry() { }
00052
00053 double GetPosition( ) { return position; }
00054
00055 bool IsEditable( ) { return is_editable; }
00056
00057 void SetPosition( double m_position ) { position = m_position; }
00058
00059 void SetEditable( bool m_is_editable ) { is_editable = m_is_editable; }
00060
00061 virtual Entry *Get( double position, Entry *ante ) = 0;
00062 };
00063
00064
00065
00066 class TimeMapValue : public TimeEntry< TimeMapValue >
00067 {
00068 protected:
00069 double value;
00070
00071 public:
00072 virtual ~TimeMapValue() { }
00073 TimeMapValue( ) : value(0) { SetPosition( 0 ); SetEditable( false ); }
00074 TimeMapValue( double position ) : value(0) { SetPosition( position ); SetEditable( false ); }
00075 TimeMapValue( double position, TimeMapValue *entry ) { SetPosition( position ); SetEditable( false ); this->value = entry->value; }
00076 void SetValue( double value ) { this->value = value; }
00077 double GetValue( ) { return value; }
00078 TimeMapValue *Get( double position, TimeMapValue *ante )
00079 {
00080 TimeMapValue *entry = new TimeMapValue();
00081 double r = ( position - GetPosition( ) ) / ( ante->GetPosition() - GetPosition( ) );
00082 entry->SetValue( value + ( ante->GetValue() - value ) * r );
00083 return entry;
00084 }
00085 };
00086
00087 class TimeMapPair : public TimeEntry< TimeMapPair >
00088 {
00089 protected:
00090 double first;
00091 double second;
00092
00093 public:
00094 virtual ~TimeMapPair() { }
00095 TimeMapPair( ) : first(0), second(0) { SetPosition( 0 ); SetEditable( false ); }
00096 TimeMapPair( double position ) : first(0), second(0) { SetPosition( position ); SetEditable( false ); }
00097 TimeMapPair( double position, TimeMapPair *entry )
00098 {
00099 SetPosition( position );
00100 SetEditable( false );
00101 this->first = entry->first;
00102 this->second = entry->second;
00103 }
00104 void SetFirst( double first ) { this->first = first; }
00105 void SetSecond( double second ) { this->second = second; }
00106 double GetFirst( ) { return first; }
00107 double GetSecond( ) { return second; }
00108 TimeMapPair *Get( double position, TimeMapPair *ante )
00109 {
00110 TimeMapPair *entry = new TimeMapPair();
00111 double r = ( position - GetPosition( ) ) / ( ante->GetPosition() - GetPosition( ) );
00112 entry->SetFirst( first + ( ante->GetFirst() - first ) * r );
00113 entry->SetSecond( second + ( ante->GetSecond() - second ) * r );
00114 return entry;
00115 }
00116 };
00117
00118 class TimeMapTriple : public TimeEntry< TimeMapTriple >
00119 {
00120 protected:
00121 double first;
00122 double second;
00123 double third;
00124
00125 public:
00126 virtual ~TimeMapTriple() { }
00127 TimeMapTriple( ) : first(0), second(0), third(0) { SetPosition( 0 ); SetEditable( false ); }
00128 TimeMapTriple( double position ) : first(0), second(0), third(0) { SetPosition( position ); SetEditable( false ); }
00129 TimeMapTriple( double position, TimeMapTriple *entry )
00130 {
00131 SetPosition( position );
00132 SetEditable( false );
00133 this->first = entry->first;
00134 this->second = entry->second;
00135 this->third = entry->third;
00136 }
00137 void SetFirst( double first ) { this->first = first; }
00138 void SetSecond( double second ) { this->second = second; }
00139 void SetThird( double third ) { this->third = third; }
00140 double GetFirst( ) { return first; }
00141 double GetSecond( ) { return second; }
00142 double GetThird( ) { return third; }
00143 TimeMapTriple *Get( double position, TimeMapTriple *ante )
00144 {
00145 TimeMapTriple *entry = new TimeMapTriple();
00146 double r = ( position - GetPosition( ) ) / ( ante->GetPosition() - GetPosition( ) );
00147 entry->SetFirst( first + ( ante->GetFirst() - first ) * r );
00148 entry->SetSecond( second + ( ante->GetSecond() - second ) * r );
00149 entry->SetThird( third + ( ante->GetThird() - third ) * r );
00150 return entry;
00151 }
00152 };
00153
00154
00159 template < typename Entry > class FilterTimeEntry : public TimeEntry< Entry >
00160 {
00161 public:
00162 virtual ~FilterTimeEntry() { }
00163
00164 virtual void RenderFinal( uint8_t *image, int width, int height ) = 0;
00165 };
00166
00171 template < typename Entry > class TransitionTimeEntry : public TimeEntry< Entry >
00172 {
00173 public:
00174 virtual ~TransitionTimeEntry() { }
00175
00176 virtual void RenderFinal( uint8_t *out, uint8_t *in, int width, int height ) = 0;
00177 };
00178
00183 template < typename Entry > class TimeMap
00184 {
00185 private:
00186 map < double, Entry * > key_frames;
00187
00188 public:
00189 virtual ~TimeMap() { }
00190
00191 void Clear( )
00192 {
00193 key_frames.erase( key_frames.begin( ), key_frames.end( ) );
00194 }
00195
00196 void FinishedWith( Entry *entry )
00197 {
00198 if ( !entry->IsEditable( ) )
00199 delete entry;
00200 }
00201
00202 bool RoughlyEquals( double x, double y )
00203 {
00204 return x == y;
00205 }
00206
00207 Entry *Get( double position )
00208 {
00209 Entry *current = NULL;
00210 position = (double)( rint( position * 1000000 ) / 1000000 );
00211
00212 if ( key_frames.size() == 0 )
00213 {
00214 current = new Entry();
00215 current->SetPosition( position );
00216 current->SetEditable( false );
00217 }
00218 else if ( key_frames.size() == 1 )
00219 {
00220 double first_key = GetFirst( );
00221 Entry *ante = key_frames[ first_key ];
00222
00223 if ( position != first_key )
00224 current = new Entry( position, *ante );
00225 else
00226 current = ante;
00227 }
00228 else
00229 {
00230 double post_key = GetNext( position );
00231 double ante_key = GetPrevious( position );
00232 bool frame_key = IsKeyFrame( position );
00233
00234 if ( frame_key )
00235 {
00236 current = key_frames[ position ];
00237 }
00238 else
00239 {
00240 Entry *ante = key_frames[ ante_key ];
00241
00242
00243 if ( post_key == ante_key )
00244 {
00245 current = new Entry( position, *ante );
00246 }
00247 else
00248 {
00249 Entry *post = key_frames[ post_key ];
00250 current = ante->Get( position, post );
00251 }
00252 }
00253 }
00254
00255 return current;
00256 }
00257
00258 Entry *SetEditable( double position, bool editable )
00259 {
00260 Entry *entry = Get( position );
00261 position = (double)( rint( position * 1000000 ) / 1000000 );
00262
00263 if ( entry->IsEditable() != editable )
00264 {
00265 if ( entry->IsEditable() )
00266 key_frames.erase( position );
00267 else
00268 key_frames[ position ] = entry;
00269 entry->SetEditable( editable );
00270 }
00271
00272 FinishedWith( entry );
00273
00274 return Get( position );
00275 }
00276
00277 Entry *GotoNextKey( double position )
00278 {
00279 return Get( GetNext( position + 0.000001 ) );
00280 }
00281
00282 Entry *GotoPreviousKey( double position )
00283 {
00284 return Get( GetPrevious( position - 0.000001 ) );
00285 }
00286
00287 double GetFirst( )
00288 {
00289 typename map< double, Entry * >::iterator it = key_frames.begin();
00290 if ( it == key_frames.end() )
00291 return 0;
00292 else
00293 return it->first;
00294 }
00295
00296 double GetLast( )
00297 {
00298 typename map< double, Entry * >::iterator it = key_frames.end();
00299 if ( key_frames.size() == 0 )
00300 return 0;
00301 else
00302 return ( -- it )->first;
00303 }
00304
00305 double GetNext( double position )
00306 {
00307 double ret_val = 0;
00308 if ( key_frames.size() >= 1 )
00309 {
00310 typename map< double, Entry * >::iterator it = key_frames.begin();
00311 for ( ; ret_val <= position && it != key_frames.end(); it ++ )
00312 ret_val = it->first;
00313
00314
00315
00316
00317
00318 }
00319 return ret_val;
00320 }
00321
00322 double GetPrevious( double position )
00323 {
00324 double ret_val = 0;
00325 if ( key_frames.size() >= 1 )
00326 {
00327 typename map< double, Entry * >::iterator it = key_frames.begin();
00328 for ( ; it != key_frames.end() && it->first < position; it ++ )
00329 ret_val = it->first;
00330
00331
00332
00333
00334
00335 }
00336 return ret_val;
00337 }
00338
00339 bool IsKeyFrame( double position )
00340 {
00341 if ( key_frames.size() >= 1 )
00342 {
00343 typename map< double, Entry * >::iterator it = key_frames.begin();
00344 for ( ; it != key_frames.end() && it->first <= position; it ++ )
00345 {
00346 if ( position == it->first )
00347 return true;
00348 }
00349 }
00350 return false;
00351 }
00352
00353 void Invert( )
00354 {
00355 map < double, Entry * > temp_frames;
00356 if ( key_frames.size() >= 1 )
00357 {
00358 typename map< double, Entry * >::iterator it = key_frames.begin();
00359 for ( ; it != key_frames.end(); it ++ )
00360 {
00361 it->second->SetPosition( 0.999999 - it->first );
00362 temp_frames[ 0.999999 - it->first ] = it->second;
00363 }
00364 }
00365
00366 key_frames = temp_frames;
00367 }
00368 };
00369
00370 #endif