///////////////////////////////////////////////////////////////////////////1//2// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas3// Digital Ltd. LLC4//5// All rights reserved.6//7// Redistribution and use in source and binary forms, with or without8// modification, are permitted provided that the following conditions are9// met:10// * Redistributions of source code must retain the above copyright11// notice, this list of conditions and the following disclaimer.12// * Redistributions in binary form must reproduce the above13// copyright notice, this list of conditions and the following disclaimer14// in the documentation and/or other materials provided with the15// distribution.16// * Neither the name of Industrial Light & Magic nor the names of17// its contributors may be used to endorse or promote products derived18// from this software without specific prior written permission.19//20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31//32///////////////////////////////////////////////////////////////////////////33343536#ifndef INCLUDED_IMATHFUN_H37#define INCLUDED_IMATHFUN_H3839//-----------------------------------------------------------------------------40//41// Miscellaneous utility functions42//43//-----------------------------------------------------------------------------4445#include "ImathLimits.h"46#include "ImathInt64.h"4748namespace Imath {4950template <class T>51inline T52abs (T a)53{54return (a > T(0)) ? a : -a;55}565758template <class T>59inline int60sign (T a)61{62return (a > T(0))? 1 : ((a < T(0)) ? -1 : 0);63}646566template <class T, class Q>67inline T68lerp (T a, T b, Q t)69{70return (T) (a * (1 - t) + b * t);71}727374template <class T, class Q>75inline T76ulerp (T a, T b, Q t)77{78return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t));79}808182template <class T>83inline T84lerpfactor(T m, T a, T b)85{86//87// Return how far m is between a and b, that is return t such that88// if:89// t = lerpfactor(m, a, b);90// then:91// m = lerp(a, b, t);92//93// If a==b, return 0.94//9596T d = b - a;97T n = m - a;9899if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d))100return n / d;101102return T(0);103}104105106template <class T>107inline T108clamp (T a, T l, T h)109{110return (a < l)? l : ((a > h)? h : a);111}112113114template <class T>115inline int116cmp (T a, T b)117{118return Imath::sign (a - b);119}120121122template <class T>123inline int124cmpt (T a, T b, T t)125{126return (Imath::abs (a - b) <= t)? 0 : cmp (a, b);127}128129130template <class T>131inline bool132iszero (T a, T t)133{134return (Imath::abs (a) <= t) ? 1 : 0;135}136137138template <class T1, class T2, class T3>139inline bool140equal (T1 a, T2 b, T3 t)141{142return Imath::abs (a - b) <= t;143}144145template <class T>146inline int147floor (T x)148{149return (x >= 0)? int (x): -(int (-x) + (-x > int (-x)));150}151152153template <class T>154inline int155ceil (T x)156{157return -floor (-x);158}159160template <class T>161inline int162trunc (T x)163{164return (x >= 0) ? int(x) : -int(-x);165}166167168//169// Integer division and remainder where the170// remainder of x/y has the same sign as x:171//172// divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))173// mods(x,y) == x - y * divs(x,y)174//175176inline int177divs (int x, int y)178{179return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):180((y >= 0)? -(-x / y): (-x / -y));181}182183184inline int185mods (int x, int y)186{187return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)):188((y >= 0)? -(-x % y): -(-x % -y));189}190191192//193// Integer division and remainder where the194// remainder of x/y is always positive:195//196// divp(x,y) == floor (double(x) / double (y))197// modp(x,y) == x - y * divp(x,y)198//199200inline int201divp (int x, int y)202{203return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):204((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y));205}206207208inline int209modp (int x, int y)210{211return x - y * divp (x, y);212}213214//----------------------------------------------------------215// Successor and predecessor for floating-point numbers:216//217// succf(f) returns float(f+e), where e is the smallest218// positive number such that float(f+e) != f.219//220// predf(f) returns float(f-e), where e is the smallest221// positive number such that float(f-e) != f.222//223// succd(d) returns double(d+e), where e is the smallest224// positive number such that double(d+e) != d.225//226// predd(d) returns double(d-e), where e is the smallest227// positive number such that double(d-e) != d.228//229// Exceptions: If the input value is an infinity or a nan,230// succf(), predf(), succd(), and predd() all231// return the input value without changing it.232//233//----------------------------------------------------------234235float succf (float f);236float predf (float f);237238double succd (double d);239double predd (double d);240241//242// Return true if the number is not a NaN or Infinity.243//244245inline bool246finitef (float f)247{248union {float f; int i;} u;249u.f = f;250251return (u.i & 0x7f800000) != 0x7f800000;252}253254inline bool255finited (double d)256{257union {double d; Int64 i;} u;258u.d = d;259260return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;261}262263264} // namespace Imath265266#endif267268269