Nori
|
00001 /* 00002 This file is part of Nori, a simple educational ray tracer 00003 00004 Copyright (c) 2012 by Wenzel Jakob and Steve Marschner. 00005 00006 Nori is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License Version 3 00008 as published by the Free Software Foundation. 00009 00010 Nori is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #if !defined(__COMMON_H) 00020 #define __COMMON_H 00021 00022 #define EIGEN_NO_DEBUG 00023 00024 #if defined(_MSC_VER) 00025 /* Disable some warnings on MSVC++ */ 00026 #pragma warning(disable : 4307) /* "integral constant overflow" in Eigen */ 00027 #define WIN32_LEAN_AND_MEAN /* Don't ever include MFC on Windows */ 00028 #define NOMINMAX /* Don't override min/max */ 00029 #endif 00030 00031 /* Include the basics needed by any Nori file */ 00032 #include <iostream> 00033 #include <algorithm> 00034 #include <vector> 00035 #include <Eigen/Core> 00036 #include <QString> 00037 #include <stdint.h> 00038 #include <ImathPlatform.h> 00039 00040 /* Convenience definitions */ 00041 #define NORI_NAMESPACE_BEGIN namespace nori { 00042 #define NORI_NAMESPACE_END } 00043 00044 /* "Ray epsilon": relative error threshold for ray intersection computations */ 00045 #define Epsilon 1e-4f 00046 00047 /* A few useful constants */ 00048 #define INV_PI 0.31830988618379067154f 00049 #define INV_TWOPI 0.15915494309189533577f 00050 #define INV_FOURPI 0.07957747154594766788f 00051 #define SQRT_TWO 1.41421356237309504880f 00052 #define INV_SQRT_TWO 0.70710678118654752440f 00053 00054 /* Optimization-related macros */ 00055 #if defined(__GNUC__) 00056 #define EXPECT_TAKEN(a) __builtin_expect(a, true) 00057 #define EXPECT_NOT_TAKEN(a) __builtin_expect(a, false) 00058 #if defined(__LINUX__) 00059 #define __restrict __restrict__ 00060 #endif 00061 #else 00062 #define EXPECT_TAKEN(a) a 00063 #define EXPECT_NOT_TAKEN(a) a 00064 #endif 00065 00066 /* MSVC is missing a few C99 functions */ 00067 #if defined(_MSC_VER) 00068 /// No nextafterf()! -- an implementation is provided in support_win32.cpp 00069 extern float nextafterf(float x, float y); 00070 #endif 00071 00072 #if !defined(_GNU_SOURCE) 00073 /// Emulate sincosf using sinf() and cosf() 00074 inline void sincosf(float theta, float *_sin, float *_cos) { 00075 *_sin = sinf(theta); 00076 *_cos = cosf(theta); 00077 } 00078 #endif 00079 00080 NORI_NAMESPACE_BEGIN 00081 00082 /* Forward declarations */ 00083 template <typename Scalar, int Dimension> struct TVector; 00084 template <typename Scalar, int Dimension> struct TPoint; 00085 template <typename Point, typename Vector> struct TRay; 00086 template <typename Point> struct TBoundingBox; 00087 00088 /* Basic Nori data structures (vectors, points, rays, bounding boxes, 00089 kd-trees) are oblivious to the underlying data type and dimension. 00090 The following list of typedefs establishes some convenient aliases 00091 for specific types. */ 00092 typedef TVector<float, 1> Vector1f; 00093 typedef TVector<float, 2> Vector2f; 00094 typedef TVector<float, 3> Vector3f; 00095 typedef TVector<float, 4> Vector4f; 00096 typedef TVector<double, 1> Vector1d; 00097 typedef TVector<double, 2> Vector2d; 00098 typedef TVector<double, 3> Vector3d; 00099 typedef TVector<double, 4> Vector4d; 00100 typedef TVector<int, 1> Vector1i; 00101 typedef TVector<int, 2> Vector2i; 00102 typedef TVector<int, 3> Vector3i; 00103 typedef TVector<int, 4> Vector4i; 00104 typedef TPoint<float, 1> Point1f; 00105 typedef TPoint<float, 2> Point2f; 00106 typedef TPoint<float, 3> Point3f; 00107 typedef TPoint<float, 4> Point4f; 00108 typedef TPoint<double, 1> Point1d; 00109 typedef TPoint<double, 2> Point2d; 00110 typedef TPoint<double, 3> Point3d; 00111 typedef TPoint<double, 4> Point4d; 00112 typedef TPoint<int, 1> Point1i; 00113 typedef TPoint<int, 2> Point2i; 00114 typedef TPoint<int, 3> Point3i; 00115 typedef TPoint<int, 4> Point4i; 00116 typedef TBoundingBox<Point1f> BoundingBox1f; 00117 typedef TBoundingBox<Point2f> BoundingBox2f; 00118 typedef TBoundingBox<Point3f> BoundingBox3f; 00119 typedef TBoundingBox<Point4f> BoundingBox4f; 00120 typedef TBoundingBox<Point1d> BoundingBox1d; 00121 typedef TBoundingBox<Point2d> BoundingBox2d; 00122 typedef TBoundingBox<Point3d> BoundingBox3d; 00123 typedef TBoundingBox<Point4d> BoundingBox4d; 00124 typedef TBoundingBox<Point1i> BoundingBox1i; 00125 typedef TBoundingBox<Point2i> BoundingBox2i; 00126 typedef TBoundingBox<Point3i> BoundingBox3i; 00127 typedef TBoundingBox<Point4i> BoundingBox4i; 00128 typedef TRay<Point2f, Vector2f> Ray2f; 00129 typedef TRay<Point3f, Vector3f> Ray3f; 00130 00131 /// Some more forward declarations 00132 class NoriObject; 00133 class NoriObjectFactory; 00134 class Mesh; 00135 class BSDF; 00136 class Bitmap; 00137 class BlockGenerator; 00138 class ImageBlock; 00139 class Camera; 00140 class Integrator; 00141 class Sampler; 00142 class KDTree; 00143 class Scene; 00144 class ReconstructionFilter; 00145 00146 /// Import cout, cerr, endl for debugging purposes 00147 using std::cout; 00148 using std::cerr; 00149 using std::endl; 00150 00151 /// Simple exception class, which stores a human-readable error description 00152 class NoriException { 00153 public: 00154 NoriException(const QString &reason) : m_reason(reason) { } 00155 inline const QString &getReason() const { return m_reason; } 00156 private: 00157 QString m_reason; 00158 }; 00159 00160 /// Measures associated with probability distributions 00161 enum EMeasure { 00162 EUnknownMeasure = 0, 00163 ESolidAngle, 00164 EDiscrete 00165 }; 00166 00167 //// Convert radians to degrees 00168 inline float radToDeg(float value) { return value * (180.0f / M_PI); } 00169 00170 /// Convert degrees to radians 00171 inline float degToRad(float value) { return value * (M_PI / 180.0f); } 00172 00173 /// Simple floating point clamping function 00174 inline float clamp(float value, float min, float max) { 00175 if (value < min) 00176 return min; 00177 else if (value > max) 00178 return max; 00179 else return value; 00180 } 00181 00182 /// Simple integer clamping function 00183 inline int clamp(int value, int min, int max) { 00184 if (value < min) 00185 return min; 00186 else if (value > max) 00187 return max; 00188 else return value; 00189 } 00190 00191 /// Linearly interpolate between two values 00192 inline float lerp(float t, float v1, float v2) { 00193 return ((float) 1 - t) * v1 + t * v2; 00194 } 00195 00196 /// Uniformly sample a vector on the unit sphere with respect to solid angles 00197 extern Vector3f squareToUniformSphere(const Point2f &sample); 00198 00199 /// Uniformly sample a vector on the unit hemisphere with respect to solid angles 00200 extern Vector3f squareToUniformHemisphere(const Point2f &sample); 00201 00202 /// Uniformly sample a vector on the unit hemisphere with respect to projected solid angles 00203 extern Vector3f squareToCosineHemisphere(const Point2f &sample); 00204 00205 /// Uniformly sample a vector on a 2D disk 00206 extern Point2f squareToUniformDisk(const Point2f &sample); 00207 00208 /// Low-distortion concentric square to disk mapping by Peter Shirley (PDF: 1/PI) 00209 extern Point2f squareToUniformDiskConcentric(const Point2f &sample); 00210 00211 /// Convert an uniformly distributed square sample into barycentric coordinates 00212 extern Point2f squareToUniformTriangle(const Point2f &sample); 00213 00214 /// Compute a direction for the given coordinates in spherical coordinates 00215 extern Vector3f sphericalDirection(float theta, float phi); 00216 00217 /// Compute a direction for the given coordinates in spherical coordinates 00218 extern Point2f sphericalCoordinates(const Vector3f &dir); 00219 00220 /// Indent a complete string (except for the first line) by the requested number of spaces 00221 extern QString indent(const QString &string, int amount = 2); 00222 00223 /// Allocate an aligned region of memory 00224 extern void *allocAligned(size_t size); 00225 00226 /// Free an aligned region of memory 00227 extern void freeAligned(void *ptr); 00228 00229 /// Return the number of cores (real and virtual) 00230 extern int getCoreCount(); 00231 00232 NORI_NAMESPACE_END 00233 00234 #endif /* __COMMON_H */