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