예제 #1
0
        public static OctValue CreateTail(Vector3 value)
        {
            var octValue = new OctValue();

            octValue.Position      = value;
            octValue.PreviousValue = IndexToOctValue.Empty();
            return(octValue);
        }
예제 #2
0
        public OctNode(AABB aabb)
        {
            AABB = aabb;

            LastValue = IndexToOctValue.Empty();

            ValueCount = 0;

            FirstChildIndex = int.MinValue;
        }
예제 #3
0
        private void InsertValueInChildren(ref OctNode node, IndexToOctValue valueToInsert)
        {
            if (!node.HasChildren())
            {
                CreateAllChildrenAndPersist(ref node);
            }

            var octant         = node.OctantAtPosition(valueToInsert.GetElement(Values).Position);
            var childNodeIndex = node.GetChildNodeFromOctant(octant);

            InsertPointInNodeOrChildren(childNodeIndex, valueToInsert);
        }
예제 #4
0
        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!");
                }
            }
        }
예제 #5
0
        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);
        }