1///////////////////////////////////////////////////////////////////////////
2//
3// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
4// Digital Ltd. LLC
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 are
10// met:
11// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Industrial Light & Magic nor the names of
18// its contributors may be used to endorse or promote products derived
19// from this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33///////////////////////////////////////////////////////////////////////////
34
35
36
37#ifndef INCLUDED_IMATHFUN_H
38#define INCLUDED_IMATHFUN_H
39
40//-----------------------------------------------------------------------------
41//
42// Miscellaneous utility functions
43//
44//-----------------------------------------------------------------------------
45
46#include "ImathExport.h"
47#include "ImathLimits.h"
48#include "ImathInt64.h"
49#include "ImathNamespace.h"
50
51IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
52
53template <class T>
54inline T
55abs (T a)
56{
57 return (a > T(0)) ? a : -a;
58}
59
60
61template <class T>
62inline int
63sign (T a)
64{
65 return (a > T(0))? 1 : ((a < T(0)) ? -1 : 0);
66}
67
68
69template <class T, class Q>
70inline T
71lerp (T a, T b, Q t)
72{
73 return (T) (a * (1 - t) + b * t);
74}
75
76
77template <class T, class Q>
78inline T
79ulerp (T a, T b, Q t)
80{
81 return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t));
82}
83
84
85template <class T>
86inline T
87lerpfactor(T m, T a, T b)
88{
89 //
90 // Return how far m is between a and b, that is return t such that
91 // if:
92 // t = lerpfactor(m, a, b);
93 // then:
94 // m = lerp(a, b, t);
95 //
96 // If a==b, return 0.
97 //
98
99 T d = b - a;
100 T n = m - a;
101
102 if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d))
103 return n / d;
104
105 return T(0);
106}
107
108
109template <class T>
110inline T
111clamp (T a, T l, T h)
112{
113 return (a < l)? l : ((a > h)? h : a);
114}
115
116
117template <class T>
118inline int
119cmp (T a, T b)
120{
121 return IMATH_INTERNAL_NAMESPACE::sign (a - b);
122}
123
124
125template <class T>
126inline int
127cmpt (T a, T b, T t)
128{
129 return (IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t)? 0 : cmp (a, b);
130}
131
132
133template <class T>
134inline bool
135iszero (T a, T t)
136{
137 return (IMATH_INTERNAL_NAMESPACE::abs (a) <= t) ? 1 : 0;
138}
139
140
141template <class T1, class T2, class T3>
142inline bool
143equal (T1 a, T2 b, T3 t)
144{
145 return IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t;
146}
147
148template <class T>
149inline int
150floor (T x)
151{
152 return (x >= 0)? int (x): -(int (-x) + (-x > int (-x)));
153}
154
155
156template <class T>
157inline int
158ceil (T x)
159{
160 return -floor (-x);
161}
162
163template <class T>
164inline int
165trunc (T x)
166{
167 return (x >= 0) ? int(x) : -int(-x);
168}
169
170
171//
172// Integer division and remainder where the
173// remainder of x/y has the same sign as x:
174//
175// divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))
176// mods(x,y) == x - y * divs(x,y)
177//
178
179inline int
180divs (int x, int y)
181{
182 return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
183 ((y >= 0)? -(-x / y): (-x / -y));
184}
185
186
187inline int
188mods (int x, int y)
189{
190 return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)):
191 ((y >= 0)? -(-x % y): -(-x % -y));
192}
193
194
195//
196// Integer division and remainder where the
197// remainder of x/y is always positive:
198//
199// divp(x,y) == floor (double(x) / double (y))
200// modp(x,y) == x - y * divp(x,y)
201//
202
203inline int
204divp (int x, int y)
205{
206 return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
207 ((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y));
208}
209
210
211inline int
212modp (int x, int y)
213{
214 return x - y * divp (x, y);
215}
216
217//----------------------------------------------------------
218// Successor and predecessor for floating-point numbers:
219//
220// succf(f) returns float(f+e), where e is the smallest
221// positive number such that float(f+e) != f.
222//
223// predf(f) returns float(f-e), where e is the smallest
224// positive number such that float(f-e) != f.
225//
226// succd(d) returns double(d+e), where e is the smallest
227// positive number such that double(d+e) != d.
228//
229// predd(d) returns double(d-e), where e is the smallest
230// positive number such that double(d-e) != d.
231//
232// Exceptions: If the input value is an infinity or a nan,
233// succf(), predf(), succd(), and predd() all
234// return the input value without changing it.
235//
236//----------------------------------------------------------
237
238IMATH_EXPORT float succf (float f);
239IMATH_EXPORT float predf (float f);
240
241IMATH_EXPORT double succd (double d);
242IMATH_EXPORT double predd (double d);
243
244//
245// Return true if the number is not a NaN or Infinity.
246//
247
248inline bool
249finitef (float f)
250{
251 union {float f; int i;} u;
252 u.f = f;
253
254 return (u.i & 0x7f800000) != 0x7f800000;
255}
256
257inline bool
258finited (double d)
259{
260 union {double d; Int64 i;} u;
261 u.d = d;
262
263 return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;
264}
265
266
267IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
268
269#endif // INCLUDED_IMATHFUN_H
270