--- /dev/null
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef INCLUDED_IMATHFUN_H
+#define INCLUDED_IMATHFUN_H
+
+//-----------------------------------------------------------------------------
+//
+// Miscellaneous utility functions
+//
+//-----------------------------------------------------------------------------
+
+#include "ImathLimits.h"
+
+namespace Imath {
+
+template <class T>
+inline T
+abs (T a)
+{
+ return (a > 0) ? a : -a;
+}
+
+
+template <class T>
+inline int
+sign (T a)
+{
+ return (a > 0)? 1 : ((a < 0) ? -1 : 0);
+}
+
+
+template <class T, class Q>
+inline T
+lerp (T a, T b, Q t)
+{
+ return (T) (a + (b - a) * t);
+}
+
+
+template <class T, class Q>
+inline T
+ulerp (T a, T b, Q t)
+{
+ return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t));
+}
+
+
+template <class T>
+inline T
+lerpfactor(T m, T a, T b)
+{
+ //
+ // Return how far m is between a and b, that is return t such that
+ // if:
+ // t = lerpfactor(m, a, b);
+ // then:
+ // m = lerp(a, b, t);
+ //
+ // If a==b, return 0.
+ //
+
+ T d = b - a;
+ T n = m - a;
+
+ if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d))
+ return n / d;
+
+ return T(0);
+}
+
+
+template <class T>
+inline T
+clamp (T a, T l, T h)
+{
+ return (a < l)? l : ((a > h)? h : a);
+}
+
+
+template <class T>
+inline int
+cmp (T a, T b)
+{
+ return Imath::sign (a - b);
+}
+
+
+template <class T>
+inline int
+cmpt (T a, T b, T t)
+{
+ return (Imath::abs (a - b) <= t)? 0 : cmp (a, b);
+}
+
+
+template <class T>
+inline bool
+iszero (T a, T t)
+{
+ return (Imath::abs (a) <= t) ? 1 : 0;
+}
+
+
+template <class T1, class T2, class T3>
+inline bool
+equal (T1 a, T2 b, T3 t)
+{
+ return Imath::abs (a - b) <= t;
+}
+
+template <class T>
+inline int
+floor (T x)
+{
+ return (x >= 0)? int (x): -(int (-x) + (-x > int (-x)));
+}
+
+
+template <class T>
+inline int
+ceil (T x)
+{
+ return -floor (-x);
+}
+
+template <class T>
+inline int
+trunc (T x)
+{
+ return (x >= 0) ? int(x) : -int(-x);
+}
+
+
+//
+// Integer division and remainder where the
+// remainder of x/y has the same sign as x:
+//
+// divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))
+// mods(x,y) == x - y * divs(x,y)
+//
+
+inline int
+divs (int x, int y)
+{
+ return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
+ ((y >= 0)? -(-x / y): (-x / -y));
+}
+
+
+inline int
+mods (int x, int y)
+{
+ return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)):
+ ((y >= 0)? -(-x % y): -(-x % -y));
+}
+
+
+//
+// Integer division and remainder where the
+// remainder of x/y is always positive:
+//
+// divp(x,y) == floor (double(x) / double (y))
+// modp(x,y) == x - y * divp(x,y)
+//
+
+inline int
+divp (int x, int y)
+{
+ return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
+ ((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y));
+}
+
+
+inline int
+modp (int x, int y)
+{
+ return x - y * divp (x, y);
+}
+
+//----------------------------------------------------------
+// Successor and predecessor for floating-point numbers:
+//
+// succf(f) returns float(f+e), where e is the smallest
+// positive number such that float(f+e) != f.
+//
+// predf(f) returns float(f-e), where e is the smallest
+// positive number such that float(f-e) != f.
+//
+// succd(d) returns double(d+e), where e is the smallest
+// positive number such that double(d+e) != d.
+//
+// predd(d) returns double(d-e), where e is the smallest
+// positive number such that double(d-e) != d.
+//
+// Exceptions: If the input value is an infinity or a nan,
+// succf(), predf(), succd(), and predd() all
+// return the input value without changing it.
+//
+//----------------------------------------------------------
+
+float succf (float f);
+float predf (float f);
+
+double succd (double d);
+double predd (double d);
+
+//
+// Return true if the number is not a NaN or Infinity.
+//
+
+inline bool
+finitef (float f)
+{
+ union {float f; int i;} u;
+ u.f = f;
+
+ return (u.i & 0x7f800000) != 0x7f800000;
+}
+
+inline bool
+finited (double d)
+{
+#if ULONG_MAX == 18446744073709551615LU
+ typedef long unsigned int Int64;
+#else
+ typedef long long unsigned int Int64;
+#endif
+
+ union {double d; Int64 i;} u;
+ u.d = d;
+
+ return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;
+}
+
+
+} // namespace Imath
+
+#endif