geometry.h

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

Generated on Wed Sep 26 14:01:19 2007 for pbrt by  doxygen 1.5.1