Beispiel #1
0
        private CollisionInfo CIRCLEvsCIRCLE(Circle_Collider lhs, Circle_Collider rhs)
        {
            Vec2    depth          = Vec2.Zero;
            Vec2    vecDistConvert = Vec2.Zero;
            Vector3 vecDistance    = lhs.transform.position - rhs.transform.position;
            float   radius         = lhs.Radius + rhs.Radius;

            if (radius * radius < vecDistance.sqrMagnitude)
            {
                return(new CollisionInfo());
            }

            float distance    = vecDistance.magnitude;
            float penetration = 0f;

            if (distance != 0f)
            {
                penetration = radius - distance;
                vecDistance.Normalize();
                vecDistConvert = new Vec2(-vecDistance.x, -vecDistance.y);
            }
            else
            {
                // Choose random (but consistent) values
                penetration    = radius;
                vecDistConvert = new Vec2(1f, 0f);
            }

            depth = vecDistConvert * penetration;

            return(new CollisionInfo(true, depth, vecDistConvert));
        }
Beispiel #2
0
        private CollisionInfo CIRCLEvsAABB(Circle_Collider lhs, AABB_Collider rhs, bool invertNormal)
        {
            // Vector from A to B
            Vector3 n = lhs.transform.position - rhs.transform.position;

            // Closest point on A to center of B
            Vector3 closest = n;

            // Calculate half extents along each axis
            float x_extent = rhs.Width * 0.5f;
            float y_extent = rhs.Height * 0.5f;

            // Clamp point to edges of the AABB
            closest.x = Mathf.Clamp(closest.x, -x_extent, x_extent);
            closest.y = Mathf.Clamp(closest.y, -y_extent, y_extent);

            bool inside = false;

            // Circle is inside the AABB, so we need to clamp the circle's center
            // to the closest edge
            if (n == closest)
            {
                inside = true;

                // Find closest axis
                if (Mathf.Abs(n.x) > Mathf.Abs(n.y))
                {
                    // Clamp to closest extent
                    if (closest.x > 0)
                    {
                        closest.x = x_extent;
                    }
                    else
                    {
                        closest.x = -x_extent;
                    }
                }

                // y axis is shorter
                else
                {
                    // Clamp to closest extent
                    if (closest.y > 0)
                    {
                        closest.y = y_extent;
                    }
                    else
                    {
                        closest.y = -y_extent;
                    }
                }
            }

            Vector3 normal      = n - closest;
            float   d           = normal.sqrMagnitude;
            float   r           = lhs.Radius;
            float   penetration = 0f;

            // Early out if the radius is shorter than distance to closest point and
            // Circle not inside the AABB
            if (d > r * r && !inside)
            {
                return(new CollisionInfo());
            }

            // Avoided sqrt until needed
            d = Mathf.Sqrt(d);

            // Collision normal needs to be flipped to point outside if circle was
            // inside the AABB
            if (inside)
            {
                normal = invertNormal ? -normal : normal;
            }
            else
            {
                normal = invertNormal ? normal : -normal;
            }

            penetration = r - d;
            Vec2 depth = new Vec2(normal.x, normal.y).Normalize();

            return(new CollisionInfo(true, depth * penetration, depth));
        }