PBRT
|
00001 00002 // 00003 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 00036 00037 #ifndef INCLUDED_IMATHFUN_H 00038 #define INCLUDED_IMATHFUN_H 00039 00040 //----------------------------------------------------------------------------- 00041 // 00042 // Miscellaneous utility functions 00043 // 00044 //----------------------------------------------------------------------------- 00045 00046 #include "ImathLimits.h" 00047 #include "ImathInt64.h" 00048 00049 namespace Imath { 00050 00051 template <class T> 00052 inline T 00053 abs (T a) 00054 { 00055 return (a > 0) ? a : -a; 00056 } 00057 00058 00059 template <class T> 00060 inline int 00061 sign (T a) 00062 { 00063 return (a > 0)? 1 : ((a < 0) ? -1 : 0); 00064 } 00065 00066 00067 template <class T, class Q> 00068 inline T 00069 lerp (T a, T b, Q t) 00070 { 00071 return (T) (a * (1 - t) + b * t); 00072 } 00073 00074 00075 template <class T, class Q> 00076 inline T 00077 ulerp (T a, T b, Q t) 00078 { 00079 return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t)); 00080 } 00081 00082 00083 template <class T> 00084 inline T 00085 lerpfactor(T m, T a, T b) 00086 { 00087 // 00088 // Return how far m is between a and b, that is return t such that 00089 // if: 00090 // t = lerpfactor(m, a, b); 00091 // then: 00092 // m = lerp(a, b, t); 00093 // 00094 // If a==b, return 0. 00095 // 00096 00097 T d = b - a; 00098 T n = m - a; 00099 00100 if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d)) 00101 return n / d; 00102 00103 return T(0); 00104 } 00105 00106 00107 template <class T> 00108 inline T 00109 clamp (T a, T l, T h) 00110 { 00111 return (a < l)? l : ((a > h)? h : a); 00112 } 00113 00114 00115 template <class T> 00116 inline int 00117 cmp (T a, T b) 00118 { 00119 return Imath::sign (a - b); 00120 } 00121 00122 00123 template <class T> 00124 inline int 00125 cmpt (T a, T b, T t) 00126 { 00127 return (Imath::abs (a - b) <= t)? 0 : cmp (a, b); 00128 } 00129 00130 00131 template <class T> 00132 inline bool 00133 iszero (T a, T t) 00134 { 00135 return (Imath::abs (a) <= t) ? 1 : 0; 00136 } 00137 00138 00139 template <class T1, class T2, class T3> 00140 inline bool 00141 equal (T1 a, T2 b, T3 t) 00142 { 00143 return Imath::abs (a - b) <= t; 00144 } 00145 00146 template <class T> 00147 inline int 00148 floor (T x) 00149 { 00150 return (x >= 0)? int (x): -(int (-x) + (-x > int (-x))); 00151 } 00152 00153 00154 template <class T> 00155 inline int 00156 ceil (T x) 00157 { 00158 return -floor (-x); 00159 } 00160 00161 template <class T> 00162 inline int 00163 trunc (T x) 00164 { 00165 return (x >= 0) ? int(x) : -int(-x); 00166 } 00167 00168 00169 // 00170 // Integer division and remainder where the 00171 // remainder of x/y has the same sign as x: 00172 // 00173 // divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y)) 00174 // mods(x,y) == x - y * divs(x,y) 00175 // 00176 00177 inline int 00178 divs (int x, int y) 00179 { 00180 return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)): 00181 ((y >= 0)? -(-x / y): (-x / -y)); 00182 } 00183 00184 00185 inline int 00186 mods (int x, int y) 00187 { 00188 return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)): 00189 ((y >= 0)? -(-x % y): -(-x % -y)); 00190 } 00191 00192 00193 // 00194 // Integer division and remainder where the 00195 // remainder of x/y is always positive: 00196 // 00197 // divp(x,y) == floor (double(x) / double (y)) 00198 // modp(x,y) == x - y * divp(x,y) 00199 // 00200 00201 inline int 00202 divp (int x, int y) 00203 { 00204 return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)): 00205 ((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y)); 00206 } 00207 00208 00209 inline int 00210 modp (int x, int y) 00211 { 00212 return x - y * divp (x, y); 00213 } 00214 00215 //---------------------------------------------------------- 00216 // Successor and predecessor for floating-point numbers: 00217 // 00218 // succf(f) returns float(f+e), where e is the smallest 00219 // positive number such that float(f+e) != f. 00220 // 00221 // predf(f) returns float(f-e), where e is the smallest 00222 // positive number such that float(f-e) != f. 00223 // 00224 // succd(d) returns double(d+e), where e is the smallest 00225 // positive number such that double(d+e) != d. 00226 // 00227 // predd(d) returns double(d-e), where e is the smallest 00228 // positive number such that double(d-e) != d. 00229 // 00230 // Exceptions: If the input value is an infinity or a nan, 00231 // succf(), predf(), succd(), and predd() all 00232 // return the input value without changing it. 00233 // 00234 //---------------------------------------------------------- 00235 00236 float succf (float f); 00237 float predf (float f); 00238 00239 double succd (double d); 00240 double predd (double d); 00241 00242 // 00243 // Return true if the number is not a NaN or Infinity. 00244 // 00245 00246 inline bool 00247 finitef (float f) 00248 { 00249 union {float f; int i;} u; 00250 u.f = f; 00251 00252 return (u.i & 0x7f800000) != 0x7f800000; 00253 } 00254 00255 inline bool 00256 finited (double d) 00257 { 00258 union {double d; Int64 i;} u; 00259 u.d = d; 00260 00261 return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL; 00262 } 00263 00264 00265 } // namespace Imath 00266 00267 #endif