public void Heal(Matrix4x4 newMatrix, Texture2D newShape, Color newColor)
        {
            if (ready == true && newShape != null && CanHeal == true)
            {
                var healData = healSnapshot.Data;
                var rect     = default(D2dRect);

                matrix     = WorldToAlphaMatrix * newMatrix;
                alphaCount = -1;

                if (D2dHelper.CalculateRect(matrix, ref rect, alphaWidth, alphaHeight) == true)
                {
                    inverse    = matrix.inverse;
                    shape      = newShape;
                    shapeW     = newShape.width;
                    shapeH     = newShape.height;
                    shapeColor = newColor * paintMultiplier;

                    rect.MinX = Mathf.Clamp(rect.MinX, 0, alphaWidth);
                    rect.MaxX = Mathf.Clamp(rect.MaxX, 0, alphaWidth);
                    rect.MinY = Mathf.Clamp(rect.MinY, 0, alphaHeight);
                    rect.MaxY = Mathf.Clamp(rect.MaxY, 0, alphaHeight);

                    var alphaPixelX     = D2dHelper.Reciprocal(alphaWidth);
                    var alphaPixelY     = D2dHelper.Reciprocal(alphaHeight);
                    var alphaHalfPixelX = alphaPixelX * 0.5f;
                    var alphaHalfPixelY = alphaPixelY * 0.5f;

                    for (var y = rect.MinY; y < rect.MaxY; y++)
                    {
                        var v      = y * alphaPixelY + alphaHalfPixelY;
                        var offset = y * alphaWidth;

                        for (var x = rect.MinX; x < rect.MaxX; x++)
                        {
                            var u = x * alphaPixelX + alphaHalfPixelX;

                            if (CalculateShapeCoord(u, v) == true)
                            {
                                var index      = offset + x;
                                var alphaPixel = alphaData[index];
                                var shapePixel = SampleShapeA();

                                alphaPixel.a = (byte)System.Math.Min(alphaPixel.a + shapePixel, healData.AlphaData[index].a);

                                if (pixels == PixelsType.PixelatedBinary)
                                {
                                    alphaPixel.a = alphaPixel.a > 127 ? (byte)255 : (byte)0;
                                }

                                alphaData[index] = alphaPixel;
                            }
                        }
                    }

                    AlphaModified.Add(rect);
                }
            }
        }
        public void Subtract(Matrix4x4 newMatrix, Texture2D newShape, Color newColor)
        {
            if (ready == true && indestructible == false && newShape != null)
            {
                var rect = default(D2dRect);

                matrix     = WorldToAlphaMatrix * newMatrix;
                alphaCount = -1;

                if (D2dHelper.CalculateRect(matrix, ref rect, alphaWidth, alphaHeight) == true)
                {
                    inverse    = matrix.inverse;
                    shape      = newShape;
                    shapeW     = newShape.width;
                    shapeH     = newShape.height;
                    shapeColor = newColor;

                    rect.MinX = Mathf.Clamp(rect.MinX, 0, alphaWidth);
                    rect.MaxX = Mathf.Clamp(rect.MaxX, 0, alphaWidth);
                    rect.MinY = Mathf.Clamp(rect.MinY, 0, alphaHeight);
                    rect.MaxY = Mathf.Clamp(rect.MaxY, 0, alphaHeight);

                    var alphaPixelX     = D2dHelper.Reciprocal(alphaWidth);
                    var alphaPixelY     = D2dHelper.Reciprocal(alphaHeight);
                    var alphaHalfPixelX = alphaPixelX * 0.5f;
                    var alphaHalfPixelY = alphaPixelY * 0.5f;

                    for (var y = rect.MinY; y < rect.MaxY; y++)
                    {
                        var v      = y * alphaPixelY + alphaHalfPixelY;
                        var offset = y * alphaWidth;

                        for (var x = rect.MinX; x < rect.MaxX; x++)
                        {
                            var u = x * alphaPixelX + alphaHalfPixelX;

                            if (CalculateShapeCoord(u, v) == true)
                            {
                                var index      = offset + x;
                                var alphaPixel = alphaData[index];
                                var shapePixel = SampleShape();

                                alphaPixel.r = (byte)System.Math.Max(alphaPixel.r - shapePixel.r, 0);
                                alphaPixel.g = (byte)System.Math.Max(alphaPixel.g - shapePixel.g, 0);
                                alphaPixel.b = (byte)System.Math.Max(alphaPixel.b - shapePixel.b, 0);
                                alphaPixel.a = (byte)System.Math.Max(alphaPixel.a - shapePixel.a, 0);

                                alphaData[index] = alphaPixel;
                            }
                        }
                    }

                    AlphaModified.Add(rect);
                }
            }
        }
        public static void Halve(ref Color32[] alphaData, ref int alphaWidth, ref int alphaHeight, ref Vector2 alphaOffset, ref Vector2 alphaScale)
        {
            var oldWidth  = alphaWidth;
            var oldHeight = alphaHeight;

            Halve(ref alphaData, ref alphaWidth, ref alphaHeight);

            var pixelW = D2dHelper.Reciprocal(oldWidth) * alphaScale.x;
            var pixelH = D2dHelper.Reciprocal(oldHeight) * alphaScale.y;

            alphaOffset.x += pixelW * 0.5f;
            alphaOffset.y += pixelH * 0.5f;
            alphaScale.x  -= pixelW * 1.0f;
            alphaScale.y  -= pixelH * 1.0f;
        }