Ejemplo n.º 1
0
        /// Constructing the tree initializes the node pool.
        public DynamicTree()
        {
            _root = NullNode;

            _nodeCapacity = 16;
            _nodeCount = 0;
            _nodes = new DynamicTreeNode[_nodeCapacity];

            //Fill the array with nodes:
            for (int i = 0; i < _nodeCapacity; ++i)
            {
                _nodes[i] = new DynamicTreeNode();
            }

            // Build a linked list for the free list. The parent
            // pointer becomes the "next" pointer.
            for (int i = 0; i < _nodeCapacity - 1; ++i)
            {
                _nodes[i].Next = i + 1;
            }

            _nodes[_nodeCapacity - 1].Next = NullNode;
            _freeList = 0;

            _insertionCount = 0;
        }
Ejemplo n.º 2
0
        public DynamicTree()
        {
            m_root = null;
            m_nodeCount = 0;
            m_nodeCapacity = 16;
            m_nodes = new DynamicTreeNode[16];

            // Build a linked list for the free list.
            for (int i = m_nodeCapacity - 1; i >= 0; i--)
            {
                m_nodes[i] = new DynamicTreeNode(i);
                m_nodes[i].parent = (i == m_nodeCapacity - 1) ? null : m_nodes[i + 1];
                m_nodes[i].height = -1;
            }
            m_freeList = 0;

            for (int i = 0; i < drawVecs.Length; i++)
            {
                drawVecs[i] = new Vec2();
            }
        }
        private int AllocateNode()
        {
            // Expand the node pool as needed.
            if (_freeList == NullNode)
            {
                Debug.Assert(_nodeCount == _nodeCapacity);

                // The free list is empty. Rebuild a bigger pool.
                DynamicTreeNode[] oldNodes = _nodes;
                _nodeCapacity *= 2;
                _nodes = new DynamicTreeNode[_nodeCapacity];
                Array.Copy(oldNodes, _nodes, _nodeCount);

                // Build a linked list for the free list. The parent
                // pointer becomes the "next" pointer.
                for (int i = _nodeCount; i < _nodeCapacity - 1; ++i)
                {
                    _nodes[i].parentOrNext = i + 1;
                }
                _nodes[_nodeCapacity - 1].parentOrNext = NullNode;
                _freeList = _nodeCount;
            }

            // Peel a node off the free list.
            int nodeId = _freeList;
            _freeList = _nodes[nodeId].parentOrNext;
            _nodes[nodeId].parentOrNext = NullNode;
            _nodes[nodeId].child1 = NullNode;
            _nodes[nodeId].child2 = NullNode;
            ++_nodeCount;
            return nodeId;
        }
        /// <summary>
        /// constructing the tree initializes the node pool.
        /// </summary>
        public DynamicTree()
        {
            _root = NullNode;

            _nodeCapacity = 16;
            _nodeCount = 0;
            _nodes = new DynamicTreeNode[_nodeCapacity];

            // Build a linked list for the free list.
            for (int i = 0; i < _nodeCapacity - 1; ++i)
            {
                _nodes[i].parentOrNext = i + 1;
            }
            _nodes[_nodeCapacity - 1].parentOrNext = NullNode;
            _freeList = 0;

            _path = 0;
        }
Ejemplo n.º 5
0
 public void Dispose()
 {
     _nodes = null;
 }
Ejemplo n.º 6
0
        private DynamicTreeNode allocateNode()
        {
            if (m_freeList == NULL_NODE)
            {
                Debug.Assert(m_nodeCount == m_nodeCapacity);

                DynamicTreeNode[] old = m_nodes;
                m_nodeCapacity *= 2;
                m_nodes = new DynamicTreeNode[m_nodeCapacity];
                Array.Copy(old, 0, m_nodes, 0, old.Length);

                // Build a linked list for the free list.
                for (int i = m_nodeCapacity - 1; i >= m_nodeCount; i--)
                {
                    m_nodes[i] = new DynamicTreeNode(i);
                    m_nodes[i].parent = (i == m_nodeCapacity - 1) ? null : m_nodes[i + 1];
                    m_nodes[i].height = -1;
                }
                m_freeList = m_nodeCount;
            }
            int nodeId = m_freeList;
            DynamicTreeNode treeNode = m_nodes[nodeId];
            m_freeList = treeNode.parent != null ? treeNode.parent.id : NULL_NODE;

            treeNode.parent = null;
            treeNode.child1 = null;
            treeNode.child2 = null;
            treeNode.height = 0;
            treeNode.userData = null;
            ++m_nodeCount;
            return treeNode;
        }
Ejemplo n.º 7
0
        public void raycast(TreeRayCastCallback callback, RayCastInput input)
        {
            Vec2 p1 = input.p1;
            Vec2 p2 = input.p2;
            float p1x = p1.x, p2x = p2.x, p1y = p1.y, p2y = p2.y;
            float vx, vy;
            float rx, ry;
            float absVx, absVy;
            float cx, cy;
            float hx, hy;
            float tempx, tempy;
            r.x = p2x - p1x;
            r.y = p2y - p1y;
            Debug.Assert((r.x*r.x + r.y*r.y) > 0f);
            r.normalize();
            rx = r.x;
            ry = r.y;

            // v is perpendicular to the segment.
            vx = -1f*ry;
            vy = 1f*rx;
            absVx = MathUtils.abs(vx);
            absVy = MathUtils.abs(vy);

            // Separating axis for segment (Gino, p80).
            // |dot(v, p1 - c)| > dot(|v|, h)

            float maxFraction = input.maxFraction;

            // Build a bounding box for the segment.
            AABB segAABB = aabb;
            // Vec2 t = p1 + maxFraction * (p2 - p1);
            // before inline
            // temp.set(p2).subLocal(p1).mulLocal(maxFraction).addLocal(p1);
            // Vec2.minToOut(p1, temp, segAABB.lowerBound);
            // Vec2.maxToOut(p1, temp, segAABB.upperBound);
            tempx = (p2x - p1x)*maxFraction + p1x;
            tempy = (p2y - p1y)*maxFraction + p1y;
            segAABB.lowerBound.x = p1x < tempx ? p1x : tempx;
            segAABB.lowerBound.y = p1y < tempy ? p1y : tempy;
            segAABB.upperBound.x = p1x > tempx ? p1x : tempx;
            segAABB.upperBound.y = p1y > tempy ? p1y : tempy;
            // end inline

            nodeStackIndex = 0;
            nodeStack[nodeStackIndex++] = m_root;
            while (nodeStackIndex > 0)
            {
                DynamicTreeNode node = nodeStack[--nodeStackIndex];
                if (node == null)
                {
                    continue;
                }

                AABB nodeAABB = node.aabb;
                if (!AABB.testOverlap(nodeAABB, segAABB))
                {
                    continue;
                }

                // Separating axis for segment (Gino, p80).
                // |dot(v, p1 - c)| > dot(|v|, h)
                // node.aabb.getCenterToOut(c);
                // node.aabb.getExtentsToOut(h);
                cx = (nodeAABB.lowerBound.x + nodeAABB.upperBound.x)*.5f;
                cy = (nodeAABB.lowerBound.y + nodeAABB.upperBound.y)*.5f;
                hx = (nodeAABB.upperBound.x - nodeAABB.lowerBound.x)*.5f;
                hy = (nodeAABB.upperBound.y - nodeAABB.lowerBound.y)*.5f;
                tempx = p1x - cx;
                tempy = p1y - cy;
                float separation = MathUtils.abs(vx*tempx + vy*tempy) - (absVx*hx + absVy*hy);
                if (separation > 0.0f)
                {
                    continue;
                }

                if (node.child1 == null)
                {
                    subInput.p1.x = p1x;
                    subInput.p1.y = p1y;
                    subInput.p2.x = p2x;
                    subInput.p2.y = p2y;
                    subInput.maxFraction = maxFraction;

                    float value = callback.raycastCallback(subInput, node.id);

                    if (value == 0.0f)
                    {
                        // The client has terminated the ray cast.
                        return;
                    }

                    if (value > 0.0f)
                    {
                        // Update segment bounding box.
                        maxFraction = value;
                        // temp.set(p2).subLocal(p1).mulLocal(maxFraction).addLocal(p1);
                        // Vec2.minToOut(p1, temp, segAABB.lowerBound);
                        // Vec2.maxToOut(p1, temp, segAABB.upperBound);
                        tempx = (p2x - p1x)*maxFraction + p1x;
                        tempy = (p2y - p1y)*maxFraction + p1y;
                        segAABB.lowerBound.x = p1x < tempx ? p1x : tempx;
                        segAABB.lowerBound.y = p1y < tempy ? p1y : tempy;
                        segAABB.upperBound.x = p1x > tempx ? p1x : tempx;
                        segAABB.upperBound.y = p1y > tempy ? p1y : tempy;
                    }
                }
                else
                {
                    if (nodeStack.Length - nodeStackIndex - 2 <= 0)
                    {
                        DynamicTreeNode[] newBuffer = new DynamicTreeNode[nodeStack.Length*2];
                        Array.Copy(nodeStack, 0, newBuffer, 0, nodeStack.Length);
                        nodeStack = newBuffer;
                    }
                    nodeStack[nodeStackIndex++] = node.child1;
                    nodeStack[nodeStackIndex++] = node.child2;
                }
            }
        }
Ejemplo n.º 8
0
        public void query(TreeCallback callback, AABB aabb)
        {
            Debug.Assert(aabb.isValid());
            nodeStackIndex = 0;
            nodeStack[nodeStackIndex++] = m_root;

            while (nodeStackIndex > 0)
            {
                DynamicTreeNode node = nodeStack[--nodeStackIndex];
                if (node == null)
                {
                    continue;
                }

                if (AABB.testOverlap(node.aabb, aabb))
                {
                    if (node.child1 == null)
                    {
                        bool proceed = callback.treeCallback(node.id);
                        if (!proceed)
                        {
                            return;
                        }
                    }
                    else
                    {
                        if (nodeStack.Length - nodeStackIndex - 2 <= 0)
                        {
                            DynamicTreeNode[] newBuffer = new DynamicTreeNode[nodeStack.Length*2];
                            Array.Copy(nodeStack, 0, newBuffer, 0, nodeStack.Length);
                            nodeStack = newBuffer;
                        }
                        nodeStack[nodeStackIndex++] = node.child1;
                        nodeStack[nodeStackIndex++] = node.child2;
                    }
                }
            }
        }