public static void CalcExtends(BVItem[] items, int nitems, int imin, int imax, out Int3 bmin, out Int3 bmax) { bmin.X = items[imin].BMin.X; bmin.Y = items[imin].BMin.Y; bmin.Z = items[imin].BMin.Z; bmax.X = items[imin].BMax.X; bmax.Y = items[imin].BMax.Y; bmax.Z = items[imin].BMax.Z; for (int i = imin + 1; i < imax; ++i) { BVItem it = items[i]; if (it.BMin.X < bmin.X) { bmin.X = it.BMin.X; } if (it.BMin.Y < bmin.Y) { bmin.Y = it.BMin.Y; } if (it.BMin.Z < bmin.Z) { bmin.Z = it.BMin.Z; } if (it.BMax.X > bmax.X) { bmax.X = it.BMax.X; } if (it.BMax.Y > bmax.Y) { bmax.Y = it.BMax.Y; } if (it.BMax.Z > bmax.Z) { bmax.Z = it.BMax.Z; } } }
public static int CreateBVTree(NavMeshCreateParams param, out List <BVNode> nodes) { nodes = new List <BVNode>(); // Build tree float quantFactor = 1 / param.cs; BVItem[] items = new BVItem[param.polyCount]; for (int i = 0; i < param.polyCount; i++) { var it = items[i]; it.I = i; // Calc polygon bounds. Use detail meshes if available. if (param.detailMeshes != null) { int vb = param.detailMeshes[i][0]; int ndv = param.detailMeshes[i][1]; var bmin = param.detailVerts[vb]; var bmax = param.detailVerts[vb]; for (int j = 1; j < ndv; j++) { bmin = Vector3.Min(bmin, param.detailVerts[vb + j]); bmax = Vector3.Max(bmax, param.detailVerts[vb + j]); } // BV-tree uses cs for all dimensions it.BMin = new Int3 { X = MathUtil.Clamp((int)((bmin.X - param.bmin.X) * quantFactor), 0, 0xffff), Y = MathUtil.Clamp((int)((bmin.Y - param.bmin.Y) * quantFactor), 0, 0xffff), Z = MathUtil.Clamp((int)((bmin.Z - param.bmin.Z) * quantFactor), 0, 0xffff) }; it.BMax = new Int3 { X = MathUtil.Clamp((int)((bmax.X - param.bmin.X) * quantFactor), 0, 0xffff), Y = MathUtil.Clamp((int)((bmax.Y - param.bmin.Y) * quantFactor), 0, 0xffff), Z = MathUtil.Clamp((int)((bmax.Z - param.bmin.Z) * quantFactor), 0, 0xffff) }; } else { var p = param.Polys[i]; var itBMin = param.Verts[p[0]]; var itBMax = param.Verts[p[0]]; for (int j = 1; j < param.nvp; ++j) { if (p[j] == MESH_NULL_IDX) { break; } var x = param.Verts[p[j]].X; var y = param.Verts[p[j]].Y; var z = param.Verts[p[j]].Z; if (x < it.BMin.X) { itBMin.X = x; } if (y < it.BMin.Y) { itBMin.Y = y; } if (z < it.BMin.Z) { itBMin.Z = z; } if (x > it.BMax.X) { itBMax.X = x; } if (y > it.BMax.Y) { itBMax.Y = y; } if (z > it.BMax.Z) { itBMax.Z = z; } } // Remap y itBMin.Y = (int)Math.Floor(it.BMin.Y * param.ch / param.cs); itBMax.Y = (int)Math.Ceiling(it.BMax.Y * param.ch / param.cs); it.BMin = itBMin; it.BMax = itBMax; } items[i] = it; } int curNode = 0; Subdivide(items, param.polyCount, 0, param.polyCount, ref curNode, ref nodes); return(curNode); }