00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00094
00095
00096 H3DInt32 currentPosition;
00097 protected:
00098
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
00151
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
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
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
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