public void Execute() { NodesCount.Value = 1; ValuesCount.Value = 0; Nodes[0] = new OctNode(AABB); var rootIndex = new IndexToOctNode(0); var root = rootIndex.GetElement(Nodes); for (int i = 0; i < ToInsert.Length; i++) { var point = ToInsert[i]; if (root.PointOverlaps(point)) { IndexToOctValue valueIndex = IndexToOctValue.NewElement(Values, ValuesCount, OctValue.CreateTail(point)); InsertPointInNodeOrChildren(rootIndex, valueIndex); } else { Debug.LogError("Cannot insert point outside of octree!"); } } }
private void InsertPointInNodeOrChildren(IndexToOctNode nodeIndex, IndexToOctValue valueToInsertIndex) { var node = nodeIndex.GetElement(Nodes); //if node is a leaf if (node.ValueCount >= 0) { #region insert into self //if no values currently in node if (!node.LastValue.HasValue()) { node.LastValue = valueToInsertIndex; } //otherwise find last element and link to new element else { //connect new last value to previous var newLastValue = valueToInsertIndex.GetElement(Values); newLastValue.PreviousValue = node.LastValue; valueToInsertIndex.SetElement(Values, newLastValue); node.LastValue = valueToInsertIndex; //set last value to new inserted value } node.ValueCount++; #endregion float theoreticalChildHalfWidth = node.AABB.HalfWidth / 2f; //if exceeded maxium allowed values, //and child would not be less than min half width if (node.ValueCount > Settings.MaxValuesPerNode && theoreticalChildHalfWidth > Settings.MinHalfSize) { #region redistributie values into children if max values exceeded and can still subdivide IndexToOctValue currentRedistributeValueIndex = node.LastValue; while (currentRedistributeValueIndex.HasValue()) { var currentRedistributeValue = currentRedistributeValueIndex.GetElement(Values); var nextRedistributeValueCache = currentRedistributeValue.PreviousValue; //break up linked list (child will reconstruct it appropriately) currentRedistributeValue.PreviousValue = IndexToOctValue.Empty(); currentRedistributeValueIndex.SetElement(Values, currentRedistributeValue); InsertValueInChildren(ref node, currentRedistributeValueIndex); currentRedistributeValueIndex = nextRedistributeValueCache; } //this node is no longer a leaf, revoke ownership of values node.LastValue = IndexToOctValue.Empty(); node.ValueCount = -1; //makes node non-insertable (a leaf) #endregion } } //if node is not a leaf else { InsertValueInChildren(ref node, valueToInsertIndex); } nodeIndex.SetElement(Nodes, node); }