Field3D
Curve.h
Go to the documentation of this file.
1//----------------------------------------------------------------------------//
2
3/*
4 * Copyright (c) 2009 Sony Pictures Imageworks Inc
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the
17 * distribution. Neither the name of Sony Pictures Imageworks nor the
18 * names of its contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36//----------------------------------------------------------------------------//
37
43//----------------------------------------------------------------------------//
44
45#ifndef _INCLUDED_Field3D_Curve_H_
46#define _INCLUDED_Field3D_Curve_H_
47
48//----------------------------------------------------------------------------//
49
50#include <algorithm>
51#include <utility>
52#include <vector>
53
54#include <boost/lexical_cast.hpp>
55
56#include <OpenEXR/ImathFun.h>
57#include <OpenEXR/ImathMatrix.h>
58
59//----------------------------------------------------------------------------//
60
61#include "ns.h"
62
64
65//----------------------------------------------------------------------------//
66// Curve
67//----------------------------------------------------------------------------//
68
75//----------------------------------------------------------------------------//
76
77template <typename T>
78class Curve
79{
80public:
81
82 // Typedefs ------------------------------------------------------------------
83
84 typedef std::pair<float, T> Sample;
85 typedef std::vector<Sample> SampleVec;
86
87 // Main methods --------------------------------------------------------------
88
92 void addSample(const float t, const T &value);
93
96 T linear(const float t) const;
97
99 size_t numSamples() const
100 { return m_samples.size(); }
101
103 const SampleVec& samples() const
104 { return m_samples; }
105
107 void clear()
108 { SampleVec().swap(m_samples); }
109
110private:
111
112 // Structs -------------------------------------------------------------------
113
116 public std::unary_function<std::pair<float, T>, bool>
117 {
119 : m_match(match)
120 { }
121 bool operator()(std::pair<float, T> test)
122 {
123 return test.first > m_match;
124 }
125 private:
126 float m_match;
127 };
128
130 struct CheckTEqual :
131 public std::unary_function<std::pair<float, T>, bool>
132 {
134 : m_match(match)
135 { }
136 bool operator()(std::pair<float, T> test)
137 {
138 return test.first == m_match;
139 }
140 private:
141 float m_match;
142 };
143
144 // Utility methods -----------------------------------------------------------
145
151 { return T(0); }
152
156 T lerp(const Sample &lower, const Sample &upper, const float t) const
157 { return Imath::lerp(lower.second, upper.second, t); }
158
159 // Private data members ------------------------------------------------------
160
164
165};
166
167//----------------------------------------------------------------------------//
168// Template implementations
169//----------------------------------------------------------------------------//
170
171template <typename T>
172void Curve<T>::addSample(const float t, const T &value)
173{
174 using namespace std;
175 // Check that sample time is not already in curve
176 typename SampleVec::iterator i =
177 find_if(m_samples.begin(), m_samples.end(), CheckTEqual(t));
178 if (i != m_samples.end()) {
179 // Sample position already exists, so we replace it
180 i->second = value;
181 return;
182 }
183 // Find the first sample location that is greater than the interpolation
184 // position
185 i = find_if(m_samples.begin(), m_samples.end(), CheckTGreaterThan(t));
186 // If we get something other than end() back then we insert the new
187 // sample before that. If there wasn't a larger value we add this sample
188 // to the end of the vector.
189 if (i != m_samples.end()) {
190 m_samples.insert(i, make_pair(t, value));
191 } else {
192 m_samples.push_back(make_pair(t, value));
193 }
194}
195
196//----------------------------------------------------------------------------//
197
198template <typename T>
199T Curve<T>::linear(const float t) const
200{
201 using namespace std;
202 // If there are no samples, return zero
203 if (m_samples.size() == 0) {
204 return defaultReturnValue();
205 }
206 // Find the first sample location that is greater than the interpolation
207 // position
208 typename SampleVec::const_iterator i =
209 find_if(m_samples.begin(), m_samples.end(), CheckTGreaterThan(t));
210 // If we get end() back then there was no sample larger, so we return the
211 // last value. If we got the first value then there is only one value and
212 // we return that.
213 if (i == m_samples.end()) {
214 return m_samples.back().second;
215 } else if (i == m_samples.begin()) {
216 return m_samples.front().second;
217 }
218 // Interpolate between the nearest two samples.
219 const Sample &upper = *i;
220 const Sample &lower = *(--i);
221 const float interpT = Imath::lerpfactor(t, lower.first, upper.first);
222 return lerp(lower, upper, interpT);
223}
224
225//----------------------------------------------------------------------------//
226// Template specializations
227//----------------------------------------------------------------------------//
228
229template <>
230inline Imath::Matrix44<float>
231Curve<Imath::Matrix44<float> >::defaultReturnValue() const
232{
233 Imath::Matrix44<float> identity;
234 identity.makeIdentity();
235 return identity;
236}
237
238//----------------------------------------------------------------------------//
239
240template <>
241inline Imath::Matrix44<double>
242Curve<Imath::Matrix44<double> >::defaultReturnValue() const
243{
244 Imath::Matrix44<double> identity;
245 identity.makeIdentity();
246 return identity;
247}
248
249//----------------------------------------------------------------------------//
250
252
253//----------------------------------------------------------------------------//
254
255#endif // Include guard
bool match(const std::string &name, const std::string &attribute, const std::vector< std::string > &patterns, const MatchFlags flags=MatchEmptyPattern)
Matches a <name>:<attribute> string against a set of patterns.
Implements a simple function curve where samples of type T can be added along a 1D axis....
Definition: Curve.h:79
T lerp(const Sample &lower, const Sample &upper, const float t) const
The default implementation for linear interpolation. Works for all classes for which Imath::lerp is i...
Definition: Curve.h:156
std::pair< float, T > Sample
Definition: Curve.h:84
SampleVec m_samples
Stores the samples that define the curve. Sample insertion ensures that the samples are sorted accord...
Definition: Curve.h:163
void addSample(const float t, const T &value)
Adds a sample point to the curve.
Definition: Curve.h:172
size_t numSamples() const
Returns the number of samples in the curve.
Definition: Curve.h:99
const SampleVec & samples() const
Returns a const reference to the samples in the curve.
Definition: Curve.h:103
T defaultReturnValue() const
The default return value is used when no sample points are available. This defaults to zero,...
Definition: Curve.h:150
void clear()
Clears all samples in curve.
Definition: Curve.h:107
T linear(const float t) const
Linearly interpolates a value from the curve.
Definition: Curve.h:199
std::vector< Sample > SampleVec
Definition: Curve.h:85
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Used when finding values in the m_samples vector.
Definition: Curve.h:132
bool operator()(std::pair< float, T > test)
Definition: Curve.h:136
CheckTEqual(float match)
Definition: Curve.h:133
Used when finding values in the m_samples vector.
Definition: Curve.h:117
CheckTGreaterThan(float match)
Definition: Curve.h:118
bool operator()(std::pair< float, T > test)
Definition: Curve.h:121