Blame Imath/ImathFun.h

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