RenderingLibrary.Graphics.Sprite.RenderTiledSprite C# (CSharp) Method

RenderTiledSprite() private method

private RenderTiledSprite ( SpriteRenderer spriteRenderer, SystemManagers managers ) : void
spriteRenderer SpriteRenderer
managers SystemManagers
return void
        private void RenderTiledSprite(SpriteRenderer spriteRenderer, SystemManagers managers)
        {
            float texelsWide = 0;
            float texelsTall = 0;

            int fullTexelsWide = 0;
            int fullTexelsTall = 0;

            if (this.AtlasedTexture != null)
            {
                fullTexelsWide = this.AtlasedTexture.SourceRectangle.Width;
                fullTexelsTall = this.AtlasedTexture.SourceRectangle.Height;
            }
            else
            {
                fullTexelsWide = this.Texture.Width;
                fullTexelsTall = this.Texture.Height;
            }

            texelsWide = fullTexelsWide;
            if (SourceRectangle.HasValue)
            {
                texelsWide = SourceRectangle.Value.Width;
            }
            texelsTall = fullTexelsTall;
            if (SourceRectangle.HasValue)
            {
                texelsTall = SourceRectangle.Value.Height;
            }


            float xRepetitions = texelsWide / (float)fullTexelsWide;
            float yRepetitions = texelsTall / (float)fullTexelsTall;


            if (xRepetitions > 0 && yRepetitions > 0)
            {
                float eachWidth = this.EffectiveWidth / xRepetitions;
                float eachHeight = this.EffectiveHeight / yRepetitions;

                float oldEffectiveWidth = this.EffectiveWidth;
                float oldEffectiveHeight = this.EffectiveHeight;

                // We're going to change the width, height, X, and Y of "this" to make rendering code work
                // by simply passing in the object. At the end of the drawing, we'll revert the values back
                // to what they were before rendering started.
                float oldWidth = this.Width;
                float oldHeight = this.Height;

                float oldX = this.X;
                float oldY = this.Y;

                var oldSource = this.SourceRectangle.Value;


                float texelsPerWorldUnitX = (float)fullTexelsWide / eachWidth;
                float texelsPerWorldUnitY = (float)fullTexelsTall / eachHeight;

                int oldSourceY = oldSource.Y;

                if (oldSourceY < 0)
                {
                    int amountToAdd = 1 - (oldSourceY / fullTexelsTall);

                    oldSourceY += amountToAdd * Texture.Height;
                }

                if (oldSourceY > 0)
                {
                    int amountToAdd = System.Math.Abs(oldSourceY) / fullTexelsTall;
                    oldSourceY -= amountToAdd * Texture.Height;
                }
                float currentY = -oldSourceY * (1 / texelsPerWorldUnitY);

                var matrix = this.GetRotationMatrix();

                for (int y = 0; y < yRepetitions; y++)
                {
                    float worldUnitsChoppedOffTop = System.Math.Max(0, oldSourceY * (1 / texelsPerWorldUnitY));
                    //float worldUnitsChoppedOffBottom = System.Math.Max(0, currentY + eachHeight - (int)oldEffectiveHeight);

                    float worldUnitsChoppedOffBottom = 0;

                    float extraY = yRepetitions - y;
                    if (extraY < 1)
                    {
                        worldUnitsChoppedOffBottom = System.Math.Max(0, (1 - extraY) * eachWidth);
                    }



                    int texelsChoppedOffTop = 0;
                    if (worldUnitsChoppedOffTop > 0)
                    {
                        texelsChoppedOffTop = oldSourceY;
                    }

                    int texelsChoppedOffBottom =
                        RenderingLibrary.Math.MathFunctions.RoundToInt(worldUnitsChoppedOffBottom * texelsPerWorldUnitY);

                    int sourceHeight = (int)(fullTexelsTall - texelsChoppedOffTop - texelsChoppedOffBottom);

                    if (sourceHeight == 0)
                    {
                        break;
                    }

                    this.Height = sourceHeight * 1 / texelsPerWorldUnitY;

                    int oldSourceX = oldSource.X;

                    if (oldSourceX < 0)
                    {
                        int amountToAdd = 1 - (oldSourceX / Texture.Width);

                        oldSourceX += amountToAdd * fullTexelsWide;
                    }

                    if (oldSourceX > 0)
                    {
                        int amountToAdd = System.Math.Abs(oldSourceX) / Texture.Width;

                        oldSourceX -= amountToAdd * fullTexelsWide;
                    }

                    float currentX = -oldSourceX * (1 / texelsPerWorldUnitX) + y * eachHeight * matrix.Up.X;
                    currentY = y * eachHeight * matrix.Up.Y;

                    for (int x = 0; x < xRepetitions; x++)
                    {
                        float worldUnitsChoppedOffLeft = System.Math.Max(0, oldSourceX * (1 / texelsPerWorldUnitX));
                        float worldUnitsChoppedOffRight = 0;

                        float extra = xRepetitions - x;
                        if (extra < 1)
                        {
                            worldUnitsChoppedOffRight = System.Math.Max(0, (1 - extra) * eachWidth);
                        }

                        int texelsChoppedOffLeft = 0;
                        if (worldUnitsChoppedOffLeft > 0)
                        {
                            // Let's use the hard number to not have any floating point issues:
                            //texelsChoppedOffLeft = worldUnitsChoppedOffLeft * texelsPerWorldUnit;
                            texelsChoppedOffLeft = oldSourceX;
                        }
                        int texelsChoppedOffRight =
                            RenderingLibrary.Math.MathFunctions.RoundToInt(worldUnitsChoppedOffRight * texelsPerWorldUnitX);

                        this.X = oldX + currentX + worldUnitsChoppedOffLeft;
                        this.Y = oldY + currentY + worldUnitsChoppedOffTop;

                        int sourceWidth = (int)(fullTexelsWide - texelsChoppedOffLeft - texelsChoppedOffRight);

                        if (sourceWidth == 0)
                        {
                            break;
                        }

                        this.Width = sourceWidth * 1 / texelsPerWorldUnitX;




                        if (AtlasedTexture != null)
                        {
                            var rectangle = new Rectangle(
                                AtlasedTexture.SourceRectangle.X + RenderingLibrary.Math.MathFunctions.RoundToInt(texelsChoppedOffLeft),
                                AtlasedTexture.SourceRectangle.Y + RenderingLibrary.Math.MathFunctions.RoundToInt(texelsChoppedOffTop),
                                sourceWidth,
                                sourceHeight);

                            Render(managers, spriteRenderer, this, AtlasedTexture.Texture, Color, rectangle, FlipHorizontal, FlipVertical, rotationInDegrees: Rotation);
                        }
                        else
                        {
                            this.SourceRectangle = new Rectangle(
                                RenderingLibrary.Math.MathFunctions.RoundToInt(texelsChoppedOffLeft),
                                RenderingLibrary.Math.MathFunctions.RoundToInt(texelsChoppedOffTop),
                                sourceWidth,
                                sourceHeight);

                            Render(managers, spriteRenderer, this, Texture, Color, SourceRectangle, FlipHorizontal, FlipVertical, rotationInDegrees: Rotation);
                        }
                        currentX = System.Math.Max(0, currentX);
                        currentX += this.Width * matrix.Right.X;
                        currentY += this.Width * matrix.Right.Y;

                    }
                }

                this.Width = oldWidth;
                this.Height = oldHeight;

                this.X = oldX;
                this.Y = oldY;

                this.SourceRectangle = oldSource;
            }
        }