1/////////////////////////////////////////////////////////////////////////// 2// 3// Copyright (c) 2002, 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 "ImathLimits.h" 47#include "ImathInt64.h" 48 49namespace Imath { 50 51template <class T> 52inline T 53abs (T a) 54{ 55 return (a > 0) ? a : -a; 56} 57 58 59template <class T> 60inline int 61sign (T a) 62{ 63 return (a > 0)? 1 : ((a < 0) ? -1 : 0); 64} 65 66 67template <class T, class Q> 68inline T 69lerp (T a, T b, Q t) 70{ 71 return (T) (a * (1 - t) + b * t); 72} 73 74 75template <class T, class Q> 76inline T 77ulerp (T a, T b, Q t) 78{ 79 return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t)); 80} 81 82 83template <class T> 84inline T 85lerpfactor(T m, T a, T b) 86{ 87 // 88 // Return how far m is between a and b, that is return t such that 89 // if: 90 // t = lerpfactor(m, a, b); 91 // then: 92 // m = lerp(a, b, t); 93 // 94 // If a==b, return 0. 95 // 96 97 T d = b - a; 98 T n = m - a; 99 100 if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d)) 101 return n / d; 102 103 return T(0); 104} 105 106 107template <class T> 108inline T 109clamp (T a, T l, T h) 110{ 111 return (a < l)? l : ((a > h)? h : a); 112} 113 114 115template <class T> 116inline int 117cmp (T a, T b) 118{ 119 return Imath::sign (a - b); 120} 121 122 123template <class T> 124inline int 125cmpt (T a, T b, T t) 126{ 127 return (Imath::abs (a - b) <= t)? 0 : cmp (a, b); 128} 129 130 131template <class T> 132inline bool 133iszero (T a, T t) 134{ 135 return (Imath::abs (a) <= t) ? 1 : 0; 136} 137 138 139template <class T1, class T2, class T3> 140inline bool 141equal (T1 a, T2 b, T3 t) 142{ 143 return Imath::abs (a - b) <= t; 144} 145 146template <class T> 147inline int 148floor (T x) 149{ 150 return (x >= 0)? int (x): -(int (-x) + (-x > int (-x))); 151} 152 153 154template <class T> 155inline int 156ceil (T x) 157{ 158 return -floor (-x); 159} 160 161template <class T> 162inline int 163trunc (T x) 164{ 165 return (x >= 0) ? int(x) : -int(-x); 166} 167 168 169// 170// Integer division and remainder where the 171// remainder of x/y has the same sign as x: 172// 173// divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y)) 174// mods(x,y) == x - y * divs(x,y) 175// 176 177inline int 178divs (int x, int y) 179{ 180 return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)): 181 ((y >= 0)? -(-x / y): (-x / -y)); 182} 183 184 185inline int 186mods (int x, int y) 187{ 188 return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)): 189 ((y >= 0)? -(-x % y): -(-x % -y)); 190} 191 192 193// 194// Integer division and remainder where the 195// remainder of x/y is always positive: 196// 197// divp(x,y) == floor (double(x) / double (y)) 198// modp(x,y) == x - y * divp(x,y) 199// 200 201inline int 202divp (int x, int y) 203{ 204 return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)): 205 ((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y)); 206} 207 208 209inline int 210modp (int x, int y) 211{ 212 return x - y * divp (x, y); 213} 214 215//---------------------------------------------------------- 216// Successor and predecessor for floating-point numbers: 217// 218// succf(f) returns float(f+e), where e is the smallest 219// positive number such that float(f+e) != f. 220// 221// predf(f) returns float(f-e), where e is the smallest 222// positive number such that float(f-e) != f. 223// 224// succd(d) returns double(d+e), where e is the smallest 225// positive number such that double(d+e) != d. 226// 227// predd(d) returns double(d-e), where e is the smallest 228// positive number such that double(d-e) != d. 229// 230// Exceptions: If the input value is an infinity or a nan, 231// succf(), predf(), succd(), and predd() all 232// return the input value without changing it. 233// 234//---------------------------------------------------------- 235 236float succf (float f); 237float predf (float f); 238 239double succd (double d); 240double predd (double d); 241 242// 243// Return true if the number is not a NaN or Infinity. 244// 245 246inline bool 247finitef (float f) 248{ 249 union {float f; int i;} u; 250 u.f = f; 251 252 return (u.i & 0x7f800000) != 0x7f800000; 253} 254 255inline bool 256finited (double d) 257{ 258 union {double d; Int64 i;} u; 259 u.d = d; 260 261 return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL; 262} 263 264 265} // namespace Imath 266 267#endif 268