00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PBRT_GEOMETRY_H
00025 #define PBRT_GEOMETRY_H
00026
00027 #include "pbrt.h"
00028 #include <float.h>
00029
00030 class COREDLL Vector {
00031 public:
00032
00033 Vector(float _x=0, float _y=0, float _z=0)
00034 : x(_x), y(_y), z(_z) {
00035 }
00036 explicit Vector(const Point &p);
00037 Vector operator+(const Vector &v) const {
00038 return Vector(x + v.x, y + v.y, z + v.z);
00039 }
00040
00041 Vector& operator+=(const Vector &v) {
00042 x += v.x; y += v.y; z += v.z;
00043 return *this;
00044 }
00045 Vector operator-(const Vector &v) const {
00046 return Vector(x - v.x, y - v.y, z - v.z);
00047 }
00048
00049 Vector& operator-=(const Vector &v) {
00050 x -= v.x; y -= v.y; z -= v.z;
00051 return *this;
00052 }
00053 bool operator==(const Vector &v) const {
00054 return x == v.x && y == v.y && z == v.z;
00055 }
00056 Vector operator*(float f) const {
00057 return Vector(f*x, f*y, f*z);
00058 }
00059
00060 Vector &operator*=(float f) {
00061 x *= f; y *= f; z *= f;
00062 return *this;
00063 }
00064 Vector operator/(float f) const {
00065 Assert(f!=0);
00066 float inv = 1.f / f;
00067 return Vector(x * inv, y * inv, z * inv);
00068 }
00069
00070 Vector &operator/=(float f) {
00071 Assert(f!=0);
00072 float inv = 1.f / f;
00073 x *= inv; y *= inv; z *= inv;
00074 return *this;
00075 }
00076 Vector operator-() const {
00077 return Vector(-x, -y, -z);
00078 }
00079 float operator[](int i) const {
00080 Assert(i >= 0 && i <= 2);
00081 return (&x)[i];
00082 }
00083
00084 float &operator[](int i) {
00085 Assert(i >= 0 && i <= 2);
00086 return (&x)[i];
00087 }
00088 float LengthSquared() const { return x*x + y*y + z*z; }
00089 float Length() const { return sqrtf(LengthSquared()); }
00090 explicit Vector(const Normal &n);
00091
00092 float x, y, z;
00093 };
00094 class COREDLL Point {
00095 public:
00096
00097 Point(float _x=0, float _y=0, float _z=0)
00098 : x(_x), y(_y), z(_z) {
00099 }
00100 Point operator+(const Vector &v) const {
00101 return Point(x + v.x, y + v.y, z + v.z);
00102 }
00103
00104 Point &operator+=(const Vector &v) {
00105 x += v.x; y += v.y; z += v.z;
00106 return *this;
00107 }
00108 Vector operator-(const Point &p) const {
00109 return Vector(x - p.x, y - p.y, z - p.z);
00110 }
00111
00112 Point operator-(const Vector &v) const {
00113 return Point(x - v.x, y - v.y, z - v.z);
00114 }
00115
00116 Point &operator-=(const Vector &v) {
00117 x -= v.x; y -= v.y; z -= v.z;
00118 return *this;
00119 }
00120 Point &operator+=(const Point &p) {
00121 x += p.x; y += p.y; z += p.z;
00122 return *this;
00123 }
00124 Point operator+(const Point &p) const {
00125 return Point(x + p.x, y + p.y, z + p.z);
00126 }
00127 Point operator* (float f) const {
00128 return Point(f*x, f*y, f*z);
00129 }
00130 Point &operator*=(float f) {
00131 x *= f; y *= f; z *= f;
00132 return *this;
00133 }
00134 Point operator/ (float f) const {
00135 float inv = 1.f/f;
00136 return Point(inv*x, inv*y, inv*z);
00137 }
00138 Point &operator/=(float f) {
00139 float inv = 1.f/f;
00140 x *= inv; y *= inv; z *= inv;
00141 return *this;
00142 }
00143 float operator[](int i) const { return (&x)[i]; }
00144 float &operator[](int i) { return (&x)[i]; }
00145
00146 float x,y,z;
00147 };
00148 class COREDLL Normal {
00149 public:
00150
00151 Normal(float _x=0, float _y=0, float _z=0)
00152 : x(_x), y(_y), z(_z) {}
00153 Normal operator-() const {
00154 return Normal(-x, -y, -z);
00155 }
00156 Normal operator+ (const Normal &v) const {
00157 return Normal(x + v.x, y + v.y, z + v.z);
00158 }
00159
00160 Normal& operator+=(const Normal &v) {
00161 x += v.x; y += v.y; z += v.z;
00162 return *this;
00163 }
00164 Normal operator- (const Normal &v) const {
00165 return Normal(x - v.x, y - v.y, z - v.z);
00166 }
00167
00168 Normal& operator-=(const Normal &v) {
00169 x -= v.x; y -= v.y; z -= v.z;
00170 return *this;
00171 }
00172 Normal operator* (float f) const {
00173 return Normal(f*x, f*y, f*z);
00174 }
00175
00176 Normal &operator*=(float f) {
00177 x *= f; y *= f; z *= f;
00178 return *this;
00179 }
00180 Normal operator/ (float f) const {
00181 float inv = 1.f/f;
00182 return Normal(x * inv, y * inv, z * inv);
00183 }
00184
00185 Normal &operator/=(float f) {
00186 float inv = 1.f/f;
00187 x *= inv; y *= inv; z *= inv;
00188 return *this;
00189 }
00190 float LengthSquared() const { return x*x + y*y + z*z; }
00191 float Length() const { return sqrtf(LengthSquared()); }
00192
00193 explicit Normal(const Vector &v)
00194 : x(v.x), y(v.y), z(v.z) {}
00195 float operator[](int i) const { return (&x)[i]; }
00196 float &operator[](int i) { return (&x)[i]; }
00197
00198 float x,y,z;
00199 };
00200 class COREDLL Ray {
00201 public:
00202
00203 Ray(): mint(RAY_EPSILON), maxt(INFINITY), time(0.f) {}
00204 Ray(const Point &origin, const Vector &direction,
00205 float start = RAY_EPSILON, float end = INFINITY, float t = 0.f)
00206 : o(origin), d(direction), mint(start), maxt(end), time(t) { }
00207 Point operator()(float t) const { return o + d * t; }
00208
00209 Point o;
00210 Vector d;
00211 mutable float mint, maxt;
00212 float time;
00213 };
00214 class COREDLL RayDifferential : public Ray {
00215 public:
00216
00217 RayDifferential() { hasDifferentials = false; }
00218 RayDifferential(const Point &org, const Vector &dir)
00219 : Ray(org, dir) {
00220 hasDifferentials = false;
00221 }
00222 explicit RayDifferential(const Ray &ray) : Ray(ray) {
00223 hasDifferentials = false;
00224 }
00225
00226 bool hasDifferentials;
00227 Ray rx, ry;
00228 };
00229 class COREDLL BBox {
00230 public:
00231
00232 BBox() {
00233 pMin = Point( INFINITY, INFINITY, INFINITY);
00234 pMax = Point(-INFINITY, -INFINITY, -INFINITY);
00235 }
00236 BBox(const Point &p) : pMin(p), pMax(p) { }
00237 BBox(const Point &p1, const Point &p2) {
00238 pMin = Point(min(p1.x, p2.x),
00239 min(p1.y, p2.y),
00240 min(p1.z, p2.z));
00241 pMax = Point(max(p1.x, p2.x),
00242 max(p1.y, p2.y),
00243 max(p1.z, p2.z));
00244 }
00245 friend inline ostream &
00246 operator<<(ostream &os, const BBox &b);
00247 friend COREDLL BBox Union(const BBox &b, const Point &p);
00248 friend COREDLL BBox Union(const BBox &b, const BBox &b2);
00249 bool Overlaps(const BBox &b) const {
00250 bool x = (pMax.x >= b.pMin.x) && (pMin.x <= b.pMax.x);
00251 bool y = (pMax.y >= b.pMin.y) && (pMin.y <= b.pMax.y);
00252 bool z = (pMax.z >= b.pMin.z) && (pMin.z <= b.pMax.z);
00253 return (x && y && z);
00254 }
00255 bool Inside(const Point &pt) const {
00256 return (pt.x >= pMin.x && pt.x <= pMax.x &&
00257 pt.y >= pMin.y && pt.y <= pMax.y &&
00258 pt.z >= pMin.z && pt.z <= pMax.z);
00259 }
00260 void Expand(float delta) {
00261 pMin -= Vector(delta, delta, delta);
00262 pMax += Vector(delta, delta, delta);
00263 }
00264 float Volume() const {
00265 Vector d = pMax - pMin;
00266 return d.x * d.y * d.z;
00267 }
00268 int MaximumExtent() const {
00269 Vector diag = pMax - pMin;
00270 if (diag.x > diag.y && diag.x > diag.z)
00271 return 0;
00272 else if (diag.y > diag.z)
00273 return 1;
00274 else
00275 return 2;
00276 }
00277 void BoundingSphere(Point *c, float *rad) const;
00278 bool IntersectP(const Ray &ray,
00279 float *hitt0 = NULL,
00280 float *hitt1 = NULL) const;
00281
00282 Point pMin, pMax;
00283 };
00284
00285 inline Vector::Vector(const Point &p)
00286 : x(p.x), y(p.y), z(p.z) {
00287 }
00288 inline ostream &operator<<(ostream &os, const Vector &v) {
00289 os << v.x << ", " << v.y << ", " << v.z;
00290 return os;
00291 }
00292 inline Vector operator*(float f, const Vector &v) {
00293 return v*f;
00294 }
00295 inline float Dot(const Vector &v1, const Vector &v2) {
00296 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
00297 }
00298 inline float AbsDot(const Vector &v1, const Vector &v2) {
00299 return fabsf(Dot(v1, v2));
00300 }
00301 inline Vector Cross(const Vector &v1, const Vector &v2) {
00302 return Vector((v1.y * v2.z) - (v1.z * v2.y),
00303 (v1.z * v2.x) - (v1.x * v2.z),
00304 (v1.x * v2.y) - (v1.y * v2.x));
00305 }
00306 inline Vector Cross(const Vector &v1, const Normal &v2) {
00307 return Vector((v1.y * v2.z) - (v1.z * v2.y),
00308 (v1.z * v2.x) - (v1.x * v2.z),
00309 (v1.x * v2.y) - (v1.y * v2.x));
00310 }
00311 inline Vector Cross(const Normal &v1, const Vector &v2) {
00312 return Vector((v1.y * v2.z) - (v1.z * v2.y),
00313 (v1.z * v2.x) - (v1.x * v2.z),
00314 (v1.x * v2.y) - (v1.y * v2.x));
00315 }
00316 inline Vector Normalize(const Vector &v) {
00317 return v / v.Length();
00318 }
00319 inline void CoordinateSystem(const Vector &v1, Vector *v2, Vector *v3) {
00320 if (fabsf(v1.x) > fabsf(v1.y)) {
00321 float invLen = 1.f / sqrtf(v1.x*v1.x + v1.z*v1.z);
00322 *v2 = Vector(-v1.z * invLen, 0.f, v1.x * invLen);
00323 }
00324 else {
00325 float invLen = 1.f / sqrtf(v1.y*v1.y + v1.z*v1.z);
00326 *v2 = Vector(0.f, v1.z * invLen, -v1.y * invLen);
00327 }
00328 *v3 = Cross(v1, *v2);
00329 }
00330 inline float Distance(const Point &p1, const Point &p2) {
00331 return (p1 - p2).Length();
00332 }
00333 inline float DistanceSquared(const Point &p1, const Point &p2) {
00334 return (p1 - p2).LengthSquared();
00335 }
00336 inline ostream &operator<<(ostream &os, const Point &v) {
00337 os << v.x << ", " << v.y << ", " << v.z;
00338 return os;
00339 }
00340 inline Point operator*(float f, const Point &p) {
00341 return p*f;
00342 }
00343 inline Normal operator*(float f, const Normal &n) {
00344 return Normal(f*n.x, f*n.y, f*n.z);
00345 }
00346 inline Normal Normalize(const Normal &n) {
00347 return n / n.Length();
00348 }
00349 inline Vector::Vector(const Normal &n)
00350 : x(n.x), y(n.y), z(n.z) { }
00351 inline float Dot(const Normal &n1, const Vector &v2) {
00352 return n1.x * v2.x + n1.y * v2.y + n1.z * v2.z;
00353 }
00354 inline float Dot(const Vector &v1, const Normal &n2) {
00355 return v1.x * n2.x + v1.y * n2.y + v1.z * n2.z;
00356 }
00357 inline float Dot(const Normal &n1, const Normal &n2) {
00358 return n1.x * n2.x + n1.y * n2.y + n1.z * n2.z;
00359 }
00360 inline float AbsDot(const Normal &n1, const Vector &v2) {
00361 return fabsf(n1.x * v2.x + n1.y * v2.y + n1.z * v2.z);
00362 }
00363 inline float AbsDot(const Vector &v1, const Normal &n2) {
00364 return fabsf(v1.x * n2.x + v1.y * n2.y + v1.z * n2.z);
00365 }
00366 inline float AbsDot(const Normal &n1, const Normal &n2) {
00367 return fabsf(n1.x * n2.x + n1.y * n2.y + n1.z * n2.z);
00368 }
00369 inline ostream &operator<<(ostream &os, const Normal &v) {
00370 os << v.x << ", " << v.y << ", " << v.z;
00371 return os;
00372 }
00373 inline ostream &operator<<(ostream &os, Ray &r) {
00374 os << "org: " << r.o << "dir: " << r.d << " range [" <<
00375 r.mint << "," << r.maxt << "] time = " <<
00376 r.time;
00377 return os;
00378 }
00379 inline ostream &operator<<(ostream &os, const BBox &b) {
00380 os << b.pMin << " -> " << b.pMax;
00381 return os;
00382 }
00383 inline Vector SphericalDirection(float sintheta,
00384 float costheta, float phi) {
00385 return Vector(sintheta * cosf(phi),
00386 sintheta * sinf(phi),
00387 costheta);
00388 }
00389 inline Vector SphericalDirection(float sintheta,
00390 float costheta,
00391 float phi,
00392 const Vector &x,
00393 const Vector &y,
00394 const Vector &z) {
00395 return sintheta * cosf(phi) * x +
00396 sintheta * sinf(phi) * y + costheta * z;
00397 }
00398 inline float SphericalTheta(const Vector &v) {
00399 return acosf(Clamp(v.z, -1.f, 1.f));
00400 }
00401 inline float SphericalPhi(const Vector &v) {
00402 float p = atan2f(v.y, v.x);
00403 return (p < 0.f) ? p + 2.f*M_PI : p;
00404 }
00405 #endif // PBRT_GEOMETRY_H