Beispiel #1
0
    public RayCastHit <T> BoundingPrimativeCast <T>(IBoundingShape myTestBox)
    {
        if (Root == null)
        {
            return(new RayCastHit <T>(new List <T>()));
        }
        List <T>          myResults      = new List <T>();
        Stack <IAABBNode> NodesToExplore = new Stack <IAABBNode>();
        IAABBNode         Current        = Root;

        if (Current.ContainsData())
        {
            if (Current.Bounds.Contains(myTestBox) != ContainmentType.Disjoint)
            {
                TryDataConvert <T>(myResults, Current);
            }
            return(new RayCastHit <T>(myResults));
        }
        while (Current != null)
        {
            ContainmentType left  = ContainmentType.Disjoint;
            ContainmentType right = ContainmentType.Disjoint;
            if (Current.Left != null)
            {
                left = myTestBox.Contains(Current.Left.Bounds);
            }
            if (Current.Right != null)
            {
                right = myTestBox.Contains(Current.Right.Bounds);
            }
            if (left == ContainmentType.Contains || left == ContainmentType.Intersects) //So it hit.
            {
                if (Current.Left.ContainsData())
                {
                    TryDataConvert <T>(myResults, Current.Left);
                }
                else
                {
                    NodesToExplore.Push(Current.Left);
                }
            }
            if (right == ContainmentType.Contains || right == ContainmentType.Intersects) //So it hit.
            {
                if (Current.Right.ContainsData())
                {
                    TryDataConvert <T>(myResults, Current.Right);
                }
                else
                {
                    NodesToExplore.Push(Current.Right);
                }
            }
            if (NodesToExplore.Count == 0)
            {
                break;
            }
            Current = NodesToExplore.Pop();
        }
        return(new RayCastHit <T>(myResults));
    }
Beispiel #2
0
    public T GetObjectDataContainingPoint <T>(Vector3 Point)
    {
        Stack <IAABBNode> NodesToExplore = new Stack <IAABBNode>();
        IAABBNode         Current        = Root;

        if (Current.ContainsData())
        {
            if (Current.Bounds.Contains(Point) == ContainmentType.Contains)
            {
                return((T)((IAABBTreeDataHolder)Current).GetInternalData());
            }
        }
        while (Current != null)
        {
            if (Current.Bounds.Contains(Point) == ContainmentType.Contains)//So it hit.
            {
                if (Current.Left.ContainsData() && Current.Left is IAABBTreeDataHolder)
                {
                    if (Current.Left.Bounds.Center == Point)
                    {
                        return((T)((IAABBTreeDataHolder)Current.Left).GetInternalData());
                    }
                    else
                    {
                        return(default(T));
                    }
                }
                else
                {
                    NodesToExplore.Push(Current.Left);
                }
            }
            if (Current.Bounds.Contains(Point) == ContainmentType.Contains) //So it hit.
            {
                if (Current.Right.ContainsData() && Current.Right is IAABBTreeDataHolder)
                {
                    if (Current.Right.Bounds.Center == Point)
                    {
                        return((T)((IAABBTreeDataHolder)Current.Right).GetInternalData());
                    }
                    else
                    {
                        return(default(T));
                    }
                }
                else
                {
                    NodesToExplore.Push(Current.Right);
                }
            }
            if (NodesToExplore.Count == 0)
            {
                break;
            }
            Current = NodesToExplore.Pop();
        }
        return(default(T));
    }
Beispiel #3
0
    public RayCastHit <T> RaycastReturnFirst <T>(Ray aRay)
    {
        if (Root == null)
        {
            return(new RayCastHit <T>(new List <T>()));
        }
        List <T>          myResults      = new List <T>();
        Stack <IAABBNode> NodesToExplore = new Stack <IAABBNode>();
        IAABBNode         Current        = Root;

        if (Current.ContainsData())
        {
            if (aRay.Intersects(Current.Bounds).HasValue)
            {
                TryDataConvert <T>(myResults, Current);
                return(new RayCastHit <T>(myResults));
            }
        }
        while (Current != null)
        {
            if (aRay.Intersects(Current.Left.Bounds).HasValue) //So it hit.
            {
                if (Current.Left.ContainsData() && Current.Left is IAABBTreeDataHolder)
                {
                    TryDataConvert <T>(myResults, Current.Left);
                    break;
                }
                else
                {
                    NodesToExplore.Push(Current.Left);
                }
            }
            if (aRay.Intersects(Current.Right.Bounds).HasValue) //So it hit.
            {
                if (Current.Right.ContainsData() && Current.Right is IAABBTreeDataHolder)
                {
                    TryDataConvert <T>(myResults, Current.Right);
                    break;
                }
                else
                {
                    NodesToExplore.Push(Current.Right);
                }
            }
            if (NodesToExplore.Count == 0)
            {
                break;
            }
            Current = NodesToExplore.Pop();
        }
        return(new RayCastHit <T>(myResults));
    }
Beispiel #4
0
    private void Insert(IAABBNode myNewNode)
    {
        if (Root == null)
        {
            Root = myNewNode;
            return;
        }
        IAABBNode CurrentObject = Root;

        while (CurrentObject != null)
        {
            if (CurrentObject.ContainsData()) //It's a game object
            {
                MergeIntoBranch(myNewNode, CurrentObject);
                return;
            }
            else //It's just a branch.
            {
                ResizeBranch(myNewNode, CurrentObject);
                ContainmentType?leftContainment  = null;
                ContainmentType?rightContainment = null;
                if (CurrentObject.Left != null)
                {
                    leftContainment = CurrentObject.Left.Bounds.Contains(myNewNode.Bounds);
                }
                if (CurrentObject.Right != null)
                {
                    rightContainment = CurrentObject.Right.Bounds.Contains(myNewNode.Bounds);
                }

                if (leftContainment == ContainmentType.Contains || !rightContainment.HasValue || (leftContainment == ContainmentType.Intersects && rightContainment == ContainmentType.Disjoint))
                {
                    CurrentObject = CurrentObject.Left;
                }
                else if (rightContainment == ContainmentType.Contains || !leftContainment.HasValue || (rightContainment == ContainmentType.Intersects && leftContainment == ContainmentType.Disjoint))
                {
                    CurrentObject = CurrentObject.Right;
                }
                else if (CurrentObject.Left != null && CurrentObject.Right != null)
                {
                    CurrentObject = GetNextByHeuristic(myNewNode, CurrentObject);
                }
            }
        }
    }
Beispiel #5
0
 private bool CheckValidNode(IAABBNode lastModified)
 {
     if (lastModified.ContainsData())
     {
         if (lastModified.Left != null || lastModified.Right != null)
         {
             return(false);
         }
     }
     else
     {
         if (lastModified.Left == null && lastModified.Right == null)
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #6
0
    private IEnumerable <IAABBNode> IterateDataNodes(DataPredicateTest myTestPredicate, IAABBNode Current)
    {
        Stack <IAABBNode> NodesToExplore = new Stack <IAABBNode>();

        if (Current.ContainsData())
        {
            if (myTestPredicate(Current))
            {
                yield return(Current);
            }
            yield break;
        }
        while (Current != null)
        {
            if (myTestPredicate(Current.Left)) //So it hit.
            {
                if (Current.Left.ContainsData() && Current.Left is IAABBTreeDataHolder)
                {
                    yield return(Current.Left);
                }
                else
                {
                    NodesToExplore.Push(Current.Left);
                }
            }
            if (myTestPredicate(Current.Right)) //So it hit.
            {
                if (Current.Right.ContainsData() && Current.Right is IAABBTreeDataHolder)
                {
                    yield return(Current.Right);
                }
                else
                {
                    NodesToExplore.Push(Current.Right);
                }
            }
            if (NodesToExplore.Count == 0)
            {
                break;
            }
            Current = NodesToExplore.Pop();
        }
    }
Beispiel #7
0
    public List <T> GetNearest <T>(Vector3 position, uint Count, float MaxDistance)
    {
        if (Count == 0)
        {
            throw new Exception("Attempted to perform get nearest search with a return count set to 0");
        }
        if (Root == null)
        {
            return(new List <T>());
        }
        List <T>          myResults       = new List <T>((int)Count);
        Stack <IAABBNode> NodesToExplore  = new Stack <IAABBNode>();
        Stack <T>         MostClosestItem = new Stack <T>();

        IAABBNode Current = Root;

        if (Current == null)
        {
            return(new List <T>());
        }
        if (Current.ContainsData())
        {
            if (IsWithinRangeOfPosition(position, MaxDistance, Current.Bounds))
            {
                TryDataConvert(myResults, Current);
            }
            else
            {
                return(null);
            }
        }
        while (Current != null)
        {
            if (Current.Left != null && (Current.Right == null || !IsWithinRangeOfPosition(position, MaxDistance, Current.Right.Bounds)))
            {
                if (IsWithinRangeOfPosition(position, MaxDistance, Current.Left.Bounds))
                {
                    if ((Current.Left.ContainsData())) //this only happens if we're at the bottom of the tree.
                    {
                        TryDataConvert <T>(MostClosestItem, Current.Left);
                    }
                    else
                    {
                        NodesToExplore.Push(Current.Left);
                    }
                }
            }
            else if (Current.Right != null && (Current.Left == null || !IsWithinRangeOfPosition(position, MaxDistance, Current.Left.Bounds)))
            {
                if (IsWithinRangeOfPosition(position, MaxDistance, Current.Right.Bounds))
                {
                    if ((Current.Right.ContainsData())) //this only happens if we're at the bottom of the tree.
                    {
                        TryDataConvert <T>(MostClosestItem, Current.Right);
                    }
                    else
                    {
                        NodesToExplore.Push(Current.Right);
                    }
                }
            }
            else if (Current.Left != null && Current.Right != null)
            {
                if (Current.Left.ContainsData() && Current.Right.ContainsData())
                {
                    TryDataConvert <T>(MostClosestItem, Current.Left);
                    TryDataConvert <T>(MostClosestItem, Current.Right);
                }
                else if (Current.Left.ContainsData())
                {
                    TryDataConvert <T>(MostClosestItem, Current.Left);
                    NodesToExplore.Push(Current.Right);
                }
                else if (Current.Right.ContainsData())
                {
                    TryDataConvert <T>(MostClosestItem, Current.Right);
                    NodesToExplore.Push(Current.Left);
                }
                else
                { //pushes nearest node into the stack first so it pop first.
                    if (Vector3.Distance(Current.Right.Bounds.Center, position) > Vector3.Distance(Current.Left.Bounds.Center, position))
                    {
                        NodesToExplore.Push(Current.Right);
                        NodesToExplore.Push(Current.Left);
                    }
                    else
                    {
                        NodesToExplore.Push(Current.Left);
                        NodesToExplore.Push(Current.Right);
                    }
                }
            }
            if (NodesToExplore.Count == 0 || (MostClosestItem.Count == Count))
            {
                break;
            }
            Current = NodesToExplore.Pop();
        }
        if (Count > 0)
        {
            int Counter = (int)Math.Min(Count, MostClosestItem.Count);
            for (int i = 0; i < Counter; i++)
            {
                myResults.Add(MostClosestItem.Pop());
            }
        }
        else
        {
            int Counter = MostClosestItem.Count;
            for (int i = 0; i < Counter; i++)
            {
                myResults.Add(MostClosestItem.Pop());
            }
        }
        return(myResults);
    }