/* ============================ R_ShadowBounds Even though the extruded shadows are drawn projected to infinity, their effects are limited to a fraction of the light's volume. An extruded box would require 12 faces to specify and be a lot of trouble, but an axial bounding box is quick and easy to determine. If the light is completely contained in the view, there is no value in trying to cull the shadows, as they will all pass. Pure function. ============================ */ void R_ShadowBounds( const idBounds& modelBounds, const idBounds& lightBounds, const idVec3& lightOrigin, idBounds& shadowBounds ) { for( int i = 0; i < 3; i++ ) { shadowBounds[0][i] = __fsels( modelBounds[0][i] - lightOrigin[i], modelBounds[0][i], lightBounds[0][i] ); shadowBounds[1][i] = __fsels( lightOrigin[i] - modelBounds[1][i], modelBounds[1][i], lightBounds[1][i] ); } }
inline float getnearestsample(float x, float y, float z) { // map x, y, z to volumetric data indices vector3f xyz = {{x}, {y}, {z}}; // volume dimensions int vw = volume.localdims.w; int vh = volume.localdims.h; int vd = volume.localdims.d; #ifdef BGQ float fvw = volume.fvoldims.x; float fvh = volume.fvoldims.y; float fvd = volume.fvoldims.z; float rfvw = volume.rfvoldims.x; float rfvh = volume.rfvoldims.y; float rfvd = volume.rfvoldims.z; float fj = __frizs (x * fvw/aabb.w - (aabb.min.x*fvw)/aabb.w); float fi = __frizs (y * fvh/aabb.h - (aabb.min.y*fvh)/aabb.h); float fk = __frizs (z * fvd/aabb.d - (aabb.min.z*fvd)/aabb.d); fj = __fsels((fj - (fvw-2.0f)), fvw-2.0f, fj); fi = __fsels((fi - (fvh-2.0f)), fvh-2.0f, fi); fk = __fsels((fk - (fvd-1.0f)), fvd-1.0f, fk); int i = (int) fi; int j = (int) fj; int k = (int) fk; PRINTDEBUG2("IJK: %d,%d,%d\n", i,j,k); #else // number of voxels in each direction and should be set when volume is input // mapping should be (volr-voll)/(box.r-box.l) + (aabb.x*vw/bboxw float ratio = (xyz.x-aabb.min.x)/aabb.w; int j = vw * ratio; ratio = (xyz.y-aabb.min.y)/aabb.h; int i = vh * ratio; ratio = (xyz.z-aabb.min.z)/aabb.d; int k = vd * ratio; i = (i >= vh-2) ? vh-2 : i; j = (j >= vw-2) ? vw-2 : j; k = (k >= vd-2) ? vd-2 : k; #endif // get nearest neighboring voxels float c; c = *(volume.data.i + maptoffset3d(i, j, k, vw, vh, vd)); return c; }
float copysignf ( float x, float y ) { double pos_x, neg_x; double pos_y, neg_y; float t; pos_x = __fabs(x); neg_x = __fnabs(x); pos_y = __fabs(y); neg_y = __fnabs(y); if (unlikely(pos_y == neg_y)) return __copysignf_MEM(x, y); if (unlikely(y != y)) return __copysignf_MEM(x, y); t = __fsels(y, pos_x, neg_x); return t; }
inline float getlinearsample(float x, float y, float z) { float x0, y0, z0, xd, yd, zd, xp, yp, zp; // map x, y, z to volumetric data indices vector3f xyz = {{x}, {y}, {z}}; // volume dimensions int vw = volume.localdims.w; int vh = volume.localdims.h; int vd = volume.localdims.d; #ifdef BGQ float fvw = volume.fvoldims.x; float fvh = volume.fvoldims.y; float fvd = volume.fvoldims.z; float rfvw = volume.rfvoldims.x; float rfvh = volume.rfvoldims.y; float rfvd = volume.rfvoldims.z; float fj = __frizs (x * fvw/aabb.w - (aabb.min.x*fvw)/aabb.w); float fi = __frizs (y * fvh/aabb.h - (aabb.min.y*fvh)/aabb.h); float fk = __frizs (z * fvd/aabb.d - (aabb.min.z*fvd)/aabb.d); fj = __fsels((fj - (fvw-2.0f)), fvw-2.0f, fj); fi = __fsels((fi - (fvh-2.0f)), fvh-2.0f, fi); fk = __fsels((fk - (fvd-2.0f)), fvd-2.0f, fk); int i = (int) fi; int j = (int) fj; int k = (int) fk; PRINTDEBUG2("IJK: %d,%d,%d\n", i,j,k); #else // number of voxels in each direction and should be set when volume is input // mapping should be (volr-voll)/(box.r-box.l) + (aabb.x*vw/bboxw float ratio = (xyz.x-aabb.min.x)/aabb.w; int j = vw * ratio; ratio = (xyz.y-aabb.min.y)/aabb.h; int i = vh * ratio; ratio = (xyz.z-aabb.min.z)/aabb.d; int k = vd * ratio; i = (i > vh-2) ? vh-2 : i; j = (j > vw-2) ? vw-2 : j; k = (k > vd-2) ? vd-2 : k; #endif // get 8 neighboring voxels float v000, v100, v010, v001, v101, v011, v110, v111; v000 = *(volume.data.f + maptoffset3d(i, j, k, vw, vh, vd)); v100 = *(volume.data.f + maptoffset3d(i+1, j, k, vw, vh, vd)); v010 = *(volume.data.f + maptoffset3d(i, j+1, k, vw, vh, vd)); v001 = *(volume.data.f + maptoffset3d(i, j, k+1, vw, vh, vd)); v101 = *(volume.data.f + maptoffset3d(i+1, j, k+1, vw, vh, vd)); v011 = *(volume.data.f + maptoffset3d(i, j+1, k+1, vw, vh, vd)); v110 = *(volume.data.f + maptoffset3d(i+1, j+1, k, vw, vh, vd)); v111 = *(volume.data.f + maptoffset3d(i+1, j+1, k+1, vw, vh, vd)); // tri-linear interpolation; I should pre-compute x0, y0, z0 for each cell probably // map to 0..aabb->max xp = x + fabs(aabb.min.x); yp = y + fabs(aabb.min.y); zp = z + fabs(aabb.min.z); #ifdef BGQ x0 = (fj * aabb.w) * rfvw; y0 = (fi * aabb.h) * rfvh; z0 = (fk * aabb.d) * rfvd; xd = (__fabss(xp - x0) * aabb.w) * rfvw; yd = (__fabss(yp - y0) * aabb.h) * rfvh; zd = (__fabss(zp - z0) * aabb.d) * rfvd; #else x0 = (j * aabb.w)/vw; y0 = (i * aabb.h)/vh; z0 = (k * aabb.d)/vd; xd = (fabsf(xp - x0) * aabb.w)/vw; yd = (fabsf(yp - y0) * aabb.h)/vh; zd = (fabsf(zp - z0) * aabb.d)/vd; #endif float c00 = v000 * (1.0f - xd) + v100 * xd; float c10 = v010 * (1.0f - xd) + v110 * xd; float c01 = v001 * (1.0f - xd) + v101 * xd; float c11 = v011 * (1.0f - xd) + v111 * xd; float c0 = c00 * (1.0f - yd) + c10 * yd; float c1 = c01 * (1.0f - yd) + c11 * yd; float c = c0 * (1.0f - zd) + c1 * zd; return c; }