예제 #1
0
        public IEnumerable <VOBoundsDepthNode> GetAllNonNullBoundsNodes()
        {
            var nodes = new Stack <VOBoundsDepthNode>();

            nodes.Push(new VOBoundsDepthNode(root, bounds));
            while (nodes.Count > 0)
            {
                var node = nodes.Pop();
                yield return(node);

                if (node.node.isLeaf)
                {
                    continue;
                }
                for (int i = 0; i < 8; ++i)
                {
                    var n = node.node[i];
                    if (n == null)
                    {
                        continue;
                    }
                    nodes.Push(
                        new VOBoundsDepthNode(n, OctPositionVector.FromIndex(i).octant(node.bounds))
                        );
                }
            }
        }
예제 #2
0
        public FlatVOTree <T> GetFlatTree()
        {
            var result = new Queue <FlatVONode <T> > [_maxDepth];

            for (int i = 0; i < _maxDepth; ++i)
            {
                result[i] = new Queue <FlatVONode <T> >();
            }

            var nodes = new Stack <VOBoundsDepthNode>();

            nodes.Push(new VOBoundsDepthNode(root, bounds, 0, -1));
            while (nodes.Count > 0)
            {
                var node       = nodes.Pop();
                int childCount = 0;
                for (int i = 0; i < 8; ++i)
                {
                    if (node.node[i] != null)
                    {
                        childCount++;
                        nodes.Push(new VOBoundsDepthNode(node.node[i], OctPositionVector.FromIndex(i).octant(node.bounds), node.depth + 1, i));
                    }
                }
            }

            return(default(FlatVOTree <T>));
        }
예제 #3
0
 public VONode GetAt(Vector3f pos, Vector3f reference, out OctPositionVector childPositionVector)
 {
     if (children == null)
     {
         childPositionVector = default(OctPositionVector); return(null);
     }
     return(children.GetAt(pos, reference, out childPositionVector));
 }
예제 #4
0
        public bool Shift(Vector3f.CardinalDirection dir, out OctPositionVector shifted)
        {
            shifted = this;
            switch (dir)
            {
            case Vector3f.CardinalDirection.Backward:
                if (!shifted.bz)
                {
                    return(false);
                }
                shifted.bz = false;
                return(true);

            case Vector3f.CardinalDirection.Forward:
                if (shifted.bz)
                {
                    return(false);
                }
                shifted.bz = true;
                return(true);

            case Vector3f.CardinalDirection.Down:
                if (!shifted.by)
                {
                    return(false);
                }
                shifted.by = false;
                return(true);

            case Vector3f.CardinalDirection.Up:
                if (shifted.by)
                {
                    return(false);
                }
                shifted.by = true;
                return(true);

            case Vector3f.CardinalDirection.Left:
                if (!shifted.bx)
                {
                    return(false);
                }
                shifted.bx = false;
                return(true);

            case Vector3f.CardinalDirection.Right:
                if (shifted.bx)
                {
                    return(false);
                }
                shifted.bx = true;
                return(true);

            case Vector3f.CardinalDirection.Nowhere:
            default:
                return(false);
            }
        }
예제 #5
0
        bool SiblingFromRay(OctPositionVector subjectPos, VOBoundsDepthNode parent, Ray3f ray, out VOBoundsDepthNode sibling, out Vector3f escapeMagnitudes)
        {
            sibling = new VOBoundsDepthNode(null, default(Bounds));

            Bounds subjectBounds = subjectPos.octant(parent.bounds);

            escapeMagnitudes = EscapeVector.GetCornerMagnitudes(subjectBounds, ray) + new Vector3f(magNudge, magNudge, magNudge);

            OctPositionVector siblingPosVector;
            var cardinalDirection = ray.direction.GetDirection(escapeMagnitudes.IndexOfAbsMin);

            if (subjectPos.Shift(cardinalDirection, out siblingPosVector))
            {
                sibling = new VOBoundsDepthNode(parent.node[siblingPosVector.flatIndex], siblingPosVector.octant(parent.bounds), parent.depth + 1);
                return(true);
            }
            return(false);
        }
예제 #6
0
 int GetIndex(Vector3f pos, Vector3f reference, out OctPositionVector childPositionVector)
 {
     childPositionVector = OctPositionVector.FromPosition(pos, reference);
     return(childPositionVector.flatIndex);
 }
예제 #7
0
 int GetIndex(Vector3f pos, Vector3f reference)
 {
     return(OctPositionVector.FromPosition(pos, reference).flatIndex);
 }
예제 #8
0
 public N GetAt(Vector3f pos, Vector3f reference, out OctPositionVector childPositionVector)
 {
     return(storage[GetIndex(pos, reference, out childPositionVector)]);
 }
예제 #9
0
 Bounds GetOctant(Bounds container, Vector3f pos)
 {
     return(OctPositionVector.FromPosition(pos, container.center).octant(container));
 }
예제 #10
0
        //
        // Get's the first leaf hit by a ray, if any.
        // TODO: revisit the logic. Exiting when we exit tree bounds feels like it shouldn't be necessary
        //
        public bool GetFirstRayhit(Ray3f ray, out T leaf, out List <DBUGColorBounds> debugTraversal, out List <Ray3f> rayStepsDebug)
        {
            debugTraversal = new List <DBUGColorBounds>();
            rayStepsDebug  = new List <Ray3f>();

            leaf = default(T);
            var      node      = new VOBoundsDepthNode(root, bounds, 0);
            var      ancestors = new Stack <VOBoundsDepthNode>();
            Vector3f pos;

            if (!EscapeVector.EnterPosition(bounds, ray, out pos))
            {
                return(false);
            }

            ray.origin = pos;

            int iterSafety = 0;

            while (true && iterSafety++ < (int)(Mathf.Pow(8, _maxDepth) / 4))
            {
                if (!bounds.Contains(ray.origin))
                {
                    return(false);
                }

                if (node.node.isLeaf)
                {
                    leaf = node.node.data;
                    return(true);
                }

                OctPositionVector nextChildPosVector;

                var nextChild = node.node.GetAt(ray.origin, node.bounds.center, out nextChildPosVector);

                if (nextChild != null)
                {
                    ancestors.Push(node);
                    node = new VOBoundsDepthNode(nextChild, nextChildPosVector.octant(node.bounds), node.depth + 1);
                    continue;
                }

                // else find a sibling or pop to parent
                int doIterSafety = 0;
                VOBoundsDepthNode sibling;
                do
                {
                    // while the ray origin is still within the parent bounds, see if there's a sibling along the ray
                    Vector3f escapeMagnitudes;
                    var      subjectPosVector = OctPositionVector.FromPosition(ray.origin, node.bounds.center);

                    var validRayMove = SiblingFromRay(subjectPosVector, node, ray, out sibling, out escapeMagnitudes);
                    ray.origin += ray.direction * escapeMagnitudes.MinAbs;
                    if (validRayMove)
                    {
                        if (sibling.node != null)
                        {
                            ancestors.Push(node);
                            node = sibling;
                        }
                    }
                    else
                    {
                        if (ancestors.Count > 0)
                        {
                            node = ancestors.Pop();
                            break;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    if (doIterSafety++ > 20)
                    {
                        Debug.LogWarning("problems: hit inner do-while iter safety"); break;
                    }
                } while (sibling.node == null);
            }
            Debug.LogWarning("We didn't want to get here. ray traversing octree ");
            return(false);
        }