Pixel collision testing

Hi folks. Firstly I apologise if I’ve ended up posting this twice, I thought I’d posted it last night, but there is no sign of it here today.

I’m going back to old code and testing my pixel collision routines and I’ve found a problem, it appears to be working but not very accurately. I’m not going to post the entire code as there’s quite a lot of it, but here is what I’m doing:

I load the textures and set the Color maps.
LaserBlockData = New Color(LaserTexture.Width * LaserTexture.Height - 1) {} LaserTexture.GetData(LaserBlockData)

This is a sample of creating the rectangles to check for collision, where L is a sprite.
Dim lTransform As Matrix = Matrix.CreateTranslation(New Vector3(-l.Centre, 0)) * Matrix.CreateRotationZ(l.Rotation) * Matrix.CreateTranslation(New Vector3(l.Position, 0)) Dim lRectangle As Rectangle = BoundingBox(New Rectangle(0, 0, l.Width, l.Height), lTransform)

Then I check that the 2 rectangles I’m checking have an intersection, and if they do I call the pixel checking.
If Collision(sTransform, Ship.Width, Ship.Height, ShipBlockData, lTransform, LaserTexture.Width, LaserTexture.Height, LaserBlockData) Then

And this is the routine I’m using for the actual pixel check, I have to point out this is a sample I found in a tutorial somewhere when I was searching for pixel checking with rotation, I don’t completely understand it.
`Public Function Collision(transformA As Matrix, widthA As Integer, heightA As Integer, dataA As Color(), transformB As Matrix, widthB As Integer, heightB As Integer, dataB As Color()) As Boolean
Dim transformAToB As Matrix = transformA * Matrix.Invert(transformB)
Dim stepX As Vector2 = Vector2.TransformNormal(Vector2.UnitX, transformAToB)
Dim stepY As Vector2 = Vector2.TransformNormal(Vector2.UnitY, transformAToB)
Dim yPosInB As Vector2 = Vector2.Transform(Vector2.Zero, transformAToB)

    For yA As Integer = 0 To heightA - 1
        Dim posInB As Vector2 = yPosInB

        For xA As Integer = 0 To widthA - 1
            Dim xB As Integer = CInt(Math.Truncate(Math.Round(posInB.X)))
            Dim yB As Integer = CInt(Math.Truncate(Math.Round(posInB.Y)))

            If 0 <= xB AndAlso xB < widthB AndAlso 0 <= yB AndAlso yB < heightB Then
                Dim colorA As Color = dataA(xA + yA * widthA)
                Dim colorB As Color = dataB(xB + yB * widthB)

                If colorA.A <> 0 AndAlso colorB.A <> 0 Then
                    Return True
                End If
            End If

            posInB += stepX

        yPosInB += stepY

    Return False
End Function`

(Sorry if this isn’t in a code block, it doesn’t seem to want to work with this snippet.)

As I say I do get collisions, but they don’t always seem to be in the right place, sometimes the collision is detected before any A value in the sprite, and at other times the collision appears to happen well into the sprite, but not consistently either. So, I think there is something wrong with the rotation of the colour map, or there is an issue with the Collision function, but as I say, I don’t fully understand it.

As I kind of side road topic, once I’ve created the rectangle from the BoundingBox, how can I display it? This would be a quick check to see if things are correct there.

If you have any ideas of what to check, or if you can see something is simply not right, please let me know.


I’ve found the answer to this, I was unfortunately and incorrectly applying a rotation to a sprite that doesn’t rotate. As this isn’t a circular sprite I was getting ghost collisions depending on the world rotation. I don’t know why I hadn’t seen it before.