1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif // HAVE_CONFIG_H
36 
37 #ifdef HAVE_VRML97
38 
39 /*!
40   \class SoVRMLInterpolator SoVRMLInterpolator.h Inventor/VRMLnodes/SoVRMLInterpolator.h
41   \brief The SoVRMLInterpolator class is an internal abstract class.
42 
43   This class collects the two fields that are common for all
44   interpolator nodes, plus common code that operates on these
45   fields. Since this is an abstract "helper" class, it does not
46   represent an actual node from the VRML97 specification, so don't use
47   it as such.
48 
49   For more information, a detailed discussion of interpolators is
50   available in section 4.6.8 of the VRML97 specification:
51 
52   <http://www.web3d.org/documents/specifications/14772/V2.0/part1/concepts.html#4.6.8>
53 */
54 
55 /*!
56   \var SoMFFloat SoVRMLInterpolator::key
57 
58   This field contains a set of floating point values which the
59   interpolation will run over. The key values should be monotonically
60   non-decreasing.
61 
62   The field is inherited from it's declaration in the abstract
63   SoVRMLInterpolator class into a range of different VRML interpolator
64   nodes.
65 
66   See the class documentation of the \e non-abstract VRML interpolator
67   node you want to use for information on what the key values
68   represent in that specific context.
69 */
70 /*!
71   \var SoSFFloat SoVRMLInterpolator::set_fraction
72 
73   The set_fraction field gets an input signal that triggers a
74   calculation of the next value_changed eventOut value.
75 
76   The field is inherited from it's declaration in the abstract
77   SoVRMLInterpolator class into a range of different VRML interpolator
78   nodes.
79 */
80 
81 #include <Inventor/VRMLnodes/SoVRMLInterpolator.h>
82 
83 #include <Inventor/VRMLnodes/SoVRMLMacros.h>
84 
85 #include "engines/SoSubNodeEngineP.h"
86 
87 SO_NODEENGINE_ABSTRACT_SOURCE(SoVRMLInterpolator);
88 
89 void
initClass(void)90 SoVRMLInterpolator::initClass(void) // static
91 {
92   SO_NODEENGINE_INTERNAL_INIT_ABSTRACT_CLASS(SoVRMLInterpolator);
93 }
94 
SoVRMLInterpolator(void)95 SoVRMLInterpolator::SoVRMLInterpolator(void) // protected
96 {
97   SO_NODEENGINE_CONSTRUCTOR(SoVRMLInterpolator);
98 
99   SO_VRMLNODE_ADD_EVENT_IN(set_fraction);
100 
101   // initialize set_fraction to some value, since if set_fraction is
102   // never set, we'll attempt to read an unitialized value when the
103   // interpolator is destructed (all engines evaluates when
104   // destructed)
105   this->set_fraction.enableNotify(FALSE);
106   this->set_fraction = 0.0f;
107   this->set_fraction.enableNotify(TRUE);
108 
109   SO_VRMLNODE_ADD_EMPTY_EXPOSED_MFIELD(key);
110 }
111 
~SoVRMLInterpolator()112 SoVRMLInterpolator::~SoVRMLInterpolator() // virtual, protected
113 {
114 }
115 
116 /*!
117   \COININTERNAL
118 */
119 int
getKeyValueIndex(float & interp,int numvalues)120 SoVRMLInterpolator::getKeyValueIndex(float & interp, int numvalues)
121 {
122   float fraction = this->set_fraction.getValue();
123   const int n = this->key.getNum();
124   if (n == 0 || numvalues == 0) return -1;
125 
126   const float * t = this->key.getValues(0);
127   for (int i = 0; i < SbMin(n, numvalues); i++) {
128     if (fraction < t[i]) {
129       if (i == 0) {
130         interp = 0.0f;
131         return 0;
132       }
133       else {
134         float delta = t[i] - t[i-1];
135         if (delta > 0.0f) {
136           interp = (fraction - t[i-1]) / delta;
137         }
138         else interp = 0.0f;
139       }
140       return i-1;
141     }
142   }
143   interp = 0.0f;
144   return SbMin(numvalues,n)-1;
145 }
146 
147 #endif // HAVE_VRML97
148