Пример #1
0
        /// <summary>
        /// This variant of the intersection method returns the affected
        /// planes of the box if the box was hit.
        /// </summary>
        public bool Intersects(
            Box3d 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 & Vec.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 & Vec.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 & Vec.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 & Vec.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 ((dirFlags & Vec.DirFlags.PositiveZ) != 0)
            {
                {
                    double t = (box.Max.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t; tmaxFlags = Box.Flags.MaxZ;
                    }
                }
                {
                    double t = (box.Min.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t; tminFlags = Box.Flags.MinZ;
                    }
                }
            }
            else if ((dirFlags & Vec.DirFlags.NegativeZ) != 0)
            {
                {
                    double t = (box.Min.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t <= tmin)
                    {
                        return(false);
                    }
                    if (t < tmax)
                    {
                        tmax = t; tmaxFlags = Box.Flags.MinZ;
                    }
                }
                {
                    double t = (box.Max.Z - Ray.Origin.Z) * InvDir.Z;
                    if (t >= tmax)
                    {
                        return(false);
                    }
                    if (t > tmin)
                    {
                        tmin = t; tminFlags = Box.Flags.MaxZ;
                    }
                }
            }
            else        // ray parallel to Z-plane
            {
                if (Ray.Origin.Z < box.Min.Z || Ray.Origin.Z > box.Max.Z)
                {
                    return(false);
                }
            }

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

            return(true);
        }
Пример #2
0
 public static Sphere3d GetBoundingSphere3d(this Box3d box)
 => box.IsInvalid ? Sphere3d.Invalid : new Sphere3d(box.Center, 0.5 * box.Size.Length);
Пример #3
0
 public Box3f(Box3d box)
 {
     Min = (V3f)box.Min;
     Max = (V3f)box.Max;
 }
Пример #4
0
 public OrientedBox3d(Box3d box, Euclidean3d trafo)
 {
     Box   = box;
     Trafo = trafo;
 }
Пример #5
0
 public OrientedBox3d(Box3d box, Rot3d rot, V3d trans)
 {
     Box   = box;
     Trafo = new Euclidean3d(rot, trans);
 }
Пример #6
0
 public OrientedBox3d(Box3d box, Rot3d rot)
 {
     Box   = box;
     Trafo = new Euclidean3d(rot, V3d.Zero);
 }
Пример #7
0
 public static V3d UniformV3dFullClosed(this IRandomUniform rnd, Box3d box)
 {
     return(box.Lerp(rnd.UniformDoubleFullClosed(),
                     rnd.UniformDoubleFullClosed(),
                     rnd.UniformDoubleFullClosed()));
 }
Пример #8
0
 public static V3d UniformV3dOpen(this IRandomUniform rnd, Box3d box)
 {
     return(box.Lerp(rnd.UniformDoubleOpen(),
                     rnd.UniformDoubleOpen(),
                     rnd.UniformDoubleOpen()));
 }
Пример #9
0
 /// <summary>
 /// Gets outline corner indices of a box as seen from given position (in counter-clockwise order).
 /// Returns null if position is inside the box.
 /// </summary>
 public static int[] GetOutlineCornerIndicesCCW(this Box3d box, V3d fromPosition)
 {
     if (fromPosition.X < box.Min.X)
     {         //-X
         if (fromPosition.Y < box.Min.Y)
         {     //-Y
             if (fromPosition.Z < box.Min.Z)
             { // -X -Y -Z
                 return(new[] { 1, 5, 4, 6, 2, 3 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { // -X -Y +Z
                 return(new[] { 0, 1, 5, 7, 6, 2 });
             }
             else
             { // -X -Y  Z
                 return(new[] { 1, 5, 6, 2 });
             }
         }
         else if (fromPosition.Y > box.Max.Y)
         {     // +Y
             if (fromPosition.Z < box.Min.Z)
             { // -X +Y -Z
                 return(new[] { 0, 4, 6, 7, 3, 1 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { // -X +Y +Z
                 return(new[] { 0, 4, 5, 7, 3, 2 });
             }
             else
             { // -X +Y  Z
                 return(new[] { 0, 4, 7, 3 });
             }
         }
         else
         {     // Y
             if (fromPosition.Z < box.Min.Z)
             { // -X  Y -Z
                 return(new[] { 1, 4, 6, 3 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { // -X  Y +Z
                 return(new[] { 0, 5, 7, 2 });
             }
             else
             { // -X  Y  Z
                 return(new[] { 0, 4, 6, 2 });
             }
         }
     }
     else if (fromPosition.X > box.Max.X)
     {         // +X
         if (fromPosition.Y < box.Min.Y)
         {     //-Y
             if (fromPosition.Z < box.Min.Z)
             { // +X -Y -Z
                 return(new[] { 0, 2, 3, 7, 5, 4 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { // +X -Y +Z
                 return(new[] { 0, 1, 3, 7, 6, 4 });
             }
             else
             { // +X -Y  Z
                 return(new[] { 0, 3, 7, 4 });
             }
         }
         else if (fromPosition.Y > box.Max.Y)
         {     // +Y
             if (fromPosition.Z < box.Min.Z)
             { // +X +Y -Z
                 return(new[] { 0, 2, 6, 7, 5, 1 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { // +X +Y +Z
                 return(new[] { 1, 3, 2, 6, 4, 5 });
             }
             else
             { // +X +Y  Z
                 return(new[] { 1, 2, 6, 5 });
             }
         }
         else
         {     // Y
             if (fromPosition.Z < box.Min.Z)
             { // +X  Y -Z
                 return(new[] { 0, 2, 7, 5 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { // +X  Y +Z
                 return(new[] { 1, 3, 6, 4 });
             }
             else
             { // +X  Y  Z
                 return(new[] { 1, 3, 7, 5 });
             }
         }
     }
     else
     {         // X
         if (fromPosition.Y < box.Min.Y)
         {     //-Y
             if (fromPosition.Z < box.Min.Z)
             { //  X -Y -Z
                 return(new[] { 2, 3, 5, 4 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { //  X -Y +Z
                 return(new[] { 0, 1, 7, 6 });
             }
             else
             { //  X -Y  Z
                 return(new[] { 0, 1, 5, 4 });
             }
         }
         else if (fromPosition.Y > box.Max.Y)
         {     // +Y
             if (fromPosition.Z < box.Min.Z)
             { //  X +Y -Z
                 return(new[] { 0, 6, 7, 1 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { //  X +Y +Z
                 return(new[] { 2, 4, 5, 3 });
             }
             else
             { //  X +Y  Z
                 return(new[] { 2, 6, 7, 3 });
             }
         }
         else
         {     // Y
             if (fromPosition.Z < box.Min.Z)
             { //  X  Y -Z
                 return(new[] { 0, 2, 3, 1 });
             }
             else if (fromPosition.Z > box.Max.Z)
             { //  X  Y +Z
                 return(new[] { 4, 5, 7, 6 });
             }
             else
             { //  X  Y  Z
                 return(null);
             }
         }
     }
 }
Пример #10
0
        /// <summary>
        /// Gets outline corners of a box as seen from given position (in clockwise order).
        /// Returns null if position is inside the box.
        /// </summary>
        public static V3d[] GetOutlineCornersCW(this Box3d box, V3d fromPosition)
        {
            var cs = box.ComputeCorners();

            return(GetOutlineCornerIndicesCW(box, fromPosition)?.Map(i => cs[i]));
        }