shape.h

Go to the documentation of this file.
00001 
00002 /*
00003  * pbrt source code Copyright(c) 1998-2007 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_SHAPE_H
00012 #define PBRT_SHAPE_H
00013 // shape.h*
00014 #include "pbrt.h"
00015 #include "geometry.h"
00016 #include "transform.h"
00017 #include "paramset.h"
00018 // DifferentialGeometry Declarations
00019 struct COREDLL DifferentialGeometry {
00020         DifferentialGeometry() { u = v = 0.; shape = NULL; }
00021         // DifferentialGeometry Public Methods
00022         DifferentialGeometry(const Point &P, const Vector &DPDU,
00023                         const Vector &DPDV, const Vector &DNDU,
00024                         const Vector &DNDV, float uu, float vv,
00025                         const Shape *sh);
00026         void ComputeDifferentials(const RayDifferential &r) const;
00027         // DifferentialGeometry Public Data
00028         Point p;
00029         Normal nn;
00030         float u, v;
00031         const Shape *shape;
00032         Vector dpdu, dpdv;
00033         Normal dndu, dndv;
00034         mutable Vector dpdx, dpdy;
00035         mutable float dudx, dvdx, dudy, dvdy;
00036 };
00037 // Shape Declarations
00038 class COREDLL Shape : public ReferenceCounted {
00039 public:
00040         // Shape Interface
00041         Shape(const Transform &o2w, bool ro);
00042         virtual ~Shape() { }
00043         virtual BBox ObjectBound() const = 0;
00044         virtual BBox WorldBound() const {
00045                 return ObjectToWorld(ObjectBound());
00046         }
00047         virtual bool CanIntersect() const { return true; }
00048         virtual void
00049                 Refine(vector<Reference<Shape> > &refined) const {
00050                 Severe("Unimplemented Shape::Refine() method called");
00051         }
00052         virtual bool Intersect(const Ray &ray, float *tHit,
00053                         DifferentialGeometry *dg) const {
00054                 Severe("Unimplemented Shape::Intersect()"
00055                    "method called");
00056                 return false;
00057         }
00058         virtual bool IntersectP(const Ray &ray) const {
00059                 Severe("Unimplemented Shape::IntersectP()"
00060                    "method called");
00061                 return false;
00062         }
00063         virtual void GetShadingGeometry(const Transform &obj2world,
00064                         const DifferentialGeometry &dg,
00065                         DifferentialGeometry *dgShading) const {
00066                 *dgShading = dg;
00067         }
00068         virtual float Area() const {
00069                 Severe("Unimplemented Shape::Area() method called");
00070                 return 0.;
00071         }
00072         virtual Point Sample(float u1, float u2, Normal *Ns) const {
00073                 Severe("Unimplemented Shape::Sample method called");
00074                 return Point();
00075         }
00076         virtual float Pdf(const Point &Pshape) const {
00077                 return 1.f / Area();
00078         }
00079         virtual Point Sample(const Point &P,
00080                         float u1, float u2, Normal *Ns) const {
00081                 return Sample(u1, u2, Ns);
00082         }
00083         virtual float Pdf(const Point &p, const Vector &wi) const {
00084                 // Intersect sample ray with area light geometry
00085                 DifferentialGeometry dgLight;
00086                 Ray ray(p, wi);
00087                 float thit;
00088                 if (!Intersect(ray, &thit, &dgLight)) return 0.;
00089                 // Convert light sample weight to solid angle measure
00090                 float pdf = DistanceSquared(p, ray(thit)) /
00091                         (AbsDot(dgLight.nn, -wi) * Area());
00092                 if (AbsDot(dgLight.nn, -wi) == 0.f) pdf = INFINITY; // NOBOOK
00093                 return pdf;
00094         }
00095         // Shape Public Data
00096         const Transform ObjectToWorld, WorldToObject;
00097         const bool reverseOrientation, transformSwapsHandedness;
00098 };
00099 class ShapeSet : public Shape {
00100 public:
00101         // ShapeSet Public Methods
00102         Point Sample(float u1, float u2, Normal *Ns) const {
00103                 float ls = RandomFloat();
00104                 u_int sn;
00105                 for (sn = 0; sn < shapes.size()-1; ++sn)
00106                         if (ls < areaCDF[sn]) break;
00107                 return shapes[sn]->Sample(u1, u2, Ns);
00108         }
00109         ShapeSet(const vector<Reference<Shape> > &s,
00110                 const Transform &o2w, bool ro)
00111                 : Shape(o2w, ro) {
00112                 shapes = s;
00113                 area = 0;
00114                 vector<float> areas;
00115                 for (u_int i = 0; i < shapes.size(); ++i) {
00116                         float a = shapes[i]->Area();
00117                         area += a;
00118                         areas.push_back(a);
00119                 }
00120                 float prevCDF = 0;
00121                 for (u_int i = 0; i < shapes.size(); ++i) {
00122                         areaCDF.push_back(prevCDF + areas[i] / area);
00123                         prevCDF = areaCDF[i];
00124                 }
00125         }
00126         BBox ObjectBound() const {
00127                 BBox ob;
00128                 for (u_int i = 0; i < shapes.size(); ++i)
00129                         ob = Union(ob, shapes[i]->ObjectBound());
00130                 return ob;
00131         }
00132         bool CanIntersect() const {
00133                 for (u_int i = 0; i < shapes.size(); ++i)
00134                         if (!shapes[i]->CanIntersect()) return false;
00135                 return true;
00136         }
00137         bool Intersect(const Ray &ray, float *t_hitp,
00138                         DifferentialGeometry *dg) const {
00139                 bool anyHit = false;
00140                 for (u_int i = 0; i < shapes.size(); ++i)
00141                         if (shapes[i]->Intersect(ray, t_hitp, dg)) anyHit = true;
00142                 return anyHit;
00143         }
00144         void Refine(vector<Reference<Shape> > &refined) const {
00145                 for (u_int i = 0; i < shapes.size(); ++i) {
00146                         if (shapes[i]->CanIntersect())
00147                                 refined.push_back(shapes[i]);
00148                         else shapes[i]->Refine(refined);
00149                 }
00150         
00151         }
00152         float Area() const { return area; }
00153 private:
00154         // ShapeSet Private Data
00155         float area;
00156         vector<float> areaCDF;
00157         vector<Reference<Shape> > shapes;
00158 };
00159 #endif // PBRT_SHAPE_H

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