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 "volume.h"
00026
00027 class ExponentialDensity : public DensityRegion {
00028 public:
00029
00030 ExponentialDensity(const Spectrum &sa, const Spectrum &ss,
00031 float gg, const Spectrum &emit, const BBox &e,
00032 const Transform &v2w, float aa, float bb,
00033 const Vector &up)
00034 : DensityRegion(sa, ss, gg, emit, v2w),
00035 extent(e), a(aa), b(bb) {
00036 upDir = Normalize(up);
00037 }
00038 BBox WorldBound() const { return WorldToVolume.GetInverse()(extent); }
00039 bool IntersectP(const Ray &r, float *t0, float *t1) const {
00040 Ray ray = WorldToVolume(r);
00041 return extent.IntersectP(ray, t0, t1);
00042 }
00043 float Density(const Point &Pobj) const {
00044 if (!extent.Inside(Pobj)) return 0;
00045 float height = Dot(Pobj - extent.pMin, upDir);
00046 return a * expf(-b * height);
00047 }
00048 private:
00049
00050 BBox extent;
00051 float a, b;
00052 Vector upDir;
00053 };
00054
00055 extern "C" DLLEXPORT VolumeRegion *CreateVolumeRegion(const Transform &volume2world,
00056 const ParamSet ¶ms) {
00057
00058 Spectrum sigma_a = params.FindOneSpectrum("sigma_a", 0.);
00059 Spectrum sigma_s = params.FindOneSpectrum("sigma_s", 0.);
00060 float g = params.FindOneFloat("g", 0.);
00061 Spectrum Le = params.FindOneSpectrum("Le", 0.);
00062 Point p0 = params.FindOnePoint("p0", Point(0,0,0));
00063 Point p1 = params.FindOnePoint("p1", Point(1,1,1));
00064 float a = params.FindOneFloat("a", 1.);
00065 float b = params.FindOneFloat("b", 1.);
00066 Vector up = params.FindOneVector("updir", Vector(0,1,0));
00067 return new ExponentialDensity(sigma_a, sigma_s, g, Le, BBox(p0, p1),
00068 volume2world, a, b, up);
00069 }