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 "volumegrid.h"
00025 #include "paramset.h"
00026 #include "error.h"
00027
00028 using namespace lux;
00029
00030
00031 VolumeGrid::VolumeGrid(const Spectrum &sa,
00032 const Spectrum &ss, float gg,
00033 const Spectrum &emit, const BBox &e,
00034 const Transform &v2w,
00035 int x, int y, int z, const float *d)
00036 : DensityRegion(sa, ss, gg, emit, v2w),
00037 nx(x), ny(y), nz(z), extent(e) {
00038 density = new float[nx*ny*nz];
00039 memcpy(density, d, nx*ny*nz*sizeof(float));
00040 }
00041 float VolumeGrid::Density(const Point &Pobj) const {
00042 if (!extent.Inside(Pobj)) return 0;
00043
00044 float voxx = (Pobj.x - extent.pMin.x) /
00045 (extent.pMax.x - extent.pMin.x) * nx - .5f;
00046 float voxy = (Pobj.y - extent.pMin.y) /
00047 (extent.pMax.y - extent.pMin.y) * ny - .5f;
00048 float voxz = (Pobj.z - extent.pMin.z) /
00049 (extent.pMax.z - extent.pMin.z) * nz - .5f;
00050 int vx = Floor2Int(voxx);
00051 int vy = Floor2Int(voxy);
00052 int vz = Floor2Int(voxz);
00053 float dx = voxx - vx, dy = voxy - vy, dz = voxz - vz;
00054
00055 float d00 = Lerp(dx, D(vx, vy, vz), D(vx+1, vy, vz));
00056 float d10 = Lerp(dx, D(vx, vy+1, vz), D(vx+1, vy+1, vz));
00057 float d01 = Lerp(dx, D(vx, vy, vz+1), D(vx+1, vy, vz+1));
00058 float d11 = Lerp(dx, D(vx, vy+1, vz+1),D(vx+1, vy+1, vz+1));
00059 float d0 = Lerp(dy, d00, d10);
00060 float d1 = Lerp(dy, d01, d11);
00061 return Lerp(dz, d0, d1);
00062 }
00063 VolumeRegion * VolumeGrid::CreateVolumeRegion(const Transform &volume2world,
00064 const ParamSet ¶ms) {
00065
00066 Spectrum sigma_a = params.FindOneSpectrum("sigma_a", 0.);
00067 Spectrum sigma_s = params.FindOneSpectrum("sigma_s", 0.);
00068 float g = params.FindOneFloat("g", 0.);
00069 Spectrum Le = params.FindOneSpectrum("Le", 0.);
00070 Point p0 = params.FindOnePoint("p0", Point(0,0,0));
00071 Point p1 = params.FindOnePoint("p1", Point(1,1,1));
00072 int nitems;
00073 const float *data = params.FindFloat("density", &nitems);
00074 if (!data) {
00075 luxError(LUX_MISSINGDATA,LUX_ERROR,"No \"density\" values provided for volume grid?");
00076 return NULL;
00077 }
00078 int nx = params.FindOneInt("nx", 1);
00079 int ny = params.FindOneInt("ny", 1);
00080 int nz = params.FindOneInt("nz", 1);
00081 if (nitems != nx*ny*nz) {
00082
00083
00084 std::stringstream ss;
00085 ss<<"VolumeGrid has "<<nitems<<" density values but nx*ny*nz = "<<nx*ny*nz;
00086 luxError(LUX_CONSISTENCY,LUX_ERROR,ss.str().c_str());
00087 return NULL;
00088 }
00089 return new VolumeGrid(sigma_a, sigma_s, g, Le, BBox(p0, p1),
00090 volume2world, nx, ny, nz, data);
00091 }