public KdNode(KdNodePlane plane, PosVector coord, List <IShape> list, KdNode nodeLeft, KdNode nodeRight) { Plane = plane; Coord = coord; Shapes = list; Left = nodeLeft; Right = nodeRight; }
private (bool, BoundingBox, BoundingBox) SplitPlane(KdNode node, BoundingBox bbox, Ray ray) { (bool, BoundingBox, BoundingBox) ExplicitSplitPlane(bool match) { if (match) { var(fbox, backbox) = SplitBoundingBox(bbox, node.Plane, node.Coord); return(true, fbox, backbox); } else { var(backbox, fbox) = SplitBoundingBox(bbox, node.Plane, node.Coord); return(false, fbox, backbox); } } switch (node.Plane) { case KdNodePlane.XY: return(ExplicitSplitPlane( ((node.Coord.Z > bbox.BoxMin.Z) && (node.Coord.Z > ray.Position.Z)) || ((node.Coord.Z < bbox.BoxMin.Z) && (node.Coord.Z < ray.Position.Z)))); case KdNodePlane.XZ: return(ExplicitSplitPlane( ((node.Coord.Y > bbox.BoxMin.Y) && (node.Coord.Y > ray.Position.Y)) || ((node.Coord.Y < bbox.BoxMin.Y) && (node.Coord.Y < ray.Position.Y)))); case KdNodePlane.YZ: return(ExplicitSplitPlane( ((node.Coord.X > bbox.BoxMin.X) && (node.Coord.X > ray.Position.X)) || ((node.Coord.X < bbox.BoxMin.X) && (node.Coord.X < ray.Position.X)))); default: throw new InvalidOperationException(); } }
private IntersectionInfo FindIntersectionNode(KdNode node, BoundingBox bbox, Ray ray) { if (node == null) { return(new IntersectionInfo()); } if (node.Plane == KdNodePlane.NoPlane) { // leaf node var bestInfo = new IntersectionInfo(); foreach (var shape in node.Shapes) { var info = shape.Intersect(ray); if (info.IsHit) { // if (bbox.IsPointInside(info.Position)) { if (info.Distance < bestInfo.Distance && info.Distance >= 0.0) { bestInfo = info; } } } } if (bestInfo.IsHit) { return(bestInfo); } else { return(new IntersectionInfo()); } } var(leftIsFront, frontBbox, backBbox) = SplitPlane(node, bbox, ray); var frontNode = leftIsFront ? node.Left : node.Right; var backNode = leftIsFront ? node.Right : node.Left; if (IsBoundingBoxIntersection(frontBbox, ray)) { var intInfo = FindIntersectionNode(frontNode, frontBbox, ray); if (intInfo.IsHit) { return(intInfo); } else { if (IsBoundingBoxIntersection(backBbox, ray)) { intInfo = FindIntersectionNode(backNode, backBbox, ray); return(intInfo.IsHit ? intInfo : new IntersectionInfo()); } else { return(new IntersectionInfo()); } } } else { return(new IntersectionInfo()); } }
private KdTree(KdNode root, BoundingBox bbox) { Root = root; BoundingBox = bbox; }