XNA Creators Club Online
Page 1 of 1 (2 items)
Sort Posts: Previous Next

Transformed Per-Pixel Collision Detection With Sprite Frame.

Last post 11/17/2009 6:04 PM by DualOpAmp29. 1 replies.
  • 11/17/2009 2:21 PM

    Transformed Per-Pixel Collision Detection With Sprite Frame.

    Alright, I'm following along with the 3rd collision detection series (the transformed per-pixel collision detection)  I've done the other 2 properly, and they work.  But, now I'm having trouble with the transformed collison detection.  I've mimmicked the tutorial's code as close as I can see, but it's still not working.  The sprite is rotating every frame, but it collides as if there's no rotation in the sprite.

    using System;  
    using Microsoft.Xna.Framework;  
    using Microsoft.Xna.Framework.Graphics;  
    using FarseerGames.FarseerPhysics.Dynamics;  
    using FarseerGames.FarseerPhysics.Factories;  
    using FarseerGames.FarseerPhysics.Collisions;  
     
    namespace XNALibrary  
    {  
        public static class Collision  
        {  
            public static bool PerPixelCollision(Sprite spriteA, Sprite spriteB)  
            {  
                // Data for each pixel.  
                Color[] spriteAData = new Color[spriteA.texture.Width * spriteA.texture.Height];  
                spriteA.texture.GetData(spriteAData);  
     
                Color[] spriteBData = new Color[spriteB.texture.Width * spriteB.texture.Height];  
                spriteB.texture.GetData(spriteBData);  
     
                // Transform A.  
                Matrix spriteAMatrix = Matrix.CreateTranslation(new Vector3(-spriteA.Origin, 0.0f)) *  
                    //Matrix.CreateScale(spriteA.Scale.X, spriteA.Scale.Y, 1.0f) *  
                    Matrix.CreateRotationZ(spriteA.Rotation) *  
                    Matrix.CreateTranslation(new Vector3(spriteA.Position, 0.0f));  
     
                // Transform B.  
                Matrix spriteBMatrix = Matrix.CreateTranslation(new Vector3(-spriteB.Origin, 0.0f)) *  
                    //Matrix.CreateScale(spriteB.Scale.X, spriteB.Scale.Y, 1.0f) *  
                    Matrix.CreateRotationZ(spriteB.Rotation) *  
                    Matrix.CreateTranslation(new Vector3(spriteB.Position, 0.0f));  
     
                Matrix transformAtoB = spriteAMatrix * Matrix.Invert(spriteBMatrix);  
     
                for (int yA = 0; yA < spriteA.texture.Height; yA++)  
                {  
                    for (int xA = 0; xA < spriteB.texture.Width; xA++)  
                    {  
                        Vector2 positionInB = Vector2.Transform(new Vector2(xA, yA), transformAtoB);  
     
                        int xB = (int)Math.Round(positionInB.X);  
                        int yB = (int)Math.Round(positionInB.Y);  
     
                        if (0 <= xB && xB < spriteB.texture.Width &&  
                            0 <= yB && yB < spriteB.texture.Height)  
                        {  
                            // Get the colors of the overlapping pixels  
                            Color colorA = spriteAData[xA + yA * spriteA.texture.Width];  
                            Color colorB = spriteBData[xA + yA * spriteB.texture.Width];  
     
                            if (colorA.A > 0 && colorB.A > 0)  
                            {  
                                // Collision occured.  
                                return true;  
                            }  
                        }  
                    }  
                }  
                //}  
                return false;  
            }  
        }  
    }  
     


    Here's the image I'm using for rotation:

    My sprite class is a tried-and-tested class, that doesn't seem to have any problems, which is why I think the problem lies here.

    Can anyone help?
  • 11/17/2009 6:04 PM In reply to

    Re: Transformed Per-Pixel Collision Detection

    Answer
    Reply Quote
    // Get the colors of the overlapping pixels     
                            Color colorA = spriteAData[xA + yA * spriteA.texture.Width];     
                            Color colorB = spriteBData[xA + yA * spriteB.texture.Width];    
     


    Simple case of putting an A where there should be a B.
    // Get the colors of the overlapping pixels     
                            Color colorA = spriteAData[xA + yA * spriteA.texture.Width];     
                            Color colorB = spriteBData[xB + yB * spriteB.texture.Width];    
     


    Final version:
    // Get the colors of the overlapping pixels  
                            Color colorA = spriteAData[spriteA.FrameRect.Top + spriteA.FrameRect.Left + xA + yA * spriteA.texture.Width];  
                            Color colorB = spriteBData[spriteB.FrameRect.Top + spriteB.FrameRect.Left + xB + yB * spriteB.texture.Width]; 


    SOLVED!!!
Page 1 of 1 (2 items) Previous Next