H3D API  2.4.1
X3DSequencerNode.h
Go to the documentation of this file.
1 // Copyright 2004-2019, SenseGraphics AB
3 //
4 // This file is part of H3D API.
5 //
6 // H3D API is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // H3D API is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with H3D API; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 //
20 // A commercial license is also available. Please contact us at
21 // www.sensegraphics.com for more information.
22 //
23 //
27 //
29 #ifndef __X3DSEQUENCERNODE_H__
30 #define __X3DSEQUENCERNODE_H__
31 
32 #include <H3D/X3DChildNode.h>
33 #include <H3D/SFBool.h>
34 #include <H3D/SFFloat.h>
35 #include <H3D/MFFloat.h>
36 
37 namespace H3D {
38 
64 
65  class H3DAPI_API X3DSequencerNode : public X3DChildNode {
66  public:
67 
70  template< class MType > class H3DAPI_API KeyValues : public MType {};
71 
78  template< class TheType, class KeyValuesIn, class SequencerClass >
79  class H3DAPI_API ValueChanged
80  : public AutoUpdate< TypedField< TheType,
81  Types< SFBool,
82  SFBool,
83  SFFloat > > > {
84  public:
85  ValueChanged() { currentPosition = 0; fractionInitialized = false; }
86  bool fractionInitialized;
87  // The X3D specification never tells from where the next and previous
88  // should start. Therefore I choose to start at the beginning
89  // by default.
90  H3DInt32 currentPosition;
91  protected:
92  // evaluate the value using set_fraction
93  inline typename TheType::value_type evaluateValueChanged(
94  const typename KeyValuesIn::vector_type &key_value,
95  const vector< H3DFloat > &keys,
96  const H3DFloat &setFraction) {
97 
98  if( setFraction <= keys.front() )
99  return key_value.front();
100  else if( setFraction >= keys.back() )
101  return key_value.back();
102  else {
103  int i;
104  for( i = 0;
105  i < ( H3DInt32 )key_value.size() - 1 &&
106  !( setFraction >= keys[i] && setFraction < keys[ i + 1 ] );
107  ++i );
108  return key_value[i];
109  }
110  }
111  virtual void update() {
112  if( TheType::routes_in[0] == TheType::event.ptr ||
113  TheType::routes_in[1] == TheType::event.ptr ||
114  TheType::routes_in[2] == TheType::event.ptr ) {
115 
116  SequencerClass * sn =
117  static_cast< SequencerClass * >( TheType::getOwner() );
118 
119  bool notMonotonically = false;
120 
121  const typename KeyValuesIn::vector_type &key_value =
122  sn->keyValue->getValue();
123 
124  const vector< H3DFloat > &keys = sn->key->getValue();
125 
126  if( keys.empty() ) {
127  Console(LogLevel::Warning) << "Warning: The key array is empty in " <<
128  "X3DSequencerNode ( " << sn->getName() <<
129  " ). Node will not be used. " << endl;
130  return;
131  }
132 
133  if( key_value.empty() ) {
134  Console(LogLevel::Warning) << "Warning: The keyValue array is empty in " <<
135  "X3DSequencerNode ( " << sn->getName() <<
136  " ). Node will not be used. " << endl;
137  return;
138  }
139 
140  if( keys.size() != key_value.size() ) {
141  Console(LogLevel::Warning) << "Warning: The key and keyValue arrays mismatch in " <<
142  "X3DSequencerNode ( " << sn->getName() <<
143  " ). Node will not be used. " << endl;
144  return;
145  }
146 
147  // The keys shall be monotonically non-decreasing,
148  // otherwise the results are undefined.
149  for( int i = 0; i < (int)keys.size() - 1; ++i ) {
150  if( keys[i] > keys[ i + 1 ] )
151  notMonotonically = true;
152  }
153 
154  if( notMonotonically ) {
155  Console(LogLevel::Warning) << "Warning: The key array is not monotonically " <<
156  "non-decreasing in X3DSequencerNode ( " << sn->getName() <<
157  " ). Node will not be used. " << endl;
158  return;
159  }
160 
161  // next value
162  if( TheType::routes_in[0] == TheType::event.ptr ) {
163  ++currentPosition;
164  if( currentPosition > ( H3DInt32 )key_value.size() - 1 )
165  currentPosition = 0;
166 
167  TheType::value = key_value[ currentPosition ];
168  }
169  // previous value
170  else if( TheType::routes_in[1] == TheType::event.ptr ) {
171  --currentPosition;
172  if( currentPosition < 0 )
173  currentPosition = (H3DInt32) key_value.size() - 1;
174 
175  TheType::value = key_value[ currentPosition ];
176  }
177  // if set_fraction is used or anything else changes.
178  else if( TheType::routes_in[2] == TheType::event.ptr ) {
179  fractionInitialized = true;
180  const H3DFloat &setFraction =
181  static_cast< SFFloat * >( TheType::routes_in[2] )->getValue( sn -> id );
182  TheType::value = evaluateValueChanged(key_value, keys, setFraction);
183  }
184  }
185  }
186  };
187 #ifdef __BORLANDC__
188  template< class TheType, class KeyValuesIn > friend class ValueChanged;
189 #endif
190 
192  X3DSequencerNode( Inst< SFNode > _metadata = 0,
193  Inst< SFBool > _next = 0,
194  Inst< SFBool > _previous = 0,
195  Inst< SFFloat > _set_fraction = 0,
196  Inst< MFFloat > _key = 0 );
197 
203  H3DUniquePtr< SFBool > next;
204 
210  H3DUniquePtr< SFBool > previous;
211 
218  H3DUniquePtr< SFFloat > set_fraction;
219 
227  H3DUniquePtr< MFFloat > key;
228 
231  };
232 }
233 
234 #endif
Contains the MFFloat field class.
Contains the SFBool field class.
Contains the SFFloat field class.
Header file for X3DChildNode, X3D scene-graph node.
The SFFloat field contains one single-precision floating point number.
Definition: SFFloat.h:41
This abstract node type indicates that the concrete nodes which are instantiated based on it may be u...
Definition: X3DChildNode.h:42
Each value in the keyValue field corresponds in order to the parameter value in the key field.
Definition: X3DSequencerNode.h:70
ValueChanged is a specialized class used to evaluate and set the value_changed field depending on the...
Definition: X3DSequencerNode.h:83
This abstract node type is the base node type from which all Sequencers are derived.
Definition: X3DSequencerNode.h:65
H3DUniquePtr< MFFloat > key
Each value in the keyValue field corresponds in order to the parameter value in the key field.
Definition: X3DSequencerNode.h:227
H3DUniquePtr< SFFloat > set_fraction
The set_fraction inputOnly field receives an SFFloat event and causes the sequencing function to eval...
Definition: X3DSequencerNode.h:218
H3DUniquePtr< SFBool > previous
Receipt of previous event triggers previous output value in keyValue array, previous goes to last ele...
Definition: X3DSequencerNode.h:210
H3DUniquePtr< SFBool > next
Receipt of next event triggers next output value in keyValue array, next goes to initial element afte...
Definition: X3DSequencerNode.h:203
static H3DNodeDatabase database
The H3DNodeDatabase for this node.
Definition: X3DSequencerNode.h:230
int H3DInt32
float H3DFloat
Type getValue(const char *s, const char *&rest)
Function that reads characters from a char * and converts them to a given type.
Definition: X3DFieldConversion.h:134
H3D API namespace.
Definition: Anchor.h:38
The AutoUpdate field is a template to force the BaseField to update itself as soon as an event is rec...
Definition: FieldTemplates.h:130
The H3DNodeDatabase contains a mapping between a name of a Node and the constructor for the Node with...
Definition: H3DNodeDatabase.h:194