void GatherLargeTriangles(ref TreeNode tn, CollisionContent cc, int[] tris, ref int lo, int hi, float r, BoundingSphere[] tbs) { for (int i = lo; i < hi; ++i) { if (tbs[tris[i]].Radius >= r) { int j = tris[i]; tris[i] = tris[lo]; tris[lo] = j; ++lo; } } }
void BuildNodes(CollisionContent cc, int[] tris, int lo, int hi, List<TreeNode> nodes, AABB bounds, BoundingSphere[] tbs) { TreeNode tn = new TreeNode(); tn.TriStart = lo; tn.Expansion = (bounds.Hi - bounds.Lo).Length() * ExpansionFactor; GatherLargeTriangles(ref tn, cc, tris, ref lo, hi, tn.Expansion, tbs); tn.TriEnd = lo; int ix = nodes.Count; nodes.Add(tn); Vector3 lb = bounds.Lo; Vector3 ub = bounds.Hi; Vector3 cb = lb + (ub - lb) * 0.5f; if (hi > lo + 4) { int midX = lo; PartitionSmallerTriangles(cc, tris, lo, ref midX, hi, tbs, Vector3.Right, cb.X); int midXlo = lo; PartitionSmallerTriangles(cc, tris, lo, ref midXlo, midX, tbs, Vector3.Up, cb.Y); int midXhi = midX; PartitionSmallerTriangles(cc, tris, midX, ref midXhi, hi, tbs, Vector3.Up, cb.Y); int midXloYlo = lo; PartitionSmallerTriangles(cc, tris, lo, ref midXloYlo, midXlo, tbs, Vector3.Backward, cb.Z); int midXloYhi = midXlo; PartitionSmallerTriangles(cc, tris, midXlo, ref midXloYhi, midX, tbs, Vector3.Backward, cb.Z); int midXhiYlo = midX; PartitionSmallerTriangles(cc, tris, midX, ref midXhiYlo, midXhi, tbs, Vector3.Backward, cb.Z); int midXhiYhi = midXhi; PartitionSmallerTriangles(cc, tris, midXhi, ref midXhiYhi, hi, tbs, Vector3.Backward, cb.Z); if (lo < midXloYlo) { tn.Child000 = nodes.Count; BuildNodes(cc, tris, lo, midXloYlo, nodes, new AABB(lb, cb), tbs); } if (midXloYlo < midXlo) { tn.Child001 = nodes.Count; BuildNodes(cc, tris, midXloYlo, midXlo, nodes, new AABB(new Vector3(lb.X, lb.Y, cb.Z), new Vector3(cb.X, cb.Y, ub.Z)), tbs); } if (midXlo < midXloYhi) { tn.Child010 = nodes.Count; BuildNodes(cc, tris, midXlo, midXloYhi, nodes, new AABB(new Vector3(lb.X, cb.Y, lb.Z), new Vector3(cb.X, ub.Y, cb.Z)), tbs); } if (midXloYhi < midX) { tn.Child011 = nodes.Count; BuildNodes(cc, tris, midXloYhi, midX, nodes, new AABB(new Vector3(lb.X, cb.Y, cb.Z), new Vector3(cb.X, ub.Y, ub.Z)), tbs); } if (midX < midXhiYlo) { tn.Child100 = nodes.Count; BuildNodes(cc, tris, midX, midXhiYlo, nodes, new AABB(new Vector3(cb.X, lb.Y, lb.Z), new Vector3(ub.X, cb.Y, cb.Z)), tbs); } if (midXhiYlo < midXhi) { tn.Child101 = nodes.Count; BuildNodes(cc, tris, midXhiYlo, midXhi, nodes, new AABB(new Vector3(cb.X, lb.Y, cb.Z), new Vector3(ub.X, cb.Y, ub.Z)), tbs); } if (midXhi < midXhiYhi) { tn.Child110 = nodes.Count; BuildNodes(cc, tris, midXhi, midXhiYhi, nodes, new AABB(new Vector3(cb.X, cb.Y, lb.Z), new Vector3(ub.X, ub.Y, cb.Z)), tbs); } if (midXhiYhi < hi) { tn.Child111 = nodes.Count; BuildNodes(cc, tris, midXhiYhi, hi, nodes, new AABB(new Vector3(cb.X, cb.Y, cb.Z), new Vector3(ub.X, ub.Y, ub.Z)), tbs); } } else { // include them all! tn.TriEnd = hi; } nodes[ix] = tn; }