00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LUX_PRIMITIVE_H
00024 #define LUX_PRIMITIVE_H
00025
00026 #include "lux.h"
00027 #include "motionsystem.h"
00028 #include "geometry/raydifferential.h"
00029 #include "spectrum.h"
00030
00031 namespace lux
00032 {
00033
00034 class PrimitiveRefinementHints;
00035
00036
00037 class Primitive {
00038 public:
00039
00040 virtual ~Primitive();
00041
00042
00046 virtual BBox WorldBound() const = 0;
00057 virtual void Refine(vector<boost::shared_ptr<Primitive> > &refined,
00058 const PrimitiveRefinementHints &refineHints,
00059 boost::shared_ptr<Primitive> thisPtr);
00060
00061
00065 virtual bool CanIntersect() const = 0;
00074 virtual bool Intersect(const Ray &r, Intersection *in) const;
00080 virtual bool IntersectP(const Ray &r) const;
00081
00082
00089 virtual void GetShadingGeometry(const Transform &obj2world,
00090 const DifferentialGeometry &dg, DifferentialGeometry *dgShading) const;
00091
00092
00096 virtual bool CanSample() const = 0;
00100 virtual float Area() const;
00110 virtual void Sample(float u1, float u2, float u3, DifferentialGeometry *dg) const;
00117 virtual float Pdf(const Point &p) const;
00129 virtual void Sample(const Point &p,
00130 float u1, float u2, float u3, DifferentialGeometry *dg) const;
00138 virtual float Pdf(const Point &p, const Vector &wi) const;
00147 virtual float Pdf(const Point &p, const Point &po) const;
00148 };
00149
00150 class PrimitiveRefinementHints {
00151 public:
00152 PrimitiveRefinementHints(bool isForSampling)
00153 : forSampling(isForSampling)
00154 {
00155 }
00156
00157
00158
00159 const bool forSampling;
00160 };
00161
00162 class Intersection {
00163 public:
00164
00165 Intersection() : primitive(NULL), material(NULL), arealight(NULL) { }
00166 BSDF *GetBSDF(const TsPack *tspack, const RayDifferential &ray) const;
00167 SWCSpectrum Le(const TsPack *tspack, const Vector &wo) const;
00168 SWCSpectrum Le(const TsPack *tspack, const Ray &ray, const Normal &n, BSDF **bsdf, float *pdf, float *pdfDirect) const;
00169
00170 void Set(const Transform& world2object,
00171 const Primitive* prim, const Material* mat,
00172 const AreaLight* areal = NULL)
00173 {
00174 WorldToObject = world2object;
00175 primitive = prim;
00176 material = mat;
00177 arealight = areal;
00178 }
00179
00180 DifferentialGeometry dg;
00181 Transform WorldToObject;
00182 const Primitive *primitive;
00183 const Material *material;
00184 const AreaLight *arealight;
00185 };
00186
00191 class AreaLightPrimitive : public Primitive {
00192 public:
00193
00194 AreaLightPrimitive(boost::shared_ptr<Primitive> prim, AreaLight* arealight);
00195 virtual ~AreaLightPrimitive() { }
00196
00197 virtual BBox WorldBound() const { return prim->WorldBound(); };
00198 virtual void Refine(vector<boost::shared_ptr<Primitive> > &refined,
00199 const PrimitiveRefinementHints& refineHints,
00200 boost::shared_ptr<Primitive> thisPtr);
00201
00202 virtual bool CanIntersect() const { return prim->CanIntersect(); }
00203 virtual bool Intersect(const Ray &r, Intersection *in) const;
00204 virtual bool IntersectP(const Ray &r) const { return prim->IntersectP(r); }
00205
00206 virtual void GetShadingGeometry(const Transform &obj2world,
00207 const DifferentialGeometry &dg, DifferentialGeometry *dgShading) const {
00208 prim->GetShadingGeometry(obj2world, dg, dgShading);
00209 }
00210
00211 virtual bool CanSample() const { return prim->CanSample(); }
00212 virtual float Area() const { return prim->Area(); }
00213 virtual void Sample(float u1, float u2, float u3, DifferentialGeometry *dg) const {
00214 prim->Sample(u1, u2, u3, dg);
00215 }
00216 virtual float Pdf(const Point &p) const { return prim->Pdf(p); }
00217 virtual void Sample(const Point &P,
00218 float u1, float u2, float u3, DifferentialGeometry *dg) const {
00219 prim->Sample(P, u1, u2, u3, dg);
00220 }
00221 virtual float Pdf(const Point &p, const Vector &wi) const {
00222 return prim->Pdf(p, wi);
00223 }
00224 virtual float Pdf(const Point &p, const Point &po) const {
00225 return prim->Pdf(p, po);
00226 }
00227 private:
00228
00229 boost::shared_ptr<Primitive> prim;
00230 AreaLight *areaLight;
00231 };
00232
00239 class InstancePrimitive : public Primitive {
00240 public:
00241
00250 InstancePrimitive(boost::shared_ptr<Primitive> i,
00251 const Transform &i2w,
00252 boost::shared_ptr<Material> mat) {
00253 instance = i;
00254 InstanceToWorld = i2w;
00255 WorldToInstance = i2w.GetInverse();
00256 material = mat;
00257 }
00258 virtual ~InstancePrimitive() { }
00259
00260 virtual BBox WorldBound() const {
00261 return InstanceToWorld(instance->WorldBound());
00262 }
00263
00264 virtual bool CanIntersect() const { return instance->CanIntersect(); }
00265 virtual bool Intersect(const Ray &r, Intersection *in) const;
00266 virtual bool IntersectP(const Ray &r) const;
00267 virtual void GetShadingGeometry(const Transform &obj2world,
00268 const DifferentialGeometry &dg, DifferentialGeometry *dgShading) const;
00269
00270 virtual bool CanSample() const { return instance->CanSample(); }
00271 virtual float Area() const { return instance->Area(); }
00272 virtual void Sample(float u1, float u2, float u3, DifferentialGeometry *dg) const {
00273 instance->Sample(u1, u2, u3, dg);
00274 dg->p = InstanceToWorld(dg->p);
00275 dg->nn = Normalize(InstanceToWorld(dg->nn));
00276 dg->dpdu = InstanceToWorld(dg->dpdu);
00277 dg->dpdv = InstanceToWorld(dg->dpdv);
00278 dg->dndu = InstanceToWorld(dg->dndu);
00279 dg->dndv = InstanceToWorld(dg->dndv);
00280 }
00281 virtual float Pdf(const Point &p) const { return instance->Pdf(p); }
00282 virtual void Sample(const Point &P,
00283 float u1, float u2, float u3, DifferentialGeometry *dg) const {
00284 instance->Sample(WorldToInstance(P), u1, u2, u3, dg);
00285 dg->p = InstanceToWorld(dg->p);
00286 dg->nn = Normalize(InstanceToWorld(dg->nn));
00287 dg->dpdu = InstanceToWorld(dg->dpdu);
00288 dg->dpdv = InstanceToWorld(dg->dpdv);
00289 dg->dndu = InstanceToWorld(dg->dndu);
00290 dg->dndv = InstanceToWorld(dg->dndv);
00291 }
00292 virtual float Pdf(const Point &p, const Vector &wi) const {
00293 return instance->Pdf(p, wi);
00294 }
00295 virtual float Pdf(const Point &p, const Point &po) const {
00296 return instance->Pdf(p, po);
00297 }
00298 private:
00299
00300 boost::shared_ptr<Primitive> instance;
00301 Transform InstanceToWorld, WorldToInstance;
00302 boost::shared_ptr<Material> material;
00303 };
00304
00305 class Aggregate : public Primitive {
00306 public:
00307
00308 virtual ~Aggregate() { }
00309 virtual bool CanIntersect() const { return true; }
00310 virtual bool CanSample() const { return false; }
00311
00316 virtual void GetPrimitives(vector<boost::shared_ptr<Primitive> > &prims) = 0;
00317 };
00318
00319
00326 class MotionPrimitive : public Primitive {
00327 public:
00328
00338 MotionPrimitive(boost::shared_ptr<Primitive> i,
00339 const Transform &i2ws,
00340 const Transform &i2we,
00341 float s, float e )
00342 {
00343 instance = i;
00344 motionSystem = new MotionSystem(s, e, i2ws, i2we);
00345 }
00346 virtual ~MotionPrimitive() { delete motionSystem; }
00347
00348 virtual BBox WorldBound() const;
00349
00350 virtual bool CanIntersect() const { return instance->CanIntersect(); }
00351 virtual bool Intersect(const Ray &r, Intersection *in) const;
00352 virtual bool IntersectP(const Ray &r) const;
00353 virtual void GetShadingGeometry(const Transform &obj2world,
00354 const DifferentialGeometry &dg, DifferentialGeometry *dgShading) const;
00355
00356 virtual bool CanSample() const { return instance->CanSample(); }
00357 virtual float Area() const { return instance->Area(); }
00358 virtual void Sample(float u1, float u2, float u3, DifferentialGeometry *dg) const {
00359 Transform InstanceToWorld = motionSystem->Sample(dg->time);
00360 instance->Sample(u1, u2, u3, dg);
00361 dg->p = InstanceToWorld(dg->p);
00362 dg->nn = Normalize(InstanceToWorld(dg->nn));
00363 dg->dpdu = InstanceToWorld(dg->dpdu);
00364 dg->dpdv = InstanceToWorld(dg->dpdv);
00365 dg->dndu = InstanceToWorld(dg->dndu);
00366 dg->dndv = InstanceToWorld(dg->dndv);
00367 }
00368 virtual float Pdf(const Point &p) const { return instance->Pdf(p); }
00369 virtual void Sample(const Point &P, float u1, float u2, float u3, DifferentialGeometry *dg) const {
00370 Transform InstanceToWorld = motionSystem->Sample(dg->time);
00371 instance->Sample(InstanceToWorld.GetInverse()(P), u1, u2, u3, dg);
00372 dg->p = InstanceToWorld(dg->p);
00373 dg->nn = Normalize(InstanceToWorld(dg->nn));
00374 dg->dpdu = InstanceToWorld(dg->dpdu);
00375 dg->dpdv = InstanceToWorld(dg->dpdv);
00376 dg->dndu = InstanceToWorld(dg->dndu);
00377 dg->dndv = InstanceToWorld(dg->dndv);
00378 }
00379 virtual float Pdf(const Point &p, const Vector &wi) const {
00380 return instance->Pdf(p, wi);
00381 }
00382 virtual float Pdf(const Point &p, const Point &po) const {
00383 return instance->Pdf(p, po);
00384 }
00385 private:
00386
00387 boost::shared_ptr<Primitive> instance;
00388 MotionSystem *motionSystem;
00389 };
00390
00391
00392 }
00393
00394 #endif // LUX_PRIMITIVE_H