17 #include <SeExpr2/Expression.h>
18 #include <SeExpr2/ExprBuiltins.h>
44 : cacheCV(0), prepared(false) {
52 _cvData.push_back(
CV(position, val, type));
60 std::sort(_cvData.begin(), _cvData.end(), cvLessThan);
63 CV& end = *(_cvData.end() - 1);
64 CV& begin = *(_cvData.begin());
65 int realCVs = _cvData.size() - 2;
68 begin.
_val = _cvData[1]._val;
71 int lastIndex = _cvData.size() - 1;
72 end._val = _cvData[lastIndex - 1]._val;
76 begin.
_pos = end._pos = 0;
77 begin.
_val = end._val = T();
79 begin.
_deriv = end._deriv = T();
83 for (
unsigned int i = 1; i < _cvData.size() - 1; i++) {
84 _cvData[i]._deriv = (_cvData[i + 1]._val - _cvData[i - 1]._val) / (_cvData[i + 1]._pos - _cvData[i - 1]._pos);
88 for (
unsigned int i = 0; i < _cvData.size() - 1; i++) {
89 if (_cvData[i]._interp == kMonotoneSpline) {
90 double h = _cvData[i + 1]._pos - _cvData[i]._pos;
92 _cvData[i]._deriv = _cvData[i + 1]._deriv = T();
94 T delta = (_cvData[i + 1]._val - _cvData[i]._val) / h;
95 clampCurveSegment(delta, _cvData[i]._deriv, _cvData[i + 1]._deriv);
107 const int numPoints = _cvData.size();
108 const CV* cvDataBegin = &_cvData[0];
110 std::upper_bound(cvDataBegin, cvDataBegin + numPoints,
CV(param, T(), kLinear), cvLessThan) - cvDataBegin;
113 const float t0 = _cvData[index - 1]._pos;
114 const T k0 = _cvData[index - 1]._val;
115 const InterpType interp = _cvData[index - 1]._interp;
116 const float t1 = _cvData[
index]._pos;
117 const T k1 = _cvData[
index]._val;
123 double u = (param - t0) / (t1 - t0);
124 return k0 + u * (k1 - k0);
127 double u = (param - t0) / (t1 - t0);
128 return k0 * (u - 1) * (u - 1) * (2 * u + 1) + k1 * u * u * (3 - 2 * u);
131 case kMonotoneSpline: {
132 double x = param - _cvData[index - 1]._pos;
133 double h = _cvData[
index]._pos - _cvData[index - 1]._pos;
134 T
y = _cvData[index - 1]._val;
135 T delta = _cvData[
index]._val - _cvData[index - 1]._val;
136 T d1 = _cvData[index - 1]._deriv;
137 T d2 = _cvData[
index]._deriv;
138 return (x * (delta * (3 * h - 2 * x) * x + h * (-h +
x) * (-(d1 * h) + (d1 + d2) * x))) / (h * h * h) + y;
153 const int numPoints = _cvData.size();
154 const CV* cvDataBegin = &_cvData[0];
156 std::upper_bound(cvDataBegin, cvDataBegin + numPoints,
CV(param, T(), kLinear), cvLessThan) - cvDataBegin;
159 const float t0 = _cvData[index - 1]._pos;
160 const double k0 = comp(_cvData[index - 1]._val, channel);
161 const InterpType interp = _cvData[index - 1]._interp;
162 const float t1 = _cvData[
index]._pos;
163 const double k1 = comp(_cvData[index]._val, channel);
169 double u = (param - t0) / (t1 - t0);
170 return k0 + u * (k1 - k0);
175 double u = (param - t0) / (t1 - t0);
176 return k0 * (u - 1) * (u - 1) * (2 * u + 1) + k1 * u * u * (3 - 2 * u);
180 case kMonotoneSpline: {
181 double x = param - _cvData[index - 1]._pos;
182 double h = _cvData[
index]._pos - _cvData[index - 1]._pos;
183 double y = comp(_cvData[index - 1]._val, channel);
185 comp(_cvData[index]._val, channel) - comp(_cvData[index - 1]._val, channel);
186 double d1 = comp(_cvData[index - 1]._deriv, channel);
187 double d2 = comp(_cvData[index]._deriv, channel);
189 return (x * (delta * (3 * h - 2 * x) * x + h * (-h + x) * (-(d1 * h) + (d1 + d2) * x))) / (h * h * h) + y;
201 const CV* cvDataBegin = &_cvData[0];
202 int numPoints = _cvData.size();
204 std::upper_bound(cvDataBegin, cvDataBegin + numPoints,
CV(param, T(), kLinear), cvLessThan) - cvDataBegin;
206 if (index - 1 > 0)
return _cvData[index - 1];
207 return _cvData[
index];
212 return interp == kNone || interp == kLinear || interp == kSmooth || interp == kSpline || interp == kMonotoneSpline;
227 for (
int i = 0; i < 3; i++) {
std::vector< CV > _cvData
void preparePoints()
Prepares points for evaluation (sorts and computes boundaries, clamps extrema)
static bool interpTypeValid(InterpType interp)
Returns whether the given interpolation type is supported.
static bool cvLessThan(const CV &cv1, const CV &cv2)
CV Parameter ordering (cv1._pos < cv2._pos)
Interpolation curve class for double->double and double->Vec3D.
T getValue(const double param) const
Evaluates curve and returns full value.
CV getLowerBoundCV(const double param) const
double max(double x, double y)
The result is computed int int< br >< divstyle="margin-left:40px;"> Picks values randomly between loRange and hiRange based on supplied index(which is automatically hashed). 
double min(double x, double y)
</pre >< h3 > A simple variable reference</h3 > This is not a very interesting subclass of expression until we add some additional variables Variables on some applications may be very dynamic In this we only need x
double clamp(double x, double lo, double hi)
static double comp(const T &val, const int i)
Returns a component of the given value.
void addPoint(double position, const T &val, InterpType type)
Adds a point to the curve.
InterpType
Supported interpolation types.
double getChannelValue(const double param, int channel) const
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float y
void clampCurveSegment(const T &delta, T &d1, T &d2)
Performs hermite derivative clamping in canonical space.