00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "primitive.h"
00026 #include "light.h"
00027
00028 Primitive::~Primitive() { }
00029
00030 bool Primitive::CanIntersect() const {
00031 return true;
00032 }
00033
00034 void
00035 Primitive::Refine(vector<Reference<Primitive> > &refined)
00036 const {
00037 Severe("Unimplemented Primitive::Refine"
00038 "method called!");
00039 }
00040 void Primitive::FullyRefine(
00041 vector<Reference<Primitive> > &refined) const {
00042 vector<Reference<Primitive> > todo;
00043 todo.push_back(const_cast<Primitive *>(this));
00044 while (todo.size()) {
00045
00046 Reference<Primitive> prim = todo.back();
00047 todo.pop_back();
00048 if (prim->CanIntersect())
00049 refined.push_back(prim);
00050 else
00051 prim->Refine(todo);
00052 }
00053 }
00054 const AreaLight *Aggregate::GetAreaLight() const {
00055 Severe("Aggregate::GetAreaLight() method"
00056 "called; should have gone to GeometricPrimitive");
00057 return NULL;
00058 }
00059 BSDF *Aggregate::GetBSDF(const DifferentialGeometry &,
00060 const Transform &) const {
00061 Severe("Aggregate::GetBSDF() method"
00062 "called; should have gone to GeometricPrimitive");
00063 return NULL;
00064 }
00065
00066 bool InstancePrimitive::Intersect(const Ray &r,
00067 Intersection *isect) const {
00068 Ray ray = WorldToInstance(r);
00069 if (!instance->Intersect(ray, isect))
00070 return false;
00071 r.maxt = ray.maxt;
00072 isect->WorldToObject = isect->WorldToObject *
00073 WorldToInstance;
00074
00075 isect->dg.p = InstanceToWorld(isect->dg.p);
00076 isect->dg.nn = Normalize(InstanceToWorld(isect->dg.nn));
00077 isect->dg.dpdu = InstanceToWorld(isect->dg.dpdu);
00078 isect->dg.dpdv = InstanceToWorld(isect->dg.dpdv);
00079 isect->dg.dndu = InstanceToWorld(isect->dg.dndu);
00080 isect->dg.dndv = InstanceToWorld(isect->dg.dndv);
00081 return true;
00082 }
00083 bool InstancePrimitive::IntersectP(const Ray &r) const {
00084 return instance->IntersectP(WorldToInstance(r));
00085 }
00086
00087 BBox GeometricPrimitive::WorldBound() const {
00088 return shape->WorldBound();
00089 }
00090 bool GeometricPrimitive::IntersectP(const Ray &r) const {
00091 return shape->IntersectP(r);
00092 }
00093 bool GeometricPrimitive::CanIntersect() const {
00094 return shape->CanIntersect();
00095 }
00096 void GeometricPrimitive::
00097 Refine(vector<Reference<Primitive> > &refined)
00098 const {
00099 vector<Reference<Shape> > r;
00100 shape->Refine(r);
00101 for (u_int i = 0; i < r.size(); ++i) {
00102 GeometricPrimitive *gp =
00103 new GeometricPrimitive(r[i],
00104 material, areaLight);
00105 refined.push_back(gp);
00106 }
00107 }
00108 GeometricPrimitive::
00109 GeometricPrimitive(const Reference<Shape> &s,
00110 const Reference<Material> &m, AreaLight *a)
00111 : shape(s), material(m), areaLight(a) {
00112 }
00113 bool GeometricPrimitive::Intersect(const Ray &r,
00114 Intersection *isect) const {
00115 float thit;
00116 if (!shape->Intersect(r, &thit, &isect->dg))
00117 return false;
00118 isect->primitive = this;
00119 isect->WorldToObject = shape->WorldToObject;
00120 r.maxt = thit;
00121 return true;
00122 }
00123 const AreaLight *GeometricPrimitive::GetAreaLight() const {
00124 return areaLight;
00125 }
00126 BSDF *
00127 GeometricPrimitive::GetBSDF(const DifferentialGeometry &dg,
00128 const Transform &WorldToObject) const {
00129 DifferentialGeometry dgs;
00130 shape->GetShadingGeometry(WorldToObject.GetInverse(),
00131 dg, &dgs);
00132 return material->GetBSDF(dg, dgs);
00133 }
00134
00135 BSDF *Intersection::GetBSDF(const RayDifferential &ray)
00136 const {
00137 static StatsCounter pointsShaded("Shading", "Number of points shaded");
00138 ++pointsShaded;
00139 dg.ComputeDifferentials(ray);
00140 return primitive->GetBSDF(dg, WorldToObject);
00141 }
00142 Spectrum Intersection::Le(const Vector &w) const {
00143 const AreaLight *area = primitive->GetAreaLight();
00144 return area ? area->L(dg.p, dg.nn, w) : Spectrum(0.);
00145 }