//: Cell Utility functions. #define X_MIN (short4)(1,0,0,0); #define X_MAX (short4)(1,0,0,1); #define Y_MIN (short4)(0,1,0,0); #define Y_MAX (short4)(0,1,0,1); #define Z_MIN (short4)(0,0,1,0); #define Z_MAX (short4)(0,0,1,1); /* uint rgbaFloatToInt(float4 rgba) { rgba.x = clamp(rgba.x,0.0f,1.0f); rgba.y = clamp(rgba.y,0.0f,1.0f); rgba.z = clamp(rgba.z,0.0f,1.0f); rgba.w = clamp(rgba.w,0.0f,1.0f); return ((uint)(rgba.w*255.0f)<<24) | ((uint)(rgba.z*255.0f)<<16) | ((uint)(rgba.y*255.0f)<<8) | (uint)(rgba.x*255.0f); } uint intensityFloatToInt(float intensity) { intensity = clamp(intensity, 0.0f, 1.0f); return ((uint)(intensity*255.0f)<<24) | ((uint)(intensity*255.0f)<<16) | ((uint)(intensity*255.0f)<<8) | (uint)(intensity*255.0f); } */ //--------------------------------------------------------------------- // The vector result for the exit face as a short vector in X, Y, Z // The element corresponding to the exit coordinate has the value 1 // The other coordinate elements are 0. The return has the 'w' element // set to 1 if the result is a max face otherwise if a min face it is 0. // cell_min is the minimum point in the cell and cell_max is the // maximum point in the cell. //--------------------------------------------------------------------- short4 cell_exit_face(float4 exit_point, float4 cell_min, float4 cell_max) { float4 min_diff = fabs(exit_point-cell_min); float4 max_diff = fabs(exit_point-cell_max); float min=1e5f; short4 faceid=(short4)(-1,-1,-1,-1); if (min_diff.x0) { min=max_diff.x; faceid=X_MAX; } if (max_diff.y0) { min=max_diff.y; faceid=Y_MAX; } if (max_diff.z0) { min=max_diff.z; faceid=Z_MAX; } return faceid; } short4 cell_exit_face_but_not_entry_face(float4 exit_point, float4 cell_min, float4 cell_max,short4 entry_face) { float4 min_diff = fabs(exit_point-cell_min); float4 max_diff = fabs(exit_point-cell_max); short4 faceid=(short4) -1; float min=1.0f; // short4 temp; not used at the moment if (min_diff.x(1,1,1) //------------------------------------------------------------------- void cell_bounding_box(short4 loc_code, int n_levels, float4* cell_min, float4* cell_max) { float tree_size = (float)(1<<(n_levels-1)); float cell_size = ((float)(1< largest_tmin; } #endif #if 0 //------------------------------------------------------------------------------ // New Intersect Cell takes in ray origin, ray direction, cell min and cell // dimension (doesn't not assume cubic volume). Doesn't use cell_max // Lots of redundant code - everything here depends on RAY_D //------------------------------------------------------------------------------ #if 0 int intersect_cell(float4 ray_o, float4 ray_d, float4 cell_min, float4 cell_dims, float *tnear, float *tfar) { // compute intersection of ray with all six cell planes float4 tmin = (1.0/ray_d) * (cell_min - ray_o); float4 tmax = (1.0/ray_d) * (cell_min + cell_dims - ray_o); // re-order intersections to find smallest and largest on each axis // minimum t values for either bounding plane float4 tmin_s = min(tmax, tmin); // maximum t values for either bounding plane float4 tmax_s = max(tmax, tmin); if (ray_d.x == 0.0f) { tmin_s.x = -3.4e38f; tmax_s.x = 3.4e38f; } if (ray_d.y == 0.0f) { tmin_s.y = -3.4e38f; tmax_s.y = 3.4e38f; } if (ray_d.z == 0.0f) { tmin_s.z = -3.4e38f; tmax_s.z = 3.4e38f; } // find the largest tmin and the smallest tmax float largest_tmin = max( max(tmin_s.x, tmin_s.y), max(tmin_s.x, tmin_s.z)); float smallest_tmax = min( min(tmax_s.x, tmax_s.y), min(tmax_s.x, tmax_s.z)); *tnear = largest_tmin; *tfar = smallest_tmax; return smallest_tmax > largest_tmin; } #endif //------------------------------------------------------------------------------ // Optimized intersect cell takes in ray origin, ray direction, cell min and cell // dimension (doesn't not assume cubic volume). Doesn't use cell_max // Lots of redundant code - everything here depends on RAY_D //------------------------------------------------------------------------------ int intersect_cell_opt(float4 ray_o, float4 ray_d, float4 ray_d_inv, float4 cell_min, float4 cell_dims, float *tnear, float *tfar) { // compute intersection of ray with all six cell planes float4 tmin = ray_d_inv * (cell_min - ray_o); float4 tmax = tmin + ray_d_inv*cell_dims; //float4 tmax = ray_d_inv * (cell_min + cell_dims - ray_o); // re-order intersections to find smallest and largest on each axis // minimum t values for either bounding plane float4 tmin_s = min(tmax, tmin); // maximum t values for either bounding plane float4 tmax_s = max(tmax, tmin); // find the largest tmin and the smallest tmax float largest_tmin = max( max(tmin_s.x, tmin_s.y), max(tmin_s.x, tmin_s.z)); float smallest_tmax = min( min(tmax_s.x, tmax_s.y), min(tmax_s.x, tmax_s.z)); *tnear = largest_tmin; *tfar = smallest_tmax; return smallest_tmax > largest_tmin; } #endif /* //------------------------------------------------------------------------------ // Intersect scene takes in 3 floats for ray o, ray d, ray d inv //------------------------------------------------------------------------------ void intersect_scene(float ray_ox, float ray_oy, float ray_oz, float ray_dx, float ray_dy, float ray_dz, //float min_fx, float min_fy, float min_fz, //float max_fx, float max_fy, float max_fz, float4 min_face, float4 max_face, float *tnear, float *tfar) { // compute intersection of ray with all six cell planes float4 tmin = ray_d_inv * (cell_min - ray_o); float4 tmax = tmin + ray_d_inv*cell_dims; //float4 tmax = ray_d_inv * (cell_min + cell_dims - ray_o); // re-order intersections to find smallest and largest on each axis // minimum t values for either bounding plane float4 tmin_s = min(tmax, tmin); // maximum t values for either bounding plane float4 tmax_s = max(tmax, tmin); // find the largest tmin and the smallest tmax float largest_tmin = max( max(tmin_s.x, tmin_s.y), max(tmin_s.x, tmin_s.z)); float smallest_tmax = min( min(tmax_s.x, tmax_s.y), min(tmax_s.x, tmax_s.z)); *tnear = largest_tmin; *tfar = smallest_tmax; return smallest_tmax > largest_tmin; } */ //----------------------------------------------------------------------------- // find exit tvalue given an array of exit faces //----------------------------------------------------------------------------- float calc_t_exit(float4 ray_o, float4 ray_d_inv, float4 exit_planes) { float4 tvec = (exit_planes - ray_o) * ray_d_inv; return min(min(tvec.x, tvec.y), tvec.z); } //-------------------------------------------------------------------------- // Find the ray entry point to a box that encloses the entire octree // Returns 0 if there is no intersection. //------------------------------------------------------------------------- int cell_entry_point(float4 ray_org, float4 ray_dir, float4 cell_min, float4 cell_max, float4* entry_pt) { float tnear = 0, tfar =0; int hit = intersect_cell(ray_org, ray_dir, cell_min, cell_max, &tnear, &tfar); if (!hit) { (*entry_pt)=(float4)(-1.0f, -1.0f, -1.0f, -1.0f); return 0; } else { (*entry_pt) = ray_org + tnear*ray_dir; return 1; } } //-------------------------------------------------------------------------- // Find the ray exit point from a cell that is specified by its loc_code // Returns 0 if there is no intersection with the cell //------------------------------------------------------------------------- int cell_exit_point(float4 ray_org, float4 ray_dir, float4 cell_min, float4 cell_max, float4* exit_pt) { float tnear = 0, tfar =0; int hit = intersect_cell(ray_org, ray_dir, cell_min, cell_max, &tnear, &tfar); if (!hit) { (*exit_pt)=(float4)(tnear, tfar, -1.0f, -1.0f); return 0; } else { (*exit_pt) = ray_org + tfar*ray_dir; return 1; } } int cell_contains_exit_pt(int n_levels, short4 loc_code, float4 exit_pt) { exit_pt.w = 0.0f; ///should be no side effects since arg is copied float4 cell_min, cell_max; cell_bounding_box(loc_code, n_levels, &cell_min, &cell_max); int4 test =isless(exit_pt , cell_min); if (any(test)) return 0; test =isgreater(exit_pt , cell_max); if (any(test)) return 0; return 1; }