2
\$\begingroup\$

I am trying to figure out how to determine the depth of a pixel perfect collision in XNA. I want to know the depth in order to be able to use it in my collision response.

At the moment I have the following code, that provides me with a working pixel perfect collision detection:

public static bool IntersectPixels(Matrix transformA, int widthA, int heightA, Color[] dataA, Matrix transformB, int widthB, int heightB, Color[] dataB)
{
    Matrix transformAToB = transformA * Matrix.Invert(transformB);

    Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToB);
    Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToB);

    // Calculate the top left corner of A in B's local space
    // This variable will be reused to keep track of the start of each row
    Vector2 yPosInB = Vector2.Transform(Vector2.Zero, transformAToB);

    // For each row of pixels in A
    for (int yA = 0; yA < heightA; yA++)
    {
        // Start at the beginning of the row
        Vector2 posInB = yPosInB;

        // For each pixel in this row
        for (int xA = 0; xA < widthA; xA++)
        {
            // Round to the nearest pixel
            int xB = (int)Math.Round(posInB.X);
            int yB = (int)Math.Round(posInB.Y);

            // If the pixel lies within the bounds of B
            if (0 <= xB && xB < widthB && 0 <= yB && yB < heightB)
            {
                // Get the colors of the overlapping pixels
                Color colorA = dataA[xA + yA * widthA];
                Color colorB = dataB[xB + yB * widthB];

                // If both pixels are not completely transparent,
                if (colorA.A != 0 && colorB.A != 0)
                {
                    // then an intersection has been found
                    return true;
                }
            }

            // Move to the next pixel in the row
            posInB += stepX;
        }

        // Move to the next row
        yPosInB += stepY;
    }

    // No intersection found
    return false;
}

How would I determine how deep the collision is into the dataB texture data?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I managed to pull this off, by grabbing all (x,y) coordinates of the sprites that intersect, then calculating as follows:

VerticalDepth = Bottom.Y  - Top.Y
HorizontalDepth = Right.X - Left.X

Based on the direction of the collision, I would then adjust accordingly.

if (depth > 0)
    AdjustPosition();

That is the simplified explanation. I would suggest you do not attempt to do this, as it is very slow, and a solution using Rectangle or Circles would most likely be better.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .