using Godot; namespace Rokojori { public static class ImageExtensions { public enum EdgeMode { Clamp, Repeat, TransparentBlack, } public static Color GetPixel( this Image image, int x, int y, EdgeMode mode ) { if ( x < 0 || y < 0 || x >= image.GetSize().X || y >= image.GetSize().Y ) { if ( mode == EdgeMode.TransparentBlack ) { return new Color( 0, 0, 0, 0 ); } if ( mode == EdgeMode.Repeat ) { x = MathX.Repeat( x, image.GetSize().X ); y = MathX.Repeat( y, image.GetSize().Y ); } if ( mode == EdgeMode.Clamp ) { x = Mathf.Clamp( x, 0, image.GetSize().X ); y = Mathf.Clamp( y, 0, image.GetSize().Y ); } } return image.GetPixel( x, y ); } public static Color SampleNearest( this Image image, Vector2 uv, EdgeMode mode = EdgeMode.Clamp ) { var pixelUV = uv * image.GetSize(); var roundedPixelUV = pixelUV.RoundToInt(); return image.GetPixel( roundedPixelUV.X, roundedPixelUV.Y, mode ); } public static Color SampleLinear( this Image image, Vector2 uv, EdgeMode mode = EdgeMode.Clamp ) { var pixelUV = uv * image.GetSize(); var lowUV = pixelUV.FloorToInt().Max( 0 ); var highUV = ( lowUV + Vector2I.One ).Min( image.GetSize() - Vector2I.One ); var mix = pixelUV - lowUV; var xTop = ColorX.Lerp( image.GetPixel( lowUV.X, lowUV.Y, mode ), image.GetPixel( highUV.X, lowUV.Y, mode ), mix.X ); var xLow = ColorX.Lerp( image.GetPixel( highUV.X, lowUV.Y, mode ), image.GetPixel( highUV.X, highUV.Y, mode ), mix.X ); return ColorX.Lerp( xTop, xLow, mix.Y ); } } }