void NaviHeightmap::update(const vector<IBox> &walkable, const vector<IBox> &blockers) { m_level_count = 0; m_data.clear(); PodArray<IBox> bboxes(walkable.size()); for(int n = 0; n < bboxes.size(); n++) { IBox bbox = walkable[n]; bboxes[n] = { vmax(bbox.min(), int3(0, 0, 0)), vmin(bbox.max(), int3(m_size.x, 255, m_size.y))}; } std::sort(bboxes.data(), bboxes.end(), [](const IBox &a, const IBox &b) { return a.y() == b.y()? a.x() == b.x()? a.z() < b.z() : a.x() < b.x() : a.y() < b.y(); } ); for(int n = 0; n < bboxes.size(); n++) { const IBox &bbox = bboxes[n]; int min_y = bbox.y(), max_y = bbox.ey(); for(int z = 0; z < bbox.depth(); z++) for(int x = 0; x < bbox.width(); x++) { int level = 0; int px = x + bbox.x(); int pz = z + bbox.z(); while(level < m_level_count) { int value = m_data[index(px, pz, level)]; if(value == invalid_value || value >= min_y - 4) break; level++; } if(level == m_level_count) { if(level == max_levels) continue; addLevel(); } m_data[index(px, pz, level)] = max_y; } } for(int n = 0; n < (int)blockers.size(); n++) { IBox blocker( vmax(blockers[n].min(), int3(0, 0, 0)), vmin(blockers[n].max(), int3(m_size.x, 255, m_size.y))); u8 min_y = max(0, blocker.y() - 4), max_y = blocker.ey(); for(int z = 0; z < blocker.depth(); z++) for(int x = 0; x < blocker.width(); x++) { int level = 0; int px = x + blocker.x(); int pz = z + blocker.z(); while(level < m_level_count) { u8 &value = m_data[index(px, pz, level++)]; if(value >= min_y && value <= max_y) value = invalid_value; } } } }
std::vector<MeshTools::BoundingBox> MultiAppTransfer::getFromBoundingBoxes() { std::vector<std::pair<Point, Point> > bb_points(_from_meshes.size()); for (unsigned int i = 0; i < _from_meshes.size(); i++) { // Get a bounding box around the mesh elements that are local to the current // processor. MeshTools::BoundingBox bbox = MeshTools::processor_bounding_box(* _from_meshes[i], processor_id()); // Translate the bounding box to the from domain's position. bbox.first += _from_positions[i]; bbox.second += _from_positions[i]; // Cast the bounding box into a pair of points (so it can be put through // MPI communication). bb_points[i] = static_cast<std::pair<Point, Point> >(bbox); } // Serialize the bounding box points. _communicator.allgather(bb_points); // Recast the points back into bounding boxes and return. std::vector<MeshTools::BoundingBox> bboxes(bb_points.size()); for (unsigned int i = 0; i < bb_points.size(); i++) bboxes[i] = static_cast<MeshTools::BoundingBox>(bb_points[i]); return bboxes; }
vector<FBox> OccluderMap::computeBBoxes(int occluder_id, bool minimize) const { DASSERT(occluder_id >= 0 && occluder_id < size()); const Occluder &occluder = m_occluders[occluder_id]; PodArray<FBox> bboxes(occluder.objects.size()); PodArray<FBox> temp(occluder.objects.size()); int count = (int)occluder.objects.size(), tcount = 0; for(int n = 0; n < count; n++) bboxes[n] = m_grid[occluder.objects[n]].bbox; std::sort(bboxes.data(), bboxes.end(), bboxOrderYXZ); FBox current = bboxes[0]; for(int n = 1; n < count; n++) { FBox next = bboxes[n]; if(current.min.y == next.min.y && current.max.y == next.max.y && current.min.x == next.min.x && current.max.x == next.max.x && current.max.z == next.min.z) current.max.z = next.max.z; else { temp[tcount++] = current; current = next; } } temp[tcount++] = current; bboxes.swap(temp); count = tcount; std::sort(bboxes.data(), bboxes.data() + count, bboxOrderYZX); tcount = 0; current = bboxes[0]; for(int n = 1; n < count; n++) { FBox next = bboxes[n]; if(current.min.y == next.min.y && current.max.y == next.max.y && current.min.z == next.min.z && current.max.z == next.max.z && current.max.x == next.min.x) current.max.x = next.max.x; else { temp[tcount++] = current; current = next; } } temp[tcount++] = current; bboxes.swap(temp); count = tcount; int normal_count = count; // if minimize is true, then bboxes might overlap objects belonging to // occluders with index greater than occluder_id if(minimize) { vector<int> inds; inds.reserve(1024); for(int iters = 0; iters < 16; iters++) { tcount = 0; current = bboxes[0]; for(int n = 0; n < count - 1; n += 2) { FBox merged = sum(bboxes[n], bboxes[n + 1]); inds.clear(); m_grid.findAll(inds, merged); bool can_merge = true; for(int i = 0; i < (int)inds.size(); i++) if(m_grid[inds[i]].occluder_id < occluder_id) { can_merge = false; break; } if(can_merge) temp[tcount++] = merged; else { temp[tcount++] = bboxes[n]; temp[tcount++] = bboxes[n + 1]; } } if(count & 1) temp[tcount++] = bboxes[count - 1]; bboxes.swap(temp); if(tcount == count) break; count = tcount; } } //printf("%5d -> %5d [%5d]\n", (int)occluder.objects.size(), count, normal_count); return vector<FBox>(bboxes.data(), bboxes.data() + count); }