Example #1
0
// Returns true if fragments have been inserted into the given ret_fragments list
bool Brush_subtract(const BrushNodePtr& brush, const Brush& other, BrushPtrVector& ret_fragments)
{
	if (brush->getBrush().localAABB().intersects(other.localAABB()))
	{
		BrushPtrVector fragments;
		fragments.reserve(other.getNumFaces());

		BrushNodePtr back = std::dynamic_pointer_cast<BrushNode>(brush->clone());

		for (Brush::const_iterator i(other.begin()); i != other.end(); ++i)
		{
			const Face& face = *(*i);

			if (!face.contributes()) continue;

			BrushSplitType split = Brush_classifyPlane(back->getBrush(), face.plane3());

			if (split.counts[ePlaneFront] != 0 && split.counts[ePlaneBack] != 0)
			{
				fragments.push_back(std::dynamic_pointer_cast<BrushNode>(back->clone()));

				FacePtr newFace = fragments.back()->getBrush().addFace(face);

				if (newFace != 0)
				{
					newFace->flipWinding();
				}

				back->getBrush().addFace(face);
			}
			else if (split.counts[ePlaneBack] == 0)
			{
				return false;
			}
		}

		ret_fragments.insert(ret_fragments.end(), fragments.begin(), fragments.end());
		return true;
	}

	return false;
}