Exemplo n.º 1
0
        /// <summary>
        /// Merge all children into this node - the opposite of Split.
        /// Note: We only have to check one level down since a merge will never happen if the children already have children,
        /// since THAT won't happen unless there are already too many objects to merge.
        /// </summary>
        void Merge()
        {
            // Note: We know children != null or we wouldn't be merging
            if (children == null)
            {
                return;
            }
            for (int i = 0; i < NUM_CHILDREN; i++)
            {
                BoundsQuadTreeNode curChild = children[i];
                int numObjects = curChild.objects.Count;
                for (int j = numObjects - 1; j >= 0; j--)
                {
                    OctreeObject curObj = curChild.objects[j];
                    objects.Add(curObj);
                    obj2Node[curObj.Obj] = this;
                }
#if SHOW_NODES
                var childCount = curChild.monoTrans.childCount;
                for (int j = childCount - 1; j >= 0; j--)
                {
                    var trans = curChild.monoTrans.GetChild(j);
                    trans.SetParent(monoTrans, true);
                }

                Debug.Assert(curChild.monoTrans.childCount == 0);
                Object.Destroy(curChild.monoTrans.gameObject);
#endif
            }

            // Remove the child nodes (and the objects in them - they've been added elsewhere now)
            children = null;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Constructor for the bounds octree.
        /// </summary>
        /// <param name="initialWorldSize">Size of the sides of the initial node, in metres. The octree will never shrink smaller than this.</param>
        /// <param name="initialWorldPos">Position of the centre of the initial node.</param>
        /// <param name="minNodeSize">Nodes will stop splitting if the new nodes would be smaller than this (metres).</param>
        /// <param name="loosenessVal">Clamped between 1 and 2. Values > 1 let nodes overlap.</param>
        public BoundsQuadTree(LFloat initialWorldSize, LVector2 initialWorldPos, LFloat minNodeSize, LFloat loosenessVal)
        {
            if (minNodeSize > initialWorldSize)
            {
                Debug.LogWarning("Minimum node size must be at least as big as the initial world size. Was: " +
                                 minNodeSize + " Adjusted to: " + initialWorldSize);
                minNodeSize = initialWorldSize;
            }

            Count       = 0;
            initialSize = initialWorldSize;
            minSize     = minNodeSize;
            looseness   = LMath.Clamp(loosenessVal, 1.ToLFloat(), 2.ToLFloat());
            rootNode    = new BoundsQuadTreeNode(null, initialSize, minSize, looseness, initialWorldPos);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="baseLengthVal">Length of this node, not taking looseness into account.</param>
        /// <param name="minSizeVal">Minimum size of nodes in this octree.</param>
        /// <param name="loosenessVal">Multiplier for baseLengthVal to get the actual size.</param>
        /// <param name="centerVal">Centre position of this node.</param>
        public BoundsQuadTreeNode(BoundsQuadTreeNode parent, LFloat baseLengthVal, LFloat minSizeVal,
                                  LFloat loosenessVal, LVector2 centerVal)
        {
#if SHOW_NODES
            monoTrans = new GameObject(MonoID++.ToString()).transform;
            if (parent != null)
            {
                monoTrans.SetParent(parent.monoTrans, false);
            }

            monoTrans.position = centerVal.ToLVector3().ToVector3();
#endif
            this.parent = parent;
            SetValues(baseLengthVal, minSizeVal, loosenessVal, centerVal);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Splits the octree into eight children.
        /// </summary>
        void Split()
        {
            LFloat quarter   = BaseLength / 4;
            LFloat newLength = BaseLength / 2;

            children    = new BoundsQuadTreeNode[NUM_CHILDREN];
            children[0] = new BoundsQuadTreeNode(this, newLength, minSize, looseness,
                                                 Center + new LVector2(-quarter, -quarter));
            children[1] = new BoundsQuadTreeNode(this, newLength, minSize, looseness,
                                                 Center + new LVector2(quarter, -quarter));
            children[2] = new BoundsQuadTreeNode(this, newLength, minSize, looseness,
                                                 Center + new LVector2(-quarter, quarter));
            children[3] = new BoundsQuadTreeNode(this, newLength, minSize, looseness,
                                                 Center + new LVector2(quarter, quarter));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Grow the octree to fit in all objects.
        /// </summary>
        /// <param name="direction">Direction to grow.</param>
        void Grow(LVector2 direction)
        {
            Debug.Trace("Grow");
            int xDirection               = direction.x >= 0 ? 1 : -1;
            int yDirection               = direction.y >= 0 ? 1 : -1;
            BoundsQuadTreeNode oldRoot   = rootNode;
            LFloat             half      = rootNode.BaseLength / 2;
            LFloat             newLength = rootNode.BaseLength * 2;
            LVector2           newCenter = rootNode.Center + new LVector2(xDirection * half, yDirection * half);

            // Create a new, bigger octree root node
            rootNode = new BoundsQuadTreeNode(null, newLength, minSize, looseness, newCenter);

            if (oldRoot.HasAnyObjects())
            {
                // Create 7 new octree children to go with the old root as children of the new root
                int rootPos = rootNode.BestFitChild(oldRoot.Center);
                BoundsQuadTreeNode[] children = new BoundsQuadTreeNode[NUM_CHILDREN];
                for (int i = 0; i < NUM_CHILDREN; i++)
                {
                    if (i == rootPos)
                    {
                        children[i] = oldRoot;
                    }
                    else
                    {
                        xDirection  = i % 2 == 0 ? -1 : 1;
                        yDirection  = i > 1 ? -1 : 1;
                        children[i] = new BoundsQuadTreeNode(rootNode, oldRoot.BaseLength, minSize, looseness,
                                                             newCenter + new LVector2(xDirection * half, yDirection * half));
                    }
                }

                // Attach the new children to the new root node
                rootNode.SetChildren(children);
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// Shrink the octree if possible, else leave it the same.
 /// </summary>
 void Shrink()
 {
     rootNode = rootNode.ShrinkIfPossible(initialSize);
 }
Exemplo n.º 7
0
 /// <summary>
 /// Shrink the octree if possible, else leave it the same.
 /// </summary>
 void Shrink()
 {
     Debug.Trace("Shrink");
     rootNode = rootNode.ShrinkIfPossible(initialSize);
 }