00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "primitive.h"
00025 #include "light.h"
00026 #include "material.h"
00027
00028 using namespace lux;
00029
00030
00031 Primitive::~Primitive() { }
00032
00033 bool Primitive::CanIntersect() const {
00034 return true;
00035 }
00036
00037 void
00038 Primitive::Refine(vector<Primitive* > &refined)
00039 const {
00040 luxError(LUX_BUG,LUX_SEVERE,"Unimplemented Primitive::Refine method called!");
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 void Primitive::FullyRefine(
00070 vector<Primitive* > &refined) const {
00071 vector<Primitive*> todo;
00072 todo.push_back(const_cast<Primitive *>(this));
00073 while (todo.size()) {
00074
00075 Primitive* prim = todo.back();
00076 todo.pop_back();
00077 if (prim->CanIntersect())
00078 refined.push_back(prim);
00079 else
00080 prim->Refine(todo);
00081 }
00082 }
00083
00084 const AreaLight *Aggregate::GetAreaLight() const {
00085 luxError(LUX_BUG,LUX_SEVERE,"Aggregate::GetAreaLight() method called; should have gone to GeometricPrimitive");
00086 return NULL;
00087 }
00088 BSDF *Aggregate::GetBSDF(const DifferentialGeometry &,
00089 const Transform &, float u) const {
00090 luxError(LUX_BUG,LUX_SEVERE,"Aggregate::GetBSDF() method called; should have gone to GeometricPrimitive");
00091 return NULL;
00092 }
00093
00094 bool InstancePrimitive::Intersect(const Ray &r,
00095 Intersection *isect) const {
00096 Ray ray = WorldToInstance(r);
00097 if (!instance->Intersect(ray, isect))
00098 return false;
00099 r.maxt = ray.maxt;
00100 isect->WorldToObject = isect->WorldToObject *
00101 WorldToInstance;
00102
00103 isect->dg.p = InstanceToWorld(isect->dg.p);
00104 isect->dg.nn = Normalize(InstanceToWorld(isect->dg.nn));
00105 isect->dg.dpdu = InstanceToWorld(isect->dg.dpdu);
00106 isect->dg.dpdv = InstanceToWorld(isect->dg.dpdv);
00107 isect->dg.dndu = InstanceToWorld(isect->dg.dndu);
00108 isect->dg.dndv = InstanceToWorld(isect->dg.dndv);
00109 return true;
00110 }
00111 bool InstancePrimitive::IntersectP(const Ray &r) const {
00112 return instance->IntersectP(WorldToInstance(r));
00113 }
00114
00115 BBox GeometricPrimitive::WorldBound() const {
00116 return shape->WorldBound();
00117 }
00118 bool GeometricPrimitive::IntersectP(const Ray &r) const {
00119 return shape->IntersectP(r);
00120 }
00121 bool GeometricPrimitive::CanIntersect() const {
00122 return shape->CanIntersect();
00123 }
00124 void GeometricPrimitive::
00125 Refine(vector<Primitive* > &refined)
00126 const {
00127 vector<boost::shared_ptr<Shape> > r;
00128 shape->Refine(r);
00129 for (u_int i = 0; i < r.size(); ++i) {
00130
00131
00132
00133 Primitive* o (new GeometricPrimitive(r[i],
00134 material, areaLight));
00135 refined.push_back(o);
00136 }
00137 }
00138 GeometricPrimitive::
00139 GeometricPrimitive(const boost::shared_ptr<Shape> &s,
00140 const boost::shared_ptr<Material> &m, AreaLight *a)
00141 : shape(s), material(m), areaLight(a) {
00142 }
00143 bool GeometricPrimitive::Intersect(const Ray &r,
00144 Intersection *isect) const {
00145 float thit;
00146 if (!shape->Intersect(r, &thit, &isect->dg))
00147 return false;
00148 isect->primitive = this;
00149 isect->WorldToObject = shape->WorldToObject;
00150 r.maxt = thit;
00151 return true;
00152 }
00153 const AreaLight *GeometricPrimitive::GetAreaLight() const {
00154 return areaLight;
00155 }
00156 BSDF *
00157 GeometricPrimitive::GetBSDF(const DifferentialGeometry &dg,
00158 const Transform &WorldToObject, float u) const {
00159 DifferentialGeometry dgs;
00160 shape->GetShadingGeometry(WorldToObject.GetInverse(),
00161 dg, &dgs);
00162 return material->GetBSDF(dg, dgs, u);
00163 }
00164
00165 BSDF *Intersection::GetBSDF(const RayDifferential &ray, float u)
00166 const {
00167
00168
00169 dg.ComputeDifferentials(ray);
00170 return primitive->GetBSDF(dg, WorldToObject, u);
00171 }
00172 SWCSpectrum Intersection::Le(const Vector &w) const {
00173 const AreaLight *area = primitive->GetAreaLight();
00174 return area ? area->L(dg.p, dg.nn, w) : SWCSpectrum(0.);
00175 }
00176 SWCSpectrum Intersection::Le(const Ray &ray, const Normal &n, BSDF **bsdf, float *pdf, float *pdfDirect) const
00177 {
00178 const AreaLight *area = primitive->GetAreaLight();
00179 if (area)
00180 return area->L(ray, dg, n, bsdf, pdf, pdfDirect);
00181 *pdf = *pdfDirect = 0.f;
00182 *bsdf = NULL;
00183 return 0.f;
00184 }