X3DSequencerNode.h

Go to the documentation of this file.
00001 
00002 //    Copyright 2004, SenseGraphics AB
00003 //
00004 //    This file is part of H3D API.
00005 //
00006 //    H3D API is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    H3D API is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with H3D API; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 //
00020 //    A commercial license is also available. Please contact us at 
00021 //    www.sensegraphics.com for more information.
00022 //
00023 //
00027 //
00029 #ifndef __X3DSEQUENCERNODE_H__
00030 #define __X3DSEQUENCERNODE_H__
00031 
00032 #include "X3DChildNode.h"
00033 #include "SFBool.h"
00034 #include "SFFloat.h"
00035 #include "MFFloat.h"
00036 
00037 namespace H3D {
00038 
00067 
00068         class H3DAPI_API X3DSequencerNode : public X3DChildNode {
00069   public:
00070                 
00073                 template< class MType > class H3DAPI_API KeyValues : public MType {};
00074 
00083                 template< class TheType, class KeyValuesIn > class H3DAPI_API ValueChanged
00084                         : public AutoUpdate< TypedField< TheType, 
00085                                                                                                                                                          Types< SFBool, 
00086                                                                                                                                                                                   SFBool, 
00087                                                                                                                                                                                         SFFloat, 
00088                                                                                                                                                                                         MFFloat, 
00089                                                                                                                                                                                         KeyValuesIn > > >{
00090                 public:
00091                         ValueChanged() { currentPosition = 0; fractionInitialized = false; }
00092                         bool fractionInitialized;
00093                         // The X3D specification never tells from where the next and previous
00094                         // should start. Therefore I choose to start at the beginning
00095                         // by default.
00096                         H3DInt32 currentPosition;
00097                 protected:
00098                         // evaluate the value using set_fraction
00099                         inline  typename TheType::value_type evaluateValueChanged(
00100                                 const typename KeyValuesIn::vector_type &key_value, 
00101                                 const vector< H3DFloat > &keys, 
00102                                 const H3DFloat &setFraction) {
00103                                 
00104                                 if( setFraction <= keys.front() )
00105                                         return key_value.front();
00106                                 else if( setFraction >= keys.back() )
00107                                         return key_value.back();
00108                                 else {
00109                                         int i;
00110                                         for( i = 0; 
00111                                                 i < ( H3DInt32 )key_value.size() - 1 &&
00112                                                 !( setFraction >= keys[i] && setFraction < keys[ i + 1 ] );
00113                                         i++ );
00114                                         return key_value[i];
00115                                 }
00116                         }
00117                         virtual void update() {
00118                                 X3DSequencerNode * sN = 
00119           static_cast< X3DSequencerNode * >( TheType::getOwner() );
00120 
00121                                 bool notMonotonically = false;
00122 
00123                                 const typename KeyValuesIn::vector_type &key_value = 
00124                                         static_cast<  KeyValuesIn * >( TheType::routes_in[4] )->getValue();
00125 
00126                                 const vector< H3DFloat > &keys = 
00127                                         static_cast< MFFloat * >( TheType::routes_in[3] )->getValue();
00128 
00129                                 if( keys.empty() ) {
00130                                         Console(3) << "Warning: The key array is empty in " <<
00131                                                 "X3DSequencerNode ( " << TheType::getName() << 
00132                                                 "). Node will not be used. " << endl;
00133                                         return;
00134                                 }
00135 
00136                                 if( key_value.empty() ) {
00137                                         Console(3) << "Warning: The keyValue array is empty in " <<
00138                                                 "X3DSequencerNode ( " << TheType::getName() << 
00139                                                 "). Node will not be used. " << endl;
00140                                         return;
00141                                 }
00142 
00143                                 if( keys.size() != key_value.size() ) {
00144                                         Console(3) << "Warning: The key and keyValue arrays mismatch in " <<
00145                                                 "X3DSequencerNode ( " << TheType::getName() << 
00146                                                 "). Node will not be used. " << endl;
00147                                         return;
00148                                 }
00149 
00150                                 // The keys shall be monotonically non-decreasing,
00151                                 // otherwise the results are undefined.
00152                                 for( int i = 0; i < (int)keys.size() - 1; i++ ) {
00153                                         if( keys[i] > keys[ i + 1 ] )
00154                                                 notMonotonically = true;
00155                                 }
00156 
00157                                 if( notMonotonically ) {
00158                                         Console(3) << "Warning: The key array is not monotonically " <<
00159                                                 "non-decreasing in X3DSequencerNode ( " << TheType::getName() << 
00160                                                 "). Node will not be used. " << endl;
00161                                         return;
00162                                 }
00163 
00164                                 // next value
00165                                 if( TheType::routes_in[0] == TheType::event.ptr ) {
00166                                         currentPosition++;
00167                                         if( currentPosition > ( H3DInt32 )key_value.size() - 1 )
00168                                                 currentPosition = 0;
00169 
00170                                         TheType::value = key_value[ currentPosition ];
00171                                 }
00172                                 // previous value
00173                                 else if( TheType::routes_in[1] == TheType::event.ptr ) {
00174                                         currentPosition--;
00175                                         if( currentPosition < 0 )
00176                                                 currentPosition = key_value.size() - 1;
00177 
00178                                         TheType::value = key_value[ currentPosition ];
00179                                 }
00180                                 // if set_fraction is used or anything else changes.
00181                                 else if( TheType::routes_in[2] == TheType::event.ptr ) {
00182                                         fractionInitialized = true;
00183                                         const H3DFloat &setFraction = 
00184                                                 static_cast< SFFloat * >( TheType::routes_in[2] )->getValue( sN -> id );
00185                                         TheType::value = evaluateValueChanged(key_value, keys, setFraction);
00186                                 }
00187                                 else if( TheType::routes_in[3] == TheType::event.ptr ) {
00188                                         if( fractionInitialized ) {
00189                                                 const H3DFloat &setFraction = 
00190                                                 static_cast< SFFloat * >( TheType::routes_in[2] )->getValue( sN -> id );
00191                                                 TheType::value = evaluateValueChanged(key_value, keys, setFraction);
00192                                         }
00193                                 }
00194                                 else if ( TheType::routes_in[4] == TheType::event.ptr ) {
00195                                         if( fractionInitialized ) {
00196                                                 const H3DFloat &setFraction = 
00197                                                 static_cast< SFFloat * >( TheType::routes_in[2] )->getValue( sN -> id );
00198                                                 TheType::value = evaluateValueChanged(key_value, keys, setFraction);
00199                                         }
00200 
00201                                         if( currentPosition > ( H3DInt32 )key_value.size() - 1 ) {
00202                                                 currentPosition = key_value.size() - 1;
00203                                                 TheType::value = key_value[ currentPosition ];
00204                                         }
00205                                 }
00206                         }
00207                 };
00208 
00210     X3DSequencerNode(   Inst< SFNode           > _metadata                      = 0,
00211                                                                                         Inst< SFBool             > _next                        = 0,
00212                                                                                         Inst< SFBool           > _previous                      = 0,
00213                                                                                         Inst< SFFloat          > _set_fraction  = 0,
00214                                                                                         Inst< MFFloat          > _key                           = 0 );
00215                                                          
00216 
00224     auto_ptr< SFBool >  next;
00225 
00233     auto_ptr< SFBool >  previous;
00234 
00243     auto_ptr< SFFloat >  set_fraction;
00244 
00254     auto_ptr< MFFloat >  key;
00255 
00257     static H3DNodeDatabase database;
00258         };
00259 }
00260 
00261 #endif

Generated on Thu Aug 24 12:38:35 2006 for H3D API by  doxygen 1.4.5