Пример #1
0
    public List <Node <T> > FindNodes(AABB queryAABB, bool strictMode         = false, List <Node <T> > into = null,
                                      AdditionalCheckDelegate additionalCheck = null)
    {
        var res = into != null ? into : new List <Node <T> >();

        if (_root == null)
        {
            return(res);
        }

        var stack = new Stack <Node <T> >();

        stack.Push(_root);
        //var cnt = 0;
        while (stack.Count > 0)
        {
            var node = stack.Pop();
            //cnt++;
            if (!queryAABB.overlaps(node.aabb))
            {
                continue;
            }

            if (node.isLeaf() && (!strictMode || (queryAABB.contains(node.aabb))))
            {
                if (additionalCheck == null)
                {
                    res.Add(node);
                }
                else
                {
                    var hitBehaviour = additionalCheck(node);
                    if (hitBehaviour == HitBehaviour.INCLUDE || hitBehaviour == HitBehaviour.INCLUDE_AND_STOP)
                    {
                        res.Add(node);
                    }

                    if (hitBehaviour == HitBehaviour.STOP || hitBehaviour == HitBehaviour.INCLUDE_AND_STOP)
                    {
                        break;
                    }
                }
            }
            else
            {
                if (node.left != null)
                {
                    stack.Push(node.left);
                }

                if (node.right != null)
                {
                    stack.Push(node.right);
                }
            }
        }

        //trace("examined: " + cnt);
        return(res);
    }
Пример #2
0
    public List <T> FindValuesAt(AABB targetAABB, bool strictMode = false, AdditionalCheckDelegate callback = null)
    {
        var result = new List <T>();

        TryFindValuesAt(targetAABB, out result, strictMode, callback);
        return(result);
    }
Пример #3
0
    public bool TryFindValuesAt(AABB targetAABB, out List <T> results, bool strictMode = false,
                                AdditionalCheckDelegate callback = null)
    {
        var result = Query(targetAABB, strictMode);

        results = result;
        if (result.Count == 0)
        {
            return(false);
        }

        return(true);
    }
Пример #4
0
    /**
     * Queries the tree for objects crossing the specified ray.
     *
     * Notes:
     *  - the intersecting objects will be returned in no particular order (closest ones to the start point may appear later in the list!).
     *  - the additionalCheck will also be called if an object fully contains the ray's start and end point.
     *
     * TODO: see how this can be optimized and return results in order
     *
     * @param	into		Hit objects will be appended to this (based on additionalCheck return value).
     * @param	additionalCheck	A function called for every object hit (function additionalCheck(data:T, id:Int):HitBehaviour).
     *
     * @return A list of all the objects found (or `into` if it was specified).
     */
    public List <T> RayCast(float fromX, float fromY, float toX, float toY, List <T> into,
                            AdditionalCheckDelegate additionalCheck)
    {
        var res = into != null ? into : new List <T>();

        if (_root == null)
        {
            return(res);
        }

        var   queryAABBResults = new List <Node <T> >();
        float tmp;
        var   rayAABB = new AABB(fromX, fromY, toX - fromX, toY - fromY);

        if (rayAABB.minX > rayAABB.maxX)
        {
            tmp          = rayAABB.maxX;
            rayAABB.maxX = rayAABB.minX;
            rayAABB.minX = tmp;
        }

        if (rayAABB.minY > rayAABB.maxY)
        {
            tmp          = rayAABB.maxY;
            rayAABB.maxY = rayAABB.minY;
            rayAABB.minY = tmp;
        }

        Query(rayAABB, false, null, (node) =>
        {
            var aabb          = node.aabb;
            var fromPointAABB = new AABB(fromX, fromY);

            var hit = false;
            for (int i = 0; i < 4; i++)
            {
                // test for intersection with node's aabb edges
                switch (i)
                {
                case 0:                         // top edge
                    hit = SegmentIntersect(fromX, fromY, toX, toY, aabb.minX, aabb.minY, aabb.maxX, aabb.minY);
                    break;

                case 1:                         // left edge
                    hit = SegmentIntersect(fromX, fromY, toX, toY, aabb.minX, aabb.minY, aabb.minX, aabb.maxY);
                    break;

                case 2:                         // bottom edge
                    hit = SegmentIntersect(fromX, fromY, toX, toY, aabb.minX, aabb.maxY, aabb.maxX, aabb.maxY);
                    break;

                case 3:                         // right edge
                    hit = SegmentIntersect(fromX, fromY, toX, toY, aabb.maxX, aabb.minY, aabb.maxX, aabb.maxY);
                    break;

                default:
                    break;
                }

                if (hit)
                {
                    break;
                }
            }

            // add intersected node id to array
            if (hit || (aabb.contains(fromPointAABB)))
            {
                queryAABBResults.Add(node);
            }

            return(HitBehaviour.SKIP);            // don't bother adding to results
        });

        foreach (var node in queryAABBResults)
        {
            if (additionalCheck != null)
            {
                var hitBehaviour = additionalCheck(node);
                if (hitBehaviour == HitBehaviour.INCLUDE || hitBehaviour == HitBehaviour.INCLUDE_AND_STOP)
                {
                    res.Add(node.data);
                }

                if (hitBehaviour == HitBehaviour.STOP || hitBehaviour == HitBehaviour.INCLUDE_AND_STOP)
                {
                    break;
                }
            }
            else
            {
                res.Add(node.data);
            }
        }

        return(res);
    }
Пример #5
0
 /**
  * Queries the tree for objects overlapping the specified point.
  *
  * @param	into			Hit objects will be appended to this (based on additionalCheck return value).
  * @param	additionalCheck		A function called for every object hit (function additionalCheck(data:*, id:int):HitBehaviour).
  *
  * @return A list of all the objects found (or `into` if it was specified).
  */
 public List <T> QueryPoint(float x, float y, List <T> into, AdditionalCheckDelegate additionalCheck)
 {
     return(Query(new AABB(x, y), false, into, additionalCheck));
 }
Пример #6
0
    public bool TryFindValuesAt(FloatWithSizeMath.FloatWithSize[] targetAABB, out List <T> results, bool strictMode = false, AdditionalCheckDelegate callback = null)
    {
        var result = Query(targetAABB[0].MinVal, targetAABB[1].MinVal, targetAABB[0].Size, targetAABB[1].Size, strictMode);

        results = result;
        if (result.Count == 0)
        {
            return(false);
        }

        return(true);
    }