/// <summary> /// Calculates the bounding box for a set of bounding boxes. /// </summary> /// <param name="items">The list of all the bounding boxes.</param> /// <param name="minIndex">The first bounding box in the list to get the extends of.</param> /// <param name="maxIndex">The last bounding box in the list to get the extends of.</param> /// <param name="bounds">The extends of all the bounding boxes.</param> private static void CalcExtends(List <Node> items, int minIndex, int maxIndex, out PolyBounds bounds) { bounds = items[minIndex].Bounds; for (int i = minIndex + 1; i < maxIndex; i++) { Node it = items[i]; PolyVertex.ComponentMin(ref it.Bounds.Min, ref bounds.Min, out bounds.Min); PolyVertex.ComponentMax(ref it.Bounds.Max, ref bounds.Max, out bounds.Max); } }
/// <summary> /// Find all the polygons within a certain bounding box. /// </summary> /// <param name="tile">Current tile</param> /// <param name="qbounds">The bounds</param> /// <param name="polys">List of polygons</param> /// <returns>Number of polygons found</returns> public int QueryPolygons(BBox3 qbounds, List <NavPolyId> polys) { if (BVTree.Count != 0) { int node = 0; int end = BvNodeCount; Vector3 tbmin = Bounds.Min; Vector3 tbmax = Bounds.Max; //Clamp query box to world box Vector3 qbmin = qbounds.Min; Vector3 qbmax = qbounds.Max; PolyBounds b; float bminx = MathHelper.Clamp(qbmin.X, tbmin.X, tbmax.X) - tbmin.X; float bminy = MathHelper.Clamp(qbmin.Y, tbmin.Y, tbmax.Y) - tbmin.Y; float bminz = MathHelper.Clamp(qbmin.Z, tbmin.Z, tbmax.Z) - tbmin.Z; float bmaxx = MathHelper.Clamp(qbmax.X, tbmin.X, tbmax.X) - tbmin.X; float bmaxy = MathHelper.Clamp(qbmax.Y, tbmin.Y, tbmax.Y) - tbmin.Y; float bmaxz = MathHelper.Clamp(qbmax.Z, tbmin.Z, tbmax.Z) - tbmin.Z; const int MinMask = unchecked ((int)0xfffffffe); b.Min.X = (int)(bminx * BvQuantFactor) & MinMask; b.Min.Y = (int)(bminy * BvQuantFactor) & MinMask; b.Min.Z = (int)(bminz * BvQuantFactor) & MinMask; b.Max.X = (int)(bmaxx * BvQuantFactor + 1) | 1; b.Max.Y = (int)(bmaxy * BvQuantFactor + 1) | 1; b.Max.Z = (int)(bmaxz * BvQuantFactor + 1) | 1; //traverse tree while (node < end) { BVTree.Node bvNode = BVTree[node]; bool overlap = PolyBounds.Overlapping(ref b, ref bvNode.Bounds); bool isLeafNode = bvNode.Index >= 0; if (isLeafNode && overlap) { NavPolyId polyRef; idManager.SetPolyIndex(ref baseRef, bvNode.Index, out polyRef); polys.Add(polyRef); } if (overlap || isLeafNode) { node++; } else { int escapeIndex = -bvNode.Index; node += escapeIndex; } } return(polys.Count); } else { BBox3 b; for (int i = 0; i < PolyCount; i++) { var poly = Polys[i]; //don't return off-mesh connection polygons if (poly.PolyType == NavPolyType.OffMeshConnection) { continue; } //calculate polygon bounds b.Max = b.Min = Verts[poly.Verts[0]]; for (int j = 1; j < poly.VertCount; j++) { Vector3 v = Verts[poly.Verts[j]]; Vector3Extensions.ComponentMin(ref b.Min, ref v, out b.Min); Vector3Extensions.ComponentMax(ref b.Max, ref v, out b.Max); } if (BBox3.Overlapping(ref qbounds, ref b)) { NavPolyId polyRef; idManager.SetPolyIndex(ref baseRef, i, out polyRef); polys.Add(polyRef); } } return(polys.Count); } }