Ejemplo n.º 1
0
 /// <summary>Expands 'lhs' to include 'rhs'. Returns **rhs**</summary>
 public static BBox Grow(ref BBox lhs, BBox rhs)
 {
     // Const version returns lhs, non-const returns rhs!
     // Don't treat !rhs.IsValid as an error, it's the only way to grow an empty bbox
     if (!rhs.IsValid)
     {
         return(rhs);
     }
     lhs = Union(lhs, rhs.Centre + rhs.Radius);
     lhs = Union(lhs, rhs.Centre - rhs.Radius);
     return(rhs);
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Clip a line segment to a bounding box returning the parametric values of the intersection.
        /// Returns false if the line does not intersect with the bounding box.
        /// Assumes initial values of 't0' and 't1' have been set.</summary>
        public static bool Clip(BBox bbox, v4 point_, v4 direction_, ref float t0, ref float t1)
        {
            // Convert v4's to float arrays for efficient indexing
            var lower     = (float[])bbox.Lower();
            var upper     = (float[])bbox.Upper();
            var point     = (float[])point_;
            var direction = (float[])direction_;

            // For all three slabs
            for (int i = 0; i != 3; ++i)
            {
                if (Math.Abs(direction[i]) < Math_.TinyF)
                {
                    // Ray is parallel to slab. No hit if origin not within slab
                    if (point[i] < lower[i] || point[i] > upper[i])
                    {
                        return(false);
                    }
                }
                else
                {
                    // Compute intersection t value of ray with near and far plane of slab
                    float u0 = (lower[i] - point[i]) / direction[i];
                    float u1 = (upper[i] - point[i]) / direction[i];

                    // Make u0 be intersection with near plane, u1 with far plane
                    if (u0 > u1)
                    {
                        Math_.Swap(ref u0, ref u1);
                    }

                    // Record the tightest bounds on the line segment
                    if (u0 > t0)
                    {
                        t0 = u0;
                    }
                    if (u1 < t1)
                    {
                        t1 = u1;
                    }

                    // Exit with no collision as soon as slab intersection becomes empty
                    if (t0 > t1)
                    {
                        return(false);
                    }
                }
            }

            // Ray intersects all 3 slabs
            return(true);
        }
Ejemplo n.º 3
0
        public static BBox operator *(m4x4 m, BBox rhs)
        {
            Debug.Assert(rhs.IsValid, "Transforming an invalid bounding box");
            var bb  = new BBox(m.pos, v4.Zero);
            var mat = Math_.Transpose3x3(m);

            bb.Centre.x += Math_.Dot(mat.x, rhs.Centre);
            bb.Radius.x += Math_.Dot(Math_.Abs(mat.x), rhs.Radius);
            bb.Centre.y += Math_.Dot(mat.y, rhs.Centre);
            bb.Radius.y += Math_.Dot(Math_.Abs(mat.y), rhs.Radius);
            bb.Centre.z += Math_.Dot(mat.z, rhs.Centre);
            bb.Radius.z += Math_.Dot(Math_.Abs(mat.z), rhs.Radius);
            return(bb);
        }
Ejemplo n.º 4
0
        /// <summary>Returns a bbox that encloses 'lhs' and 'rhs'</summary>
        public static BBox Union(BBox lhs, BBox rhs)
        {
            // Const version returns lhs, non-const returns rhs!
            // Don't treat !rhs.IsValid as an error, it's the only way to grow an empty bbox
            var bb = lhs;

            if (!rhs.IsValid)
            {
                return(bb);
            }
            bb = Union(bb, rhs.Centre + rhs.Radius);
            bb = Union(bb, rhs.Centre - rhs.Radius);
            return(bb);
        }
Ejemplo n.º 5
0
 /// <summary>Expands 'lhs' to include 'rhs'. Returns **rhs**</summary>
 public static v4 Grow(ref BBox bbox, v4 point)
 {
     // Const version returns lhs, non-const returns rhs!
     bbox = Union(bbox, point);
     return(point);
 }