Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

time_map.h

Go to the documentation of this file.
00001 /*
00002  * time_map.h -- Time Mapping Interfaces and Templates
00003  * Copyright (C) 2002 Charles Yates <charles.yates@pandora.be>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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         // Get the position of this entry
00053         double GetPosition( ) { return position; }
00054         // Is it a key field?
00055         bool IsEditable( ) { return is_editable; }
00056         // Set the position of this entry
00057         void SetPosition( double m_position ) { position = m_position; }
00058         // Set its key status
00059         void SetEditable( bool m_is_editable ) { is_editable = m_is_editable; }
00060         // This method is used to generate the virtual/computed entries
00061         virtual Entry *Get( double position, Entry *ante ) = 0;
00062 };
00063 
00064 // Seems silly to extend the single, pair and triple entities - so 3 specific classes are provided
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         // Called when the final image is being rendered
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         // Called when the final image is being rendered
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                     // We may now be at the end of the map
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 /*              if ( it != key_frames.end() )
00314                 {
00315                     ++it;
00316                     ret_val = it->first;
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 /*              if ( it != key_frames.begin() )
00331                 {
00332                     --it;
00333                     ret_val = it->first;
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

Generated on Sun Mar 11 22:11:47 2007 for Kino by  doxygen 1.4.2