Пример #1
0
 public Box3dAndFlags(Box3d union, Box3d box0, Box3d box1)
 {
     BFlags = 0;
     BBox   = union;
     if (box0.Min.X > union.Min.X)
     {
         BBox.Min.X = box0.Min.X; BFlags |= Box.Flags.MinX0;
     }
     if (box0.Min.Y > union.Min.Y)
     {
         BBox.Min.Y = box0.Min.Y; BFlags |= Box.Flags.MinY0;
     }
     if (box0.Min.Z > union.Min.Z)
     {
         BBox.Min.Z = box0.Min.Z; BFlags |= Box.Flags.MinZ0;
     }
     if (box0.Max.X < union.Max.X)
     {
         BBox.Max.X = box0.Max.X; BFlags |= Box.Flags.MaxX0;
     }
     if (box0.Max.Y < union.Max.Y)
     {
         BBox.Max.Y = box0.Max.Y; BFlags |= Box.Flags.MaxY0;
     }
     if (box0.Max.Z < union.Max.Z)
     {
         BBox.Max.Z = box0.Max.Z; BFlags |= Box.Flags.MaxZ0;
     }
     if (box1.Min.X > union.Min.X)
     {
         BBox.Min.X = box1.Min.X; BFlags |= Box.Flags.MinX1;
     }
     if (box1.Min.Y > union.Min.Y)
     {
         BBox.Min.Y = box1.Min.Y; BFlags |= Box.Flags.MinY1;
     }
     if (box1.Min.Z > union.Min.Z)
     {
         BBox.Min.Z = box1.Min.Z; BFlags |= Box.Flags.MinZ1;
     }
     if (box1.Max.X < union.Max.X)
     {
         BBox.Max.X = box1.Max.X; BFlags |= Box.Flags.MaxX1;
     }
     if (box1.Max.Y < union.Max.Y)
     {
         BBox.Max.Y = box1.Max.Y; BFlags |= Box.Flags.MaxY1;
     }
     if (box1.Max.Z < union.Max.Z)
     {
         BBox.Max.Z = box1.Max.Z; BFlags |= Box.Flags.MaxZ1;
     }
 }
Пример #2
0
        /// <summary>
        /// This variant of the intersection method returns the affected
        /// planes of the box if the box was hit.
        /// </summary>
        public bool Intersects(
            Box2d box,
            ref double tmin,
            ref double tmax,
            out Box.Flags tminFlags,
            out Box.Flags tmaxFlags
            )
        {
            var dirFlags = DirFlags;

            tminFlags = Box.Flags.None;
            tmaxFlags = Box.Flags.None;

            if ((dirFlags & DirFlags.PositiveX) != 0)
            {
                {
                    double t = (box.Max.X - Ray.Origin.X) * InvDir.X;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t; tmaxFlags = Box.Flags.MaxX;
                    }
                }
                {
                    double t = (box.Min.X - Ray.Origin.X) * InvDir.X;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t; tminFlags = Box.Flags.MinX;
                    }
                }
            }
            else if ((dirFlags & DirFlags.NegativeX) != 0)
            {
                {
                    double t = (box.Min.X - Ray.Origin.X) * InvDir.X;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t; tmaxFlags = Box.Flags.MinX;
                    }
                }
                {
                    double t = (box.Max.X - Ray.Origin.X) * InvDir.X;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t; tminFlags = Box.Flags.MaxX;
                    }
                }
            }
            else    // ray parallel to X-plane
            {
                if (Ray.Origin.X < box.Min.X || Ray.Origin.X > box.Max.X)
                {
                    return(false);
                }
            }

            if ((dirFlags & DirFlags.PositiveY) != 0)
            {
                {
                    double t = (box.Max.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t; tmaxFlags = Box.Flags.MaxY;
                    }
                }
                {
                    double t = (box.Min.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t; tminFlags = Box.Flags.MinY;
                    }
                }
            }
            else if ((dirFlags & DirFlags.NegativeY) != 0)
            {
                {
                    double t = (box.Min.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t; tmaxFlags = Box.Flags.MinY;
                    }
                }
                {
                    double t = (box.Max.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t; tminFlags = Box.Flags.MaxY;
                    }
                }
            }
            else    // ray parallel to Y-plane
            {
                if (Ray.Origin.Y < box.Min.Y || Ray.Origin.Y > box.Max.Y)
                {
                    return(false);
                }
            }

            if (tmin > tmax)
            {
                return(false);
            }

            return(true);
        }
Пример #3
0
        /// <summary>
        /// This variant of the intersection method only tests with the
        /// faces of the box indicated by the supplied boxFlags.
        /// </summary>
        public bool Intersects(
            Box3d box,
            Box.Flags boxFlags,
            ref double tmin,
            ref double tmax
            )
        {
            var dirFlags = DirFlags;

            if ((dirFlags & Vec.DirFlags.PositiveX) != 0)
            {
                if ((boxFlags & Box.Flags.MaxX) != 0)
                {
                    double t = (box.Max.X - Ray.Origin.X) * InvDir.X;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t;
                    }
                }
                if ((boxFlags & Box.Flags.MinX) != 0)
                {
                    double t = (box.Min.X - Ray.Origin.X) * InvDir.X;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t;
                    }
                }
            }
            else if ((dirFlags & Vec.DirFlags.NegativeX) != 0)
            {
                if ((boxFlags & Box.Flags.MinX) != 0)
                {
                    double t = (box.Min.X - Ray.Origin.X) * InvDir.X;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t;
                    }
                }
                if ((boxFlags & Box.Flags.MaxX) != 0)
                {
                    double t = (box.Max.X - Ray.Origin.X) * InvDir.X;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t;
                    }
                }
            }
            else        // ray parallel to X-plane
            {
                if ((boxFlags & Box.Flags.MinX) != 0 && (Ray.Origin.X < box.Min.X) ||
                    (boxFlags & Box.Flags.MaxX) != 0 && (Ray.Origin.X > box.Max.X))
                {
                    return(false);
                }
            }

            if ((dirFlags & Vec.DirFlags.PositiveY) != 0)
            {
                if ((boxFlags & Box.Flags.MaxY) != 0)
                {
                    double t = (box.Max.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t;
                    }
                }
                if ((boxFlags & Box.Flags.MinY) != 0)
                {
                    double t = (box.Min.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t;
                    }
                }
            }
            else if ((dirFlags & Vec.DirFlags.NegativeY) != 0)
            {
                if ((boxFlags & Box.Flags.MinY) != 0)
                {
                    double t = (box.Min.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t;
                    }
                }
                if ((boxFlags & Box.Flags.MaxY) != 0)
                {
                    double t = (box.Max.Y - Ray.Origin.Y) * InvDir.Y;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t;
                    }
                }
            }
            else        // ray parallel to Y-plane
            {
                if ((boxFlags & Box.Flags.MinY) != 0 && (Ray.Origin.Y < box.Min.Y) ||
                    (boxFlags & Box.Flags.MaxY) != 0 && (Ray.Origin.Y > box.Max.Y))
                {
                    return(false);
                }
            }

            if ((dirFlags & Vec.DirFlags.PositiveZ) != 0)
            {
                if ((boxFlags & Box.Flags.MaxZ) != 0)
                {
                    double t = (box.Max.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t;
                    }
                }
                if ((boxFlags & Box.Flags.MinZ) != 0)
                {
                    double t = (box.Min.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t;
                    }
                }
            }
            else if ((dirFlags & Vec.DirFlags.NegativeZ) != 0)
            {
                if ((boxFlags & Box.Flags.MinZ) != 0)
                {
                    double t = (box.Min.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t;
                    }
                }
                if ((boxFlags & Box.Flags.MaxZ) != 0)
                {
                    double t = (box.Max.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t;
                    }
                }
            }
            else        // ray parallel to Z-plane
            {
                if ((boxFlags & Box.Flags.MinZ) != 0 && (Ray.Origin.Z < box.Min.Z) ||
                    (boxFlags & Box.Flags.MaxZ) != 0 && (Ray.Origin.Z > box.Max.Z))
                {
                    return(false);
                }
            }

            if (tmin > tmax)
            {
                return(false);
            }

            return(true);
        }