Esempio n. 1
0
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;
				}
			}
	}
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}