public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
{
Bounds bounds = o.bounds;
// Bounding rectangle with floating point coordinates
Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);
// Bounding rectangle with int coordinates
var r2 = new IntRect(
Mathf.FloorToInt(bounds.min.x * Int3.Precision),
Mathf.FloorToInt(bounds.min.z * Int3.Precision),
Mathf.FloorToInt(bounds.max.x * Int3.Precision),
Mathf.FloorToInt(bounds.max.z * Int3.Precision)
);
// Corners of the bounding rectangle
var a = new Int3(r2.xmin, 0, r2.ymin);
var b = new Int3(r2.xmin, 0, r2.ymax);
var c = new Int3(r2.xmax, 0, r2.ymin);
var d = new Int3(r2.xmax, 0, r2.ymax);
var ymin = ((Int3)bounds.min).y;
var ymax = ((Int3)bounds.max).y;
// Loop through all nodes
graph.GetNodes(_node => {
var node = _node as TriangleMeshNode;
bool inside = false;
int allLeft = 0;
int allRight = 0;
int allTop = 0;
int allBottom = 0;
// Check bounding box rect in XZ plane
for (int v = 0; v < 3; v++)
{
Int3 p = node.GetVertex(v);
var vert = (Vector3)p;
if (r2.Contains(p.x, p.z))
{
inside = true;
break;
}
if (vert.x < r.xMin)
{
allLeft++;
}
if (vert.x > r.xMax)
{
allRight++;
}
if (vert.z < r.yMin)
{
allTop++;
}
if (vert.z > r.yMax)
{
allBottom++;
}
}
if (!inside)
{
if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)
{
return(true);
}
}
// Check if the polygon edges intersect the bounding rect
for (int v = 0; v < 3; v++)
{
int v2 = v > 1 ? 0 : v + 1;
Int3 vert1 = node.GetVertex(v);
Int3 vert2 = node.GetVertex(v2);
if (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2))
{
inside = true; break;
}
if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2))
{
inside = true; break;
}
if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2))
{
inside = true; break;
}
if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2))
{
inside = true; break;
}
}
// Check if the node contains any corner of the bounding rect
if (inside || node.ContainsPoint(a) || node.ContainsPoint(b) || node.ContainsPoint(c) || node.ContainsPoint(d))
{
inside = true;
}
if (!inside)
{
return(true);
}
int allAbove = 0;
int allBelow = 0;
// Check y coordinate
for (int v = 0; v < 3; v++)
{
Int3 p = node.GetVertex(v);
if (p.y < ymin)
{
allBelow++;
}
if (p.y > ymax)
{
allAbove++;
}
}
// Polygon is either completely above the bounding box or completely below it
if (allBelow == 3 || allAbove == 3)
{
return(true);
}
// Triangle is inside the bounding box!
// Update it!
o.WillUpdateNode(node);
o.Apply(node);
return(true);
});
}