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)) ); } } }
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>)); }
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)); }
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); } }
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); }
int GetIndex(Vector3f pos, Vector3f reference, out OctPositionVector childPositionVector) { childPositionVector = OctPositionVector.FromPosition(pos, reference); return(childPositionVector.flatIndex); }
int GetIndex(Vector3f pos, Vector3f reference) { return(OctPositionVector.FromPosition(pos, reference).flatIndex); }
public N GetAt(Vector3f pos, Vector3f reference, out OctPositionVector childPositionVector) { return(storage[GetIndex(pos, reference, out childPositionVector)]); }
Bounds GetOctant(Bounds container, Vector3f pos) { return(OctPositionVector.FromPosition(pos, container.center).octant(container)); }
// // 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); }