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 49 namespace Imath { 50 51 template <class T> 52 inline T 53 abs (T a) 54 { 55 return (a > T(0)) ? a : -a; 56 } 57 58 59 template <class T> 60 inline int 61 sign (T a) 62 { 63 return (a > T(0))? 1 : ((a < T(0)) ? -1 : 0); 64 } 65 66 67 template <class T, class Q> 68 inline T 69 lerp (T a, T b, Q t) 70 { 71 return (T) (a * (1 - t) + b * t); 72 } 73 74 75 template <class T, class Q> 76 inline T 77 ulerp (T a, T b, Q t) 78 { 79 return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t)); 80 } 81 82 83 template <class T> 84 inline T 85 lerpfactor(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 107 template <class T> 108 inline T 109 clamp (T a, T l, T h) 110 { 111 return (a < l)? l : ((a > h)? h : a); 112 } 113 114 115 template <class T> 116 inline int 117 cmp (T a, T b) 118 { 119 return Imath::sign (a - b); 120 } 121 122 123 template <class T> 124 inline int 125 cmpt (T a, T b, T t) 126 { 127 return (Imath::abs (a - b) <= t)? 0 : cmp (a, b); 128 } 129 130 131 template <class T> 132 inline bool 133 iszero (T a, T t) 134 { 135 return (Imath::abs (a) <= t) ? 1 : 0; 136 } 137 138 139 template <class T1, class T2, class T3> 140 inline bool 141 equal (T1 a, T2 b, T3 t) 142 { 143 return Imath::abs (a - b) <= t; 144 } 145 146 template <class T> 147 inline int 148 floor (T x) 149 { 150 return (x >= 0)? int (x): -(int (-x) + (-x > int (-x))); 151 } 152 153 154 template <class T> 155 inline int 156 ceil (T x) 157 { 158 return -floor (-x); 159 } 160 161 template <class T> 162 inline int 163 trunc (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 177 inline int 178 divs (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 185 inline int 186 mods (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 201 inline int 202 divp (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 209 inline int 210 modp (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 236 float succf (float f); 237 float predf (float f); 238 239 double succd (double d); 240 double predd (double d); 241 242 // 243 // Return true if the number is not a NaN or Infinity. 244 // 245 246 inline bool 247 finitef (float f) 248 { 249 union {float f; int i;} u; 250 u.f = f; 251 252 return (u.i & 0x7f800000) != 0x7f800000; 253 } 254 255 inline bool 256 finited (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