Example #1
0
        /// <summary>
        /// Query an AABB for overlapping proxies.
        /// </summary>
        /// <param name="aabb"></param>
        public void Query(ITreeQueryCallback callback, AABB aabb)
        {
            Stack <int> stack = new Stack <int>();

            stack.Push(rootIndex);

            while (stack.Count > 0)
            {
                int nodeId = stack.Pop();
                if (nodeId == nullNode)
                {
                    continue;
                }

                DTNode node = nodes[nodeId];
                if (node.aabb.Overlaps(aabb))
                {
                    if (node.IsLeaf())
                    {
                        bool proceed = callback.QueryCallback(nodeId);
                        if (proceed == false)
                        {
                            return;
                        }
                    }
                    else
                    {
                        stack.Push(node.leftChildIndex);
                        stack.Push(node.rightChildIndex);
                    }
                }
            }
        }
Example #2
0
        void OnDrawGizmosSelected()
        {
            if (!debug)
            {
                return;
            }

            DynamicTree dt = physicsScene.dynamicTree;

            if (dt == null)
            {
                return;
            }

            for (int i = 0; i < dt.nodeCount; i++)
            {
                DTNode node = dt.nodes[i];
                if (i == dt.rootIndex)
                {
                    Handles.color = Color.white;
                }
                else if (node.IsLeaf())
                {
                    Handles.color = Color.green;
                }
                else
                {
                    Handles.color = Color.yellow;
                }
                Handles.DrawLine((Vector3)(node.aabb.min), (Vector3)(new FixVec3(node.aabb.max.x, node.aabb.min.y, 0)));
                Handles.DrawLine((Vector3)(new FixVec3(node.aabb.max.x, node.aabb.min.y, 0)), (Vector3)(node.aabb.max));
                Handles.DrawLine((Vector3)(node.aabb.max), (Vector3)(new FixVec3(node.aabb.min.x, node.aabb.max.y, 0)));
                Handles.DrawLine((Vector3)(new FixVec3(node.aabb.min.x, node.aabb.max.y, 0)), (Vector3)(node.aabb.min));
            }
        }
Example #3
0
        /// <summary>
        /// Performs a left/right rotation if node A is imbalanced.
        /// </summary>
        /// <param name="indexA">The index of node A.</param>
        /// <returns>The new root index.</returns>
        private int Rotate(int indexA)
        {
            DTNode node = nodes[indexA];

            if (node.IsLeaf() || node.height < 2)
            {
                return(indexA);
            }

            int indexLeft  = node.leftChildIndex;
            int indexRight = node.rightChildIndex;

            DTNode leftChild  = nodes[indexLeft];
            DTNode rightChild = nodes[indexRight];

            int balance = rightChild.height - leftChild.height;

            // Rotate right branch up.
            if (balance > 1)
            {
                int    iF = rightChild.leftChildIndex;
                int    iG = rightChild.rightChildIndex;
                DTNode F  = nodes[iF];
                DTNode G  = nodes[iG];

                // Swap node and it's right child.
                rightChild.leftChildIndex = indexA;
                rightChild.parentIndex    = node.parentIndex;
                node.parentIndex          = indexRight;

                // The node's old parent should point to its right child.
                if (rightChild.parentIndex != nullNode)
                {
                    if (nodes[rightChild.parentIndex].leftChildIndex == indexA)
                    {
                        nodes[rightChild.parentIndex].leftChildIndex = indexRight;
                    }
                    else
                    {
                        nodes[rightChild.parentIndex].rightChildIndex = indexRight;
                    }
                }
                else
                {
                    rootIndex = indexRight;
                }


                // Rotate
                if (F.height > G.height)
                {
                    rightChild.rightChildIndex = iF;
                    node.rightChildIndex       = iG;
                    G.parentIndex   = indexA;
                    node.aabb       = AABB.Union(leftChild.aabb, G.aabb);
                    rightChild.aabb = AABB.Union(node.aabb, F.aabb);

                    node.height       = 1 + Mathf.Max(leftChild.height, G.height);
                    rightChild.height = 1 + Mathf.Max(node.height, F.height);
                }
                else
                {
                    rightChild.rightChildIndex = iG;
                    node.rightChildIndex       = iF;
                    F.parentIndex   = indexA;
                    node.aabb       = AABB.Union(leftChild.aabb, F.aabb);
                    rightChild.aabb = AABB.Union(node.aabb, G.aabb);

                    node.height       = 1 + Mathf.Max(leftChild.height, F.height);
                    rightChild.height = 1 + Mathf.Max(node.height, G.height);
                }

                return(indexRight);
            }

            // Rotate left branch up
            if (balance < -1)
            {
                int    iD = leftChild.leftChildIndex;
                int    iE = leftChild.rightChildIndex;
                DTNode D  = nodes[iD];
                DTNode E  = nodes[iE];

                // Swap node and its left child.
                leftChild.leftChildIndex = indexA;
                leftChild.parentIndex    = node.parentIndex;
                node.parentIndex         = indexLeft;

                // A's old parent should point to B
                if (leftChild.parentIndex != nullNode)
                {
                    if (nodes[leftChild.parentIndex].leftChildIndex == indexA)
                    {
                        nodes[leftChild.parentIndex].leftChildIndex = indexLeft;
                    }
                    else
                    {
                        nodes[leftChild.parentIndex].rightChildIndex = indexLeft;
                    }
                }
                else
                {
                    rootIndex = indexLeft;
                }

                // Rotate
                if (D.height > E.height)
                {
                    leftChild.rightChildIndex = iD;
                    node.leftChildIndex       = iE;
                    E.parentIndex             = indexA;
                    node.aabb      = AABB.Union(rightChild.aabb, E.aabb);
                    leftChild.aabb = AABB.Union(node.aabb, D.aabb);

                    node.height      = 1 + Mathf.Max(rightChild.height, E.height);
                    leftChild.height = 1 + Mathf.Max(node.height, D.height);
                }
                else
                {
                    leftChild.rightChildIndex = iE;
                    node.leftChildIndex       = iD;
                    D.parentIndex             = indexA;
                    node.aabb      = AABB.Union(rightChild.aabb, D.aabb);
                    leftChild.aabb = AABB.Union(node.aabb, E.aabb);

                    node.height      = 1 + Mathf.Max(rightChild.height, D.height);
                    leftChild.height = 1 + Mathf.Max(node.height, E.height);
                }

                return(indexLeft);
            }

            return(indexA);
        }