public void RebuildFrom(TriangleMeshNode[] nodes) { this.Clear(); if (nodes.Length == 0) { return; } this.EnsureCapacity(Mathf.CeilToInt((float)nodes.Length * 2.1f)); this.EnsureNodeCapacity(Mathf.CeilToInt((float)nodes.Length * 1.1f)); int[] array = ArrayPool <int> .Claim(nodes.Length); for (int i = 0; i < nodes.Length; i++) { array[i] = i; } IntRect[] array2 = ArrayPool <IntRect> .Claim(nodes.Length); for (int j = 0; j < nodes.Length; j++) { Int3 @int; Int3 int2; Int3 int3; nodes[j].GetVertices(out @int, out int2, out int3); IntRect intRect = new IntRect(@int.x, @int.z, @int.x, @int.z); intRect = intRect.ExpandToContain(int2.x, int2.z); intRect = intRect.ExpandToContain(int3.x, int3.z); array2[j] = intRect; } this.RebuildFromInternal(nodes, array, array2, 0, nodes.Length, false); ArrayPool <int> .Release(ref array, false); ArrayPool <IntRect> .Release(ref array2, false); }
/** Rebuilds the tree using the specified nodes */ public void RebuildFrom(TriangleMeshNode[] nodes) { Clear(); if (nodes.Length == 0) { return; } // We will use approximately 2N tree nodes EnsureCapacity(Mathf.CeilToInt(nodes.Length * 2.1f)); // We will use approximately N node references EnsureNodeCapacity(Mathf.CeilToInt(nodes.Length * 1.1f)); // This will store the order of the nodes while the tree is being built // It turns out that it is a lot faster to do this than to actually modify // the nodes and nodeBounds arrays (presumably since that involves shuffling // around 20 bytes of memory (sizeof(pointer) + sizeof(IntRect)) per node // instead of 4 bytes (sizeof(int)). // It also means we don't have to make a copy of the nodes array since // we do not modify it var permutation = ArrayPool <int> .Claim(nodes.Length); for (int i = 0; i < nodes.Length; i++) { permutation[i] = i; } // Precalculate the bounds of the nodes in XZ space. // It turns out that calculating the bounds is a bottleneck and precalculating // the bounds makes it around 3 times faster to build a tree var nodeBounds = ArrayPool <IntRect> .Claim(nodes.Length); for (int i = 0; i < nodes.Length; i++) { VInt3 v0, v1, v2; nodes[i].GetVertices(out v0, out v1, out v2); var rect = new IntRect(v0.x, v0.z, v0.x, v0.z); rect = rect.ExpandToContain(v1.x, v1.z); rect = rect.ExpandToContain(v2.x, v2.z); nodeBounds[i] = rect; } RebuildFromInternal(nodes, permutation, nodeBounds, 0, nodes.Length, false); ArrayPool <int> .Release(ref permutation); ArrayPool <IntRect> .Release(ref nodeBounds); }
/** Rebuilds the tree using the specified nodes. * This is faster and gives better quality results compared to calling Insert with all nodes */ public void RebuildFrom(MeshNode[] nodes) { Clear(); if (nodes.Length == 0) { return; } // We will use approximately 2N tree nodes EnsureCapacity(Mathf.CeilToInt(nodes.Length * 2.1f)); // This will store the order of the nodes while the tree is being built // It turns out that it is a lot faster to do this than to actually modify // the nodes and nodeBounds arrays (presumably since that involves shuffling // around 20 bytes of memory (sizeof(pointer) + sizeof(IntRect)) per node // instead of 4 bytes (sizeof(int)). // It also means we don't have to make a copy of the nodes array since // we do not modify it var permutation = new int[nodes.Length]; for (int i = 0; i < nodes.Length; i++) { permutation[i] = i; } // Precalculate the bounds of the nodes in XZ space. // It turns out that calculating the bounds is a bottleneck and precalculating // the bounds makes it around 3 times faster to build a tree var nodeBounds = new IntRect[nodes.Length]; for (int i = 0; i < nodes.Length; i++) { var node = nodes[i]; var v0 = node.GetVertex(0); var v1 = node.GetVertex(1); var v2 = node.GetVertex(2); var r = new IntRect(v0.x, v0.z, v0.x, v0.z); r = r.ExpandToContain(v1.x, v1.z); r = r.ExpandToContain(v2.x, v2.z); nodeBounds[i] = r; } RebuildFromInternal(nodes, permutation, nodeBounds, 0, nodes.Length, false); }