00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if defined(_MSC_VER)
00025 #pragma once
00026 #endif
00027
00028 #ifndef PBRT_CORE_PBRT_H
00029 #define PBRT_CORE_PBRT_H
00030
00031
00032
00033 #if defined(_WIN32) || defined(_WIN64)
00034 #define PBRT_IS_WINDOWS
00035 #elif defined(__linux__)
00036 #define PBRT_IS_LINUX
00037 #elif defined(__APPLE__)
00038 #define PBRT_IS_APPLE
00039 #elif defined(__OpenBSD__)
00040 #define PBRT_IS_OPENBSD
00041 #endif
00042
00043
00044 #include <math.h>
00045 #include <stdlib.h>
00046 #define _GNU_SOURCE 1
00047 #include <stdio.h>
00048 #include <string.h>
00049 #include <string>
00050 using std::string;
00051 #include <vector>
00052 using std::vector;
00053 #include "error.h"
00054 #if !defined(__APPLE__) && !defined(__OpenBSD__)
00055 #include <malloc.h>
00056 #endif
00057 #if !defined(PBRT_IS_WINDOWS) && !defined(__APPLE__) && !defined(__OpenBSD__)
00058 #include <alloca.h>
00059 #endif
00060 #include <assert.h>
00061 #include <algorithm>
00062 using std::min;
00063 using std::max;
00064 using std::swap;
00065 using std::sort;
00066
00067
00068 #if defined(PBRT_IS_WINDOWS)
00069 #include <float.h>
00070 #define isnan _isnan
00071 #define isinf(f) (!_finite((f)))
00072 #define int8_t __int8
00073 #define uint8_t unsigned __int8
00074 #define int16_t __int16
00075 #define uint16_t unsigned __int16
00076 #define int32_t __int32
00077 #define uint32_t unsigned __int32
00078 #define int64_t __int64
00079 #define uint64_t unsigned __int64
00080 #pragma warning (disable : 4305) // double constant assigned to float
00081 #pragma warning (disable : 4244) // int -> float conversion
00082 #pragma warning (disable : 4267) // size_t -> unsigned int conversion
00083 #endif
00084
00085 #ifdef __linux__
00086 #include <stdint.h>
00087 #endif // __linux__
00088 #if defined(PBRT_IS_WINDOWS)
00089 #define isnan _isnan
00090 #define isinf(f) (!_finite((f)))
00091 #endif
00092
00093
00094 #define ALLOCA(TYPE, COUNT) (TYPE *)alloca((COUNT) * sizeof(TYPE))
00095
00096
00097 class RNG;
00098 class Timer;
00099 class ProgressReporter;
00100 class MemoryArena;
00101 template <typename T, int logBlockSize = 2> class BlockedArray;
00102 struct Matrix4x4;
00103 class Mutex;
00104 class RWMutex;
00105 class Shape;
00106 class ParamSet;
00107 template <typename T> struct ParamSetItem;
00108 struct Options {
00109 Options() { nCores = 0;
00110 quickRender = quiet = openWindow = verbose = false;
00111 imageFile = ""; }
00112 int nCores;
00113 bool quickRender;
00114 bool quiet, verbose;
00115 bool openWindow;
00116 string imageFile;
00117 };
00118
00119
00120 extern Options PbrtOptions;
00121 class TextureParams;
00122 class Scene;
00123 class Renderer;
00124 class Vector;
00125 class Point;
00126 class Normal;
00127 class Ray;
00128 class RayDifferential;
00129 class BBox;
00130 class Transform;
00131 struct DifferentialGeometry;
00132 class Primitive;
00133 struct Intersection;
00134 class GeometricPrimitive;
00135 template <int nSamples> class CoefficientSpectrum;
00136 class RGBSpectrum;
00137 class SampledSpectrum;
00138 typedef RGBSpectrum Spectrum;
00139
00140 class Camera;
00141 class ProjectiveCamera;
00142 class Sampler;
00143 struct CameraSample;
00144 struct Sample;
00145 class Filter;
00146 class Film;
00147 class BxDF;
00148 class BRDF;
00149 class BTDF;
00150 class BSDF;
00151 class Material;
00152 template <typename T> class Texture;
00153 class VolumeRegion;
00154 class BSSRDF;
00155 class Light;
00156 struct VisibilityTester;
00157 class AreaLight;
00158 struct Distribution1D;
00159 struct Distribution2D;
00160 struct BSDFSample;
00161 struct BSDFSampleOffsets;
00162 struct LightSample;
00163 struct LightSampleOffsets;
00164 class SurfaceIntegrator;
00165 class Integrator;
00166 class VolumeIntegrator;
00167
00168
00169 #define PBRT_VERSION "2.0.0"
00170 #ifdef M_PI
00171 #undef M_PI
00172 #endif
00173 #define M_PI 3.14159265358979323846f
00174 #define INV_PI 0.31830988618379067154f
00175 #define INV_TWOPI 0.15915494309189533577f
00176 #define INV_FOURPI 0.07957747154594766788f
00177 #ifndef INFINITY
00178 #define INFINITY FLT_MAX
00179 #endif
00180 #if defined(PBRT_IS_WINDOWS)
00181 #define alloca _alloca
00182 #endif
00183 #ifndef PBRT_L1_CACHE_LINE_SIZE
00184 #define PBRT_L1_CACHE_LINE_SIZE 64
00185 #endif
00186 #ifndef PBRT_POINTER_SIZE
00187 #if defined(__amd64__) || defined(_M_X64)
00188 #define PBRT_POINTER_SIZE 8
00189 #elif defined(__i386__) || defined(_M_IX86)
00190 #define PBRT_POINTER_SIZE 4
00191 #endif
00192 #endif
00193 #ifndef PBRT_HAS_64_BIT_ATOMICS
00194 #if (PBRT_POINTER_SIZE == 8)
00195 #define PBRT_HAS_64_BIT_ATOMICS
00196 #endif
00197 #endif // PBRT_HAS_64_BIT_ATOMICS
00198
00199
00200 inline float Lerp(float t, float v1, float v2) {
00201 return (1.f - t) * v1 + t * v2;
00202 }
00203
00204
00205 inline float Clamp(float val, float low, float high) {
00206 if (val < low) return low;
00207 else if (val > high) return high;
00208 else return val;
00209 }
00210
00211
00212 inline int Clamp(int val, int low, int high) {
00213 if (val < low) return low;
00214 else if (val > high) return high;
00215 else return val;
00216 }
00217
00218
00219 inline int Mod(int a, int b) {
00220 int n = int(a/b);
00221 a -= n*b;
00222 if (a < 0) a += b;
00223 return a;
00224 }
00225
00226
00227 inline float Radians(float deg) {
00228 return ((float)M_PI/180.f) * deg;
00229 }
00230
00231
00232 inline float Degrees(float rad) {
00233 return (180.f/(float)M_PI) * rad;
00234 }
00235
00236
00237 inline float Log2(float x) {
00238 static float invLog2 = 1.f / logf(2.f);
00239 return logf(x) * invLog2;
00240 }
00241
00242
00243 inline int Floor2Int(float val);
00244 inline int Log2Int(float v) {
00245 return Floor2Int(Log2(v));
00246 }
00247
00248
00249 inline bool IsPowerOf2(int v) {
00250 return (v & (v - 1)) == 0;
00251 }
00252
00253
00254 inline uint32_t RoundUpPow2(uint32_t v) {
00255 v--;
00256 v |= v >> 1; v |= v >> 2;
00257 v |= v >> 4; v |= v >> 8;
00258 v |= v >> 16;
00259 return v+1;
00260 }
00261
00262
00263 inline int Floor2Int(float val) {
00264 return (int)floorf(val);
00265 }
00266
00267
00268 inline int Round2Int(float val) {
00269 return Floor2Int(val + 0.5f);
00270 }
00271
00272
00273 inline int Float2Int(float val) {
00274 return (int)val;
00275 }
00276
00277
00278 inline int Ceil2Int(float val) {
00279 return (int)ceilf(val);
00280 }
00281
00282
00283 #ifdef NDEBUG
00284 #define Assert(expr) ((void)0)
00285 #else
00286 #define Assert(expr) \
00287 ((expr) ? (void)0 : \
00288 Severe("Assertion \"%s\" failed in %s, line %d", \
00289 #expr, __FILE__, __LINE__))
00290 #endif // NDEBUG
00291 inline bool Quadratic(float A, float B, float C, float *t0, float *t1) {
00292
00293 float discrim = B * B - 4.f * A * C;
00294 if (discrim <= 0.) return false;
00295 float rootDiscrim = sqrtf(discrim);
00296
00297
00298 float q;
00299 if (B < 0) q = -.5f * (B - rootDiscrim);
00300 else q = -.5f * (B + rootDiscrim);
00301 *t0 = q / A;
00302 *t1 = C / q;
00303 if (*t0 > *t1) swap(*t0, *t1);
00304 return true;
00305 }
00306
00307
00308
00309 #endif // PBRT_CORE_PBRT_H