1//: Cell Utility functions. 2#define X_MIN (short4)(1,0,0,0); 3#define X_MAX (short4)(1,0,0,1); 4#define Y_MIN (short4)(0,1,0,0); 5#define Y_MAX (short4)(0,1,0,1); 6#define Z_MIN (short4)(0,0,1,0); 7#define Z_MAX (short4)(0,0,1,1); 8 9/* 10uint rgbaFloatToInt(float4 rgba) 11{ 12 rgba.x = clamp(rgba.x,0.0f,1.0f); 13 rgba.y = clamp(rgba.y,0.0f,1.0f); 14 rgba.z = clamp(rgba.z,0.0f,1.0f); 15 rgba.w = clamp(rgba.w,0.0f,1.0f); 16 return ((uint)(rgba.w*255.0f)<<24) | ((uint)(rgba.z*255.0f)<<16) | ((uint)(rgba.y*255.0f)<<8) | (uint)(rgba.x*255.0f); 17} 18 19uint intensityFloatToInt(float intensity) 20{ 21 intensity = clamp(intensity, 0.0f, 1.0f); 22 return ((uint)(intensity*255.0f)<<24) | ((uint)(intensity*255.0f)<<16) | ((uint)(intensity*255.0f)<<8) | (uint)(intensity*255.0f); 23} 24*/ 25 26//--------------------------------------------------------------------- 27// The vector result for the exit face as a short vector in X, Y, Z 28// The element corresponding to the exit coordinate has the value 1 29// The other coordinate elements are 0. The return has the 'w' element 30// set to 1 if the result is a max face otherwise if a min face it is 0. 31// cell_min is the minimum point in the cell and cell_max is the 32// maximum point in the cell. 33//--------------------------------------------------------------------- 34short4 cell_exit_face(float4 exit_point, float4 cell_min, float4 cell_max) 35{ 36 float4 min_diff = fabs(exit_point-cell_min); 37 float4 max_diff = fabs(exit_point-cell_max); 38 39 float min=1e5f; 40 short4 faceid=(short4)(-1,-1,-1,-1); 41 if (min_diff.x<min) 42 { 43 min=min_diff.x; 44 faceid=X_MIN; 45 } 46 if (min_diff.y<min) 47 { 48 min=min_diff.y; 49 faceid=Y_MIN; 50 } 51 if (min_diff.z<min) 52 { 53 min=min_diff.z; 54 faceid=Z_MIN; 55 } 56 if (max_diff.x<min) 57 { 58 min=max_diff.x; 59 faceid=X_MAX; 60 } 61 if (max_diff.y<min) 62 { 63 min=max_diff.y; 64 faceid=Y_MAX; 65 } 66 if (max_diff.z<min) 67 { 68 min=max_diff.z; 69 faceid=Z_MAX; 70 } 71 72 return faceid; 73} 74 75short4 cell_exit_face_safe(float4 exit_point,float4 ray_d, float4 cell_min, float4 cell_max) 76{ 77 float4 min_diff = fabs(exit_point-cell_min); 78 float4 max_diff = fabs(exit_point-cell_max); 79 80 float min=1e5f; 81 short4 faceid=(short4)(-1,-1,-1,-1); 82 if (min_diff.x<min && ray_d.x<0) 83 { 84 min=min_diff.x; 85 faceid=X_MIN; 86 } 87 if (min_diff.y<min && ray_d.y<0) 88 { 89 min=min_diff.y; 90 faceid=Y_MIN; 91 } 92 if (min_diff.z<min && ray_d.z<0) 93 { 94 min=min_diff.z; 95 faceid=Z_MIN; 96 } 97 if (max_diff.x<min && ray_d.x>0) 98 { 99 min=max_diff.x; 100 faceid=X_MAX; 101 } 102 if (max_diff.y<min&& ray_d.y>0) 103 { 104 min=max_diff.y; 105 faceid=Y_MAX; 106 } 107 if (max_diff.z<min&& ray_d.z>0) 108 { 109 min=max_diff.z; 110 faceid=Z_MAX; 111 } 112 113 return faceid; 114} 115 116short4 cell_exit_face_but_not_entry_face(float4 exit_point, float4 cell_min, float4 cell_max,short4 entry_face) 117{ 118 float4 min_diff = fabs(exit_point-cell_min); 119 float4 max_diff = fabs(exit_point-cell_max); 120 121 short4 faceid=(short4) -1; 122 123 float min=1.0f; 124 125 // short4 temp; not used at the moment 126 if (min_diff.x<min) 127 { 128 if (!(entry_face.x==1 && entry_face.w==0 )) 129 { 130 min=min_diff.x; 131 faceid=X_MIN; 132 } 133 } 134 if (min_diff.y<min ) 135 { 136 if (!(entry_face.y==1 && entry_face.w==0 )) 137 { 138 min=min_diff.y; 139 faceid=Y_MIN; 140 } 141 } 142 if (min_diff.z<min) 143 { 144 if (!(entry_face.z==1 && entry_face.w==0 )) 145 { 146 min=min_diff.z; 147 faceid=Z_MIN; 148 } 149 } 150 if (max_diff.x<min ) 151 { 152 if (!(entry_face.x==1 && entry_face.w==1 )) 153 { 154 min=max_diff.x; 155 faceid=X_MAX; 156 } 157 } 158 if (max_diff.y<min ) 159 { 160 if (!(entry_face.y==1 && entry_face.w==1 )) 161 { 162 min=max_diff.y; 163 faceid=Y_MAX; 164 } 165 } 166 if (max_diff.z<min ) 167 { 168 if (!(entry_face.z==1 && entry_face.w==1 )) 169 { 170 min=max_diff.z; 171 faceid=Z_MAX; 172 } 173 } 174 175 return faceid; 176} 177 178//------------------------------------------------------------------- 179// Given the location code determine the bounding box for the 180// cell in local tree coordinates, i.e. the max bounds of the 181// tree are (0,0,0)->(1,1,1) 182//------------------------------------------------------------------- 183void cell_bounding_box(short4 loc_code, int n_levels, 184 float4* cell_min, float4* cell_max) 185{ 186 float tree_size = (float)(1<<(n_levels-1)); 187 float cell_size = ((float)(1<<loc_code.w))/tree_size; 188 float4 rtsize = (float4)(1.0f/tree_size); 189 (*cell_min) = convert_float4(loc_code); 190 (*cell_min) *= rtsize; 191 float4 csize = (float4)cell_size; 192 (*cell_max) = (*cell_min) + csize; 193 (*cell_min).w = 0.0f; (*cell_max).w = 0.0f; 194} 195 196 197#if 1 198//-------------------------------------------------------------------------- 199// Given the ray origin, ray_o and its direction, ray_d and the cell min 200// and max points, find the ray parameters, tnear and tfar that correspond 201// to the entry and exit points of the cell-ray intersection. If the ray 202// does not intersect the cell, 0 is returned. 203//------------------------------------------------------------------------- 204int intersect_cell(float4 ray_o, float4 ray_d, float4 cell_min, float4 cell_max, float *tnear, float *tfar) 205{ 206 // compute intersection of ray with all six cell planes 207 float4 invR = (float4)(1.0f,1.0f,1.0f,1.0f) / ray_d; 208 209 float4 tmin = invR * (cell_min - ray_o); 210 float4 tmax = invR * (cell_max - ray_o); 211 212 // re-order intersections to find smallest and largest on each axis 213 // minimum t values for either bounding plane 214 float4 tmin_s = min(tmax, tmin); 215 // maximum t values for either bounding plane 216 float4 tmax_s = max(tmax, tmin); 217 218 if (ray_d.x ==0.0f) { 219 tmin_s.x = -3.4e38f; 220 tmax_s.x = 3.4e38f; 221 } 222 if (ray_d.y ==0.0f) { 223 tmin_s.y = -3.4e38f; 224 tmax_s.y = 3.4e38f; 225 } 226 if (ray_d.z ==0.0f) { 227 tmin_s.z = -3.4e38f; 228 tmax_s.z = 3.4e38f; 229 } 230 231 // find the largest tmin and the smallest tmax 232 float largest_tmin = max( max(tmin_s.x, tmin_s.y), max(tmin_s.x, tmin_s.z)); 233 float smallest_tmax = min( min(tmax_s.x, tmax_s.y), min(tmax_s.x, tmax_s.z)); 234 *tnear = largest_tmin; 235 *tfar = smallest_tmax; 236 return smallest_tmax > largest_tmin; 237} 238#endif 239 240#if 0 241//------------------------------------------------------------------------------ 242// New Intersect Cell takes in ray origin, ray direction, cell min and cell 243// dimension (doesn't not assume cubic volume). Doesn't use cell_max 244// Lots of redundant code - everything here depends on RAY_D 245//------------------------------------------------------------------------------ 246#if 0 247int intersect_cell(float4 ray_o, float4 ray_d, float4 cell_min, float4 cell_dims, float *tnear, float *tfar) 248{ 249 // compute intersection of ray with all six cell planes 250 float4 tmin = (1.0/ray_d) * (cell_min - ray_o); 251 float4 tmax = (1.0/ray_d) * (cell_min + cell_dims - ray_o); 252 253 // re-order intersections to find smallest and largest on each axis 254 // minimum t values for either bounding plane 255 float4 tmin_s = min(tmax, tmin); 256 // maximum t values for either bounding plane 257 float4 tmax_s = max(tmax, tmin); 258 259 if (ray_d.x == 0.0f) { 260 tmin_s.x = -3.4e38f; 261 tmax_s.x = 3.4e38f; 262 } 263 if (ray_d.y == 0.0f) { 264 tmin_s.y = -3.4e38f; 265 tmax_s.y = 3.4e38f; 266 } 267 if (ray_d.z == 0.0f) { 268 tmin_s.z = -3.4e38f; 269 tmax_s.z = 3.4e38f; 270 } 271 272 // find the largest tmin and the smallest tmax 273 float largest_tmin = max( max(tmin_s.x, tmin_s.y), max(tmin_s.x, tmin_s.z)); 274 float smallest_tmax = min( min(tmax_s.x, tmax_s.y), min(tmax_s.x, tmax_s.z)); 275 *tnear = largest_tmin; 276 *tfar = smallest_tmax; 277 return smallest_tmax > largest_tmin; 278} 279#endif 280//------------------------------------------------------------------------------ 281// Optimized intersect cell takes in ray origin, ray direction, cell min and cell 282// dimension (doesn't not assume cubic volume). Doesn't use cell_max 283// Lots of redundant code - everything here depends on RAY_D 284//------------------------------------------------------------------------------ 285int intersect_cell_opt(float4 ray_o, float4 ray_d, float4 ray_d_inv, float4 cell_min, float4 cell_dims, float *tnear, float *tfar) 286{ 287 288 // compute intersection of ray with all six cell planes 289 float4 tmin = ray_d_inv * (cell_min - ray_o); 290 float4 tmax = tmin + ray_d_inv*cell_dims; 291 //float4 tmax = ray_d_inv * (cell_min + cell_dims - ray_o); 292 293 // re-order intersections to find smallest and largest on each axis 294 // minimum t values for either bounding plane 295 float4 tmin_s = min(tmax, tmin); 296 // maximum t values for either bounding plane 297 float4 tmax_s = max(tmax, tmin); 298 299 // find the largest tmin and the smallest tmax 300 float largest_tmin = max( max(tmin_s.x, tmin_s.y), max(tmin_s.x, tmin_s.z)); 301 float smallest_tmax = min( min(tmax_s.x, tmax_s.y), min(tmax_s.x, tmax_s.z)); 302 *tnear = largest_tmin; 303 *tfar = smallest_tmax; 304 return smallest_tmax > largest_tmin; 305} 306#endif 307 308 309/* 310//------------------------------------------------------------------------------ 311// Intersect scene takes in 3 floats for ray o, ray d, ray d inv 312//------------------------------------------------------------------------------ 313void intersect_scene(float ray_ox, float ray_oy, float ray_oz, 314 float ray_dx, float ray_dy, float ray_dz, 315 //float min_fx, float min_fy, float min_fz, 316 //float max_fx, float max_fy, float max_fz, 317 float4 min_face, float4 max_face, 318 float *tnear, float *tfar) 319{ 320 321 // compute intersection of ray with all six cell planes 322 float4 tmin = ray_d_inv * (cell_min - ray_o); 323 float4 tmax = tmin + ray_d_inv*cell_dims; 324 //float4 tmax = ray_d_inv * (cell_min + cell_dims - ray_o); 325 326 // re-order intersections to find smallest and largest on each axis 327 // minimum t values for either bounding plane 328 float4 tmin_s = min(tmax, tmin); 329 // maximum t values for either bounding plane 330 float4 tmax_s = max(tmax, tmin); 331 332 // find the largest tmin and the smallest tmax 333 float largest_tmin = max( max(tmin_s.x, tmin_s.y), max(tmin_s.x, tmin_s.z)); 334 float smallest_tmax = min( min(tmax_s.x, tmax_s.y), min(tmax_s.x, tmax_s.z)); 335 *tnear = largest_tmin; 336 *tfar = smallest_tmax; 337 return smallest_tmax > largest_tmin; 338} 339*/ 340 341 342//----------------------------------------------------------------------------- 343// find exit tvalue given an array of exit faces 344//----------------------------------------------------------------------------- 345float calc_t_exit(float4 ray_o, float4 ray_d_inv, float4 exit_planes) 346{ 347 float4 tvec = (exit_planes - ray_o) * ray_d_inv; 348 return min(min(tvec.x, tvec.y), tvec.z); 349} 350 351//-------------------------------------------------------------------------- 352// Find the ray entry point to a box that encloses the entire octree 353// Returns 0 if there is no intersection. 354//------------------------------------------------------------------------- 355int cell_entry_point(float4 ray_org, float4 ray_dir, 356 float4 cell_min, float4 cell_max, float4* entry_pt) 357{ 358 float tnear = 0, tfar =0; 359 int hit = intersect_cell(ray_org, ray_dir, cell_min, cell_max, 360 &tnear, &tfar); 361 if (!hit) { 362 (*entry_pt)=(float4)(-1.0f, -1.0f, -1.0f, -1.0f); 363 return 0; 364 } 365 else { 366 (*entry_pt) = ray_org + tnear*ray_dir; 367 return 1; 368 } 369} 370 371//-------------------------------------------------------------------------- 372// Find the ray exit point from a cell that is specified by its loc_code 373// Returns 0 if there is no intersection with the cell 374//------------------------------------------------------------------------- 375 376int cell_exit_point(float4 ray_org, float4 ray_dir, 377 float4 cell_min, float4 cell_max, float4* exit_pt) 378{ 379 float tnear = 0, tfar =0; 380 int hit = intersect_cell(ray_org, ray_dir, cell_min, cell_max, 381 &tnear, &tfar); 382 if (!hit) { 383 (*exit_pt)=(float4)(tnear, tfar, -1.0f, -1.0f); 384 return 0; 385 } 386 else { 387 (*exit_pt) = ray_org + tfar*ray_dir; 388 return 1; 389 } 390} 391 392int cell_contains_exit_pt(int n_levels, short4 loc_code, float4 exit_pt) 393{ 394 exit_pt.w = 0.0f; ///should be no side effects since arg is copied 395 float4 cell_min, cell_max; 396 cell_bounding_box(loc_code, n_levels, &cell_min, &cell_max); 397 int4 test =isless(exit_pt , cell_min); 398 if (any(test)) return 0; 399 test =isgreater(exit_pt , cell_max); 400 if (any(test)) return 0; 401 return 1; 402} 403 404