Пример #1
0
 public KdNode(KdNodePlane plane, PosVector coord, List <IShape> list, KdNode nodeLeft, KdNode nodeRight)
 {
     Plane  = plane;
     Coord  = coord;
     Shapes = list;
     Left   = nodeLeft;
     Right  = nodeRight;
 }
Пример #2
0
        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();
            }
        }
Пример #3
0
        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());
            }
        }
Пример #4
0
 private KdTree(KdNode root, BoundingBox bbox)
 {
     Root        = root;
     BoundingBox = bbox;
 }