Jump to content
  • Advertisement
Sign in to follow this  
Spa8nky

[C#] Why is t_Enter always 0?

This topic is 3090 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When colliding with more than one object at the same time, I require the time of collision between two objects in order to resolve the collision correctly. Here I have a test that correctly determines if two AABBs are intersecting, but the swept test using a ray always returns 0.0f for t_Enter:
        private static bool TestAABBAABB(Shape2D s1, Shape2D s2, ref Contact2D contact)
        {
            CD_AABB2D a = (CD_AABB2D)s1;
            CD_AABB2D b = (CD_AABB2D)s2;

            // Minimum Translation Vector parameters
            float mtv_Distance = float.MaxValue;            // Set current minimum distance (max float value so next value is always less)
            Vector2 mtv_Axis = Vector2.Zero;                // Axis along which to travel with the minimum distance

            // Clip length of ray to the segment boundaries
            // Initialise times of first and last contact
            float t_Enter = 0.0f;                           // Time of entry (for ray)
            float t_Exit = 1.0f;                            // Time of exit (for ray)

            if (!IntersectThruAxisSwept(Vector2.UnitX, a, b, ref t_Enter, ref t_Exit, ref mtv_Distance, ref mtv_Axis))
            {
                return false;
            }
            if (!IntersectThruAxisSwept(Vector2.UnitY, a, b, ref t_Enter, ref t_Exit, ref mtv_Distance, ref mtv_Axis))
            {
                return false;
            }

            // Calculate Minimum Translation Vector (MTV)
            Vector2 d = a.Position - b.Position;
            mtv_Axis = Vector2.Dot(d, mtv_Axis) < 0 ? -mtv_Axis : mtv_Axis;

            contact.normal = mtv_Axis;
            contact.penetration = Math.Abs(mtv_Distance) + Math_Util.EPSILON;
            contact.t_Enter = t_Enter;
            contact.t_Exit = t_Exit;

            // Objects are intersecting
            return true;
        }

        private static bool IntersectThruAxisSwept(Vector2 axis, CD_AABB2D a, CD_AABB2D b, ref float t_Enter, ref float t_Exit, ref float mtv_Distance, ref Vector2 mtv_Axis)
        {
            Vector2 v = a.Velocity - b.Velocity;
            if (v.LengthSquared() < 0.0001f)
            {
                return false;
            }

            float a_Min = float.MaxValue;
            float a_Max = float.MinValue;
            float b_Min = float.MaxValue;
            float b_Max = float.MinValue;

            a.CalculateSlab(axis, ref a_Min, ref a_Max);
            b.CalculateSlab(axis, ref b_Min, ref b_Max);

            // Find distance intervals for current two slabs
            // Distance is between slab min/max values
            float d_S0 = a_Min - b_Max;
            float d_S1 = b_Min - a_Max;

            // The distance is positive if the intervals do not overlap
            // Must be >= to 0 and not > 0, otherwise MTV can equal Vector2.Zero and cause NaN
            if (d_S0 > 0f || d_S1 > 0f)
            {
                return false;
            }

            // Current distance interval for slabs [A_Min, A_Max] and [B_Min, B_Max]
            float d = (d_S0 > d_S1) ? -d_S0 : d_S1;

            // If d is the smallest distance so far
            if (Math.Abs(d) < Math.Abs(mtv_Distance))
            {
                // Store the distance and the current axis
                mtv_Distance = d;
                mtv_Axis = axis;
            }

            //===========================================================
            //---[Swept Test]--------------------------------------------
            //===========================================================

            // Convert the slab for B into a 1D ray
            float origin = (b_Max + b_Min) * 0.5f;                          // Origin of ray
            float e = (b_Max - b_Min) * 0.5f;                               // Extent of slab B
            float direction = Vector2.Dot(b.Velocity - a.Velocity, axis);   // Direction of ray (projected onto current axis of separation)

            // Expand the slab for A by the extent of the slab for B
            // This transforms a slab/slab collision test into a ray/slab collision test
            a_Min -= e;
            a_Max += e;

            // Do a 1 dimensional collision check on projected axis
            return RaySlabIntersect(a_Min, a_Max, origin, direction, ref t_Enter, ref t_Exit);
        }

        private static bool RaySlabIntersect(float slab_Min, float slab_Max, float ray_Origin, float ray_End, ref float tb_Enter, ref float tb_Exit)
        {
            float ray_Direction = ray_End - ray_Origin;

            // If ray is parallel to the slab
            if (Math.Abs(ray_Direction) < float.Epsilon)
            {
                // Ray is parallel to slab, but NOT inside the slab
                if (ray_Origin < slab_Min || ray_Origin > slab_Max)
                {
                    return false;
                }
            }
            else
            {
                // Compute intersection t value of ray with near and far plane of slab
                float ood = 1.0f / ray_Direction;
                float ts_Enter = (slab_Min - ray_Origin) * ood;
                float ts_Exit = (slab_Max - ray_Origin) * ood;

                // Make "ts_Enter" be intersection with near plane, "ts_Exit" with far plane
                if (ts_Enter > ts_Exit)
                {
                    Math_Util.Swap(ref ts_Enter, ref ts_Exit);
                }

                // Compute the intersection of slab intersection intervals
                tb_Enter = Math.Max(tb_Enter, ts_Enter);
                tb_Exit = Math.Min(tb_Exit, ts_Exit);

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

            if (tb_Enter > 0 && tb_Enter < 1)
            {
                Console.WriteLine("STOP");              // NEVER happens, ever!
            }

            return true;
        }

Why am I not getting any collision times, other than 0 for the RaySlabIntersect?

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!