public AlignedBox3Tree(Vector3[] positions, UInt16[] indices) { Debug.Assert(indices.Length % 3 == 0); this.positions = new Vector3[positions.Length]; Array.Copy(positions, this.positions, positions.Length); this.indices = new UInt16[indices.Length]; Array.Copy(indices, this.indices, indices.Length); root = new AlignedBox3TreeNode(this.indices.Length / 3, 0, this.indices, this.positions); }
/// <summary> /// recursively builds the collision tree. this method calculates the bounding box of the node /// and if necessary splits the node into two and continues to build the tree within these child /// nodes /// constructs this node /// </summary> /// <param name="numTriangles"> /// Numbers of Triangles stored inside this node or inside its children /// </param> /// <param name="baseIndex"> /// Index into the indices array. This is the point where the part of the array that /// is owned by this node starts /// </param> /// <param name="indices"> /// reference to the array containing all triangle indices of the model /// </param> public AlignedBox3TreeNode(int numTriangles, int baseIndex, UInt16[] indices, Vector3[] positions) { this.numTriangles = numTriangles; this.baseIndex = baseIndex; this.indices = indices; Debug.Assert(numTriangles > 0); if (numTriangles == 0) { return; } ComputeBoundingBox(positions); if (numTriangles < 10) { return; } // split along the axis where we get triangles distributed the best... int halfNumTriangles = numTriangles / 2; int[] numLeft = new int[3] { Split(positions, Axis.AxisX), Split(positions, Axis.AxisY), Split(positions, Axis.AxisZ) }; int[] diff = new int[3] { halfNumTriangles - numLeft[0], halfNumTriangles - numLeft[1], halfNumTriangles - numLeft[2] }; int min = 0; // 0 == x-axis, 1 == y-axis, 2 == z-axis Axis minAxis = Axis.AxisX; if (System.Math.Abs(diff[1]) < System.Math.Abs(diff[min])) { min = 1; minAxis = Axis.AxisY; } if (System.Math.Abs(diff[2]) < System.Math.Abs(diff[min])) { min = 2; minAxis = Axis.AxisZ; } int splitCount = Split(positions, minAxis); if (splitCount == 0 || splitCount == numTriangles) { // abort if either 0 or all triangles would be positioned inside a single child return; } left = new AlignedBox3TreeNode(splitCount, baseIndex, indices, positions); right = new AlignedBox3TreeNode(numTriangles - splitCount, baseIndex + splitCount * 3, indices, positions); }