• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Per Pixel Collision Transformation Matrix

Status
Not open for further replies.
Level 29
Joined
Oct 24, 2012
Messages
6,543
Edit: I am using C# XNA.
I am trying to do per pixel collision with scaled texture 2ds.
It currently is not detecting the collision and I am not sure why.

Here is where I create the matrix transformation.


JASS:
        private void BuildMatrix()
        {
            // Build the transformation matrix
            Matrix TransformMatrix =
                // _Rect.center.x and .y get the centers as this object is based off of a single square pixel.
                Matrix.CreateTranslation(new Vector3(-_Rect.Center.X, -_Rect.Center.Y, 0.0f)) *
                // _Width is the scale width and height is scale height.
                Matrix.CreateScale(_Width, _Height, 0) *
                // This one does not have rotation.
                Matrix.CreateRotationZ(0) *
                // Rect.X / Y are the top left X / Y coordinates for that rectangle.
                Matrix.CreateTranslation(new Vector3(_Rect.X, _Rect.Y, 0.0f));
        }

Here is the other build matrix.

JASS:
        private void BuildMatrix()
        {
            // Build the transformation matrix
            Matrix TransformMatrix =
                // The location.center is the center of the texture 2d. Where it is placed on the screen.
                Matrix.CreateTranslation(new Vector3(-Location.Center, 0.0f)) *
                // Size width / height are the size of the texture after it is scaled.
                Matrix.CreateScale(Size.Width, Size.Height, 0) *
                // No rotation.
                Matrix.CreateRotationZ(0) *
                // Location.Position is the is the top coordinates for the texture2d before scaling.
                Matrix.CreateTranslation(new Vector3(Location.Position, 0.0f));
        }

Here is the per pixel method.



JASS:
        public static bool IntersectPixels( Matrix transformA, int widthA, int heightA, Color[] dataA, Matrix transformB, int widthB, int heightB, Color[] dataB)
        {
            // Calculate a matrix which transforms from A's local space into 
            // world space and then into B's local space 
            Matrix transformAToB = transformA * Matrix.Invert(transformB);

            // When a point moves in A's local space, it moves in B's local space with a 
            // fixed direction and distance proportional to the movement in A. 
            // This algorithm steps through A one pixel at a time along A's X and Y axes 
            // Calculate the analogous steps in B: 
            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) { return true; } // then an intersection has been found 
                    }
                    // Move to the next pixel in the row 
                    posInB += stepX;
                }
                // Move to the next row 
                yPosInB += stepY;
            }
            // No intersection found 
            return false;
        }


Here is the call to the per pixel collision.

JASS:
        Statistics.IntersectPixels(Projectile.TransformMatrix, Projectile.Txt2DImage.Width,
                                            Projectile.Txt2DImage.Height, Projectile.TextureColorArr,
                                            TextBoxContainer.Pillar.TransformMatrix, (int)TextBoxContainer.Pillar.Width,
                                            (int)TextBoxContainer.Pillar.Height, TextBoxContainer.Pillar.TextureColorArr);

The matrix for the pillar is displaying M41 : -179890 / M42 : -402444 / M43 : 0 / M44 : 1
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,229
Although this does not solve your problem. I do not seem to see you performing a pre-mature cull. If neither A or B overlap in any way you do not need to check the pixels of either since it is impossible for them to overlap.

Surely it would be most efficient if you could do this on the GPU?
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
Although this does not solve your problem. I do not seem to see you performing a pre-mature cull. If neither A or B overlap in any way you do not need to check the pixels of either since it is impossible for them to overlap.

Surely it would be most efficient if you could do this on the GPU?

I do that call. I just showed the info for the problem as everything else works.

Also I am not sure how XNA handles this.
 
Status
Not open for further replies.
Top