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
00026 #include "stdafx.h"
00027 #include "primitive.h"
00028 #include "light.h"
00029 #include "intersection.h"
00030
00031
00032 uint32_t Primitive::nextprimitiveId = 1;
00033 Primitive::~Primitive() { }
00034
00035 bool Primitive::CanIntersect() const {
00036 return true;
00037 }
00038
00039
00040
00041 void Primitive::Refine(vector<Reference<Primitive> > &refined) const {
00042 Severe("Unimplemented Primitive::Refine() method called!");
00043 }
00044
00045
00046 void
00047 Primitive::FullyRefine(vector<Reference<Primitive> > &refined) const {
00048 vector<Reference<Primitive> > todo;
00049 todo.push_back(const_cast<Primitive *>(this));
00050 while (todo.size()) {
00051
00052 Reference<Primitive> prim = todo.back();
00053 todo.pop_back();
00054 if (prim->CanIntersect())
00055 refined.push_back(prim);
00056 else
00057 prim->Refine(todo);
00058 }
00059 }
00060
00061
00062 const AreaLight *Aggregate::GetAreaLight() const {
00063 Severe("Aggregate::GetAreaLight() method"
00064 "called; should have gone to GeometricPrimitive");
00065 return NULL;
00066 }
00067
00068
00069 BSDF *Aggregate::GetBSDF(const DifferentialGeometry &,
00070 const Transform &, MemoryArena &) const {
00071 Severe("Aggregate::GetBSDF() method"
00072 "called; should have gone to GeometricPrimitive");
00073 return NULL;
00074 }
00075
00076
00077 BSSRDF *Aggregate::GetBSSRDF(const DifferentialGeometry &,
00078 const Transform &, MemoryArena &) const {
00079 Severe("Aggregate::GetBSSRDF() method"
00080 "called; should have gone to GeometricPrimitive");
00081 return NULL;
00082 }
00083
00084
00085
00086
00087 bool TransformedPrimitive::Intersect(const Ray &r,
00088 Intersection *isect) const {
00089 Transform w2p;
00090 WorldToPrimitive.Interpolate(r.time, &w2p);
00091 Ray ray = w2p(r);
00092 if (!primitive->Intersect(ray, isect))
00093 return false;
00094 r.maxt = ray.maxt;
00095 isect->primitiveId = primitiveId;
00096 if (!w2p.IsIdentity()) {
00097
00098 isect->WorldToObject = isect->WorldToObject * w2p;
00099 isect->ObjectToWorld = Inverse(isect->WorldToObject);
00100
00101
00102 Transform PrimitiveToWorld = Inverse(w2p);
00103 isect->dg.p = PrimitiveToWorld(isect->dg.p);
00104 isect->dg.nn = Normalize(PrimitiveToWorld(isect->dg.nn));
00105 isect->dg.dpdu = PrimitiveToWorld(isect->dg.dpdu);
00106 isect->dg.dpdv = PrimitiveToWorld(isect->dg.dpdv);
00107 isect->dg.dndu = PrimitiveToWorld(isect->dg.dndu);
00108 isect->dg.dndv = PrimitiveToWorld(isect->dg.dndv);
00109 }
00110 return true;
00111 }
00112
00113
00114 bool TransformedPrimitive::IntersectP(const Ray &r) const {
00115 return primitive->IntersectP(WorldToPrimitive(r));
00116 }
00117
00118
00119
00120
00121 BBox GeometricPrimitive::WorldBound() const {
00122 return shape->WorldBound();
00123 }
00124
00125
00126 bool GeometricPrimitive::IntersectP(const Ray &r) const {
00127 return shape->IntersectP(r);
00128 }
00129
00130
00131 bool GeometricPrimitive::CanIntersect() const {
00132 return shape->CanIntersect();
00133 }
00134
00135
00136 void GeometricPrimitive::
00137 Refine(vector<Reference<Primitive> > &refined)
00138 const {
00139 vector<Reference<Shape> > r;
00140 shape->Refine(r);
00141 for (uint32_t i = 0; i < r.size(); ++i) {
00142 GeometricPrimitive *gp = new GeometricPrimitive(r[i],
00143 material, areaLight);
00144 refined.push_back(gp);
00145 }
00146 }
00147
00148
00149 GeometricPrimitive::GeometricPrimitive(const Reference<Shape> &s,
00150 const Reference<Material> &m, AreaLight *a)
00151 : shape(s), material(m), areaLight(a) {
00152 }
00153
00154
00155 bool GeometricPrimitive::Intersect(const Ray &r,
00156 Intersection *isect) const {
00157 float thit, rayEpsilon;
00158 if (!shape->Intersect(r, &thit, &rayEpsilon, &isect->dg))
00159 return false;
00160 isect->primitive = this;
00161 isect->WorldToObject = *shape->WorldToObject;
00162 isect->ObjectToWorld = *shape->ObjectToWorld;
00163 isect->shapeId = shape->shapeId;
00164 isect->primitiveId = primitiveId;
00165 isect->rayEpsilon = rayEpsilon;
00166 r.maxt = thit;
00167 return true;
00168 }
00169
00170
00171 const AreaLight *GeometricPrimitive::GetAreaLight() const {
00172 return areaLight;
00173 }
00174
00175
00176 BSDF *GeometricPrimitive::GetBSDF(const DifferentialGeometry &dg,
00177 const Transform &ObjectToWorld,
00178 MemoryArena &arena) const {
00179 DifferentialGeometry dgs;
00180 shape->GetShadingGeometry(ObjectToWorld, dg, &dgs);
00181 return material->GetBSDF(dg, dgs, arena);
00182 }
00183
00184
00185 BSSRDF *GeometricPrimitive::GetBSSRDF(const DifferentialGeometry &dg,
00186 const Transform &ObjectToWorld,
00187 MemoryArena &arena) const {
00188 DifferentialGeometry dgs;
00189 shape->GetShadingGeometry(ObjectToWorld, dg, &dgs);
00190 return material->GetBSSRDF(dg, dgs, arena);
00191 }
00192
00193