Пример #1
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);
        }
Пример #2
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);
        }