5KZF63OICCGFAZ5E3TRS5GKZJLKQYWLGKOA7IYV4X3C6AOXB4MMAC BEBIJRW2J3ZMUXNK7ZTKUXY6KDXZVTACUSB5XCBRN5Z3TNG6QNQAC ON4ZQE4HSC2FJXEQZ5FAASYDAD46SD6FMHBCGL2KKDF34DFMVFHAC QWRLAVPB4UM3B7OSNEJYN5L72NZQQBNLCM2OLOIBA6OD7IC6JW4AC ACZYEIX7WMPIIODKCATBCUE626AJ4ZGGBOMVC6BGXM27EQU2RECAC YGPAMROCZY2O2N4PJONW6NMFUNOFHAGT5ZA4APCXKFXQUHLEIN2AC WY3Q6JZ3HTBF2CYFJOUVG4MMFINBK4PI2DJ625CVKMJ5BPMXAW2AC PHJ2TT2CQ2IRXOB5KAV2664KKTPYFPFUIBEGAOQBGB4SAZ7PKNHAC ICVDXXH2Z5MV7BLYVWQNLQSV63THIB4E6NVORIDBB7D6TBEHBXOAC RGO2JV5HFKZFXO7KJWDXGDMNBR6NIAOMJW34NHRTLLVN2N7XGW7QC 2EBEWIV4YHXXAFR4GG2GMZJ2K77NK762HNQ77CZLHI3LDVGX7RJAC // These store certain unique subsequences of ray_coords.// Filled during precomputation (_create_blockrays)std::vector<coord_def> compressed_ray;// 3D bit array indexed by coordinate and cellray index.// Bit los_blockrays[x][y][i] is set iff a wall at (x,y) blocks// the cellray starting at compressed_ray[i].
// These store all unique minimal cellrays. For each i,// cellray i ends in cellray_ends[i] and passes through// thoses cells p that have blockrays(p)[i] set. In other// words, blockrays(p)[i] is set iff an opaque cell p blocks// the cellray with index i.std::vector<coord_def> cellray_ends;
// determine nonduplicated raysstd::vector<int> nondupe_cellrays = _find_nonduped_cellrays();const int num_nondupe_rays = nondupe_cellrays.size();const int num_cellrays = ray_coords.size();blockrays_t full_los_blockrays;
// First, we calculate blocking information for all cell rays.// Cellrays are numbered according to the index of their end// cell in ray_coords.const int n_cellrays = ray_coords.size();blockrays_t all_blockrays;
// we want to only keep the cellrays from nondupe_cellrays.compressed_ray.resize(num_nondupe_rays);for (int i = 0; i < num_nondupe_rays; ++i)compressed_ray[i] = ray_coords[nondupe_cellrays[i]];
// Determine nonduplicated rays and store their end points.std::vector<int> nondupe_cellrays = _find_nonduped_cellrays();const int n_nondupe_rays = nondupe_cellrays.size();cellray_ends.resize(n_nondupe_rays);for (int i = 0; i < n_nondupe_rays; ++i)cellray_ends[i] = ray_coords[nondupe_cellrays[i]];
for (int i = 0; i < num_nondupe_rays; ++i)los_blockrays(*qi)->set(i, full_los_blockrays(*qi)->get(nondupe_cellrays[i]));
{blockrays(*qi) = new bit_array(n_nondupe_rays);for (int i = 0; i < n_nondupe_rays; ++i)blockrays(*qi)->set(i, all_blockrays(*qi)->get(nondupe_cellrays[i]));}
// block rays which have already seen a cloud*dead_rays |= (*smoke_rays & *los_blockrays(*qi));*smoke_rays |= *los_blockrays(*qi);
// Block rays which have already seen a cloud.*dead_rays |= (*smoke_rays & *blockrays(*qi));*smoke_rays |= *blockrays(*qi);
// this ray is alive!const coord_def p = coord_def(sx * compressed_ray[rayidx].x,sy * compressed_ray[rayidx].y);// update shadow map
// This ray is alive, thus the end cell is visible.const coord_def p = coord_def(sx * cellray_ends[rayidx].x,sy * cellray_ends[rayidx].y);