From ecb3eccfe5084a45ecc32250bd1d51674706031a Mon Sep 17 00:00:00 2001 From: drewcassidy Date: Sun, 14 Jun 2020 01:54:33 -0700 Subject: [PATCH] Add blit functions --- Source/ConformalDecals/ConformalDecals.csproj | 1 + Source/ConformalDecals/Util/TextureUtils.cs | 131 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 Source/ConformalDecals/Util/TextureUtils.cs diff --git a/Source/ConformalDecals/ConformalDecals.csproj b/Source/ConformalDecals/ConformalDecals.csproj index 19d5ed4..7cce8a8 100644 --- a/Source/ConformalDecals/ConformalDecals.csproj +++ b/Source/ConformalDecals/ConformalDecals.csproj @@ -65,6 +65,7 @@ + diff --git a/Source/ConformalDecals/Util/TextureUtils.cs b/Source/ConformalDecals/Util/TextureUtils.cs new file mode 100644 index 0000000..0d86ae6 --- /dev/null +++ b/Source/ConformalDecals/Util/TextureUtils.cs @@ -0,0 +1,131 @@ +using UnityEngine; + +namespace ConformalDecals.Util { + public static class TextureUtils { + public static void BlitRect( + Texture2D src, Color32[] srcColors, Vector2Int srcPos, + Texture2D dst, Color32[] dstColors, Vector2Int dstPos, + Vector2Int size) { + + if (srcPos.x < 0) { + size.x += srcPos.x; + dstPos.x -= srcPos.x; + srcPos.x = 0; + } + + if (srcPos.y < 0) { + size.y += srcPos.y; + dstPos.y -= srcPos.y; + srcPos.y = 0; + } + + if (dstPos.x < 0) { + size.x += dstPos.x; + srcPos.x -= dstPos.x; + dstPos.x = 0; + } + + if (dstPos.y < 0) { + size.y += dstPos.y; + srcPos.y -= dstPos.y; + dstPos.y = 0; + } + + if (srcPos.x + size.x > src.width) size.x = src.width - srcPos.x; + if (srcPos.y + size.y > src.height) size.y = src.height - srcPos.y; + if (dstPos.x + size.x > dst.width) size.x = dst.width - srcPos.x; + if (dstPos.y + size.y > dst.height) size.y = dst.height - srcPos.y; + + if (size.x <= 0) return; + if (size.y <= 0) return; + + int srcIndex = srcPos.x + srcPos.y * src.width; + int dstIndex = dstPos.x + dstPos.y * dst.width; + + for (int dy = 0; dy < size.y; dy++) { + + for (int dx = 0; dx < size.x; dx++) { + dstColors[dstIndex + dx] = srcColors[srcIndex + dx]; + } + + srcIndex += src.width; + dstIndex += dst.width; + } + } + + public static void BlitRectBilinear( + Texture2D src, Vector2Int srcPos, Vector2 srcSize, + Texture2D dst, Color32[] dstColors, Vector2Int dstPos, Vector2Int dstSize) { + + var sizeRatio = dstSize / srcSize; + + if (srcPos.x < 0) { + dstSize.x += (int) (srcPos.x * sizeRatio.x); + dstPos.x -= (int) (srcPos.x * sizeRatio.x); + srcSize.x += srcPos.x; + srcPos.x = 0; + } + + if (srcPos.y < 0) { + dstSize.y += (int) (srcPos.y * sizeRatio.y); + dstPos.y -= (int) (srcPos.y * sizeRatio.y); + srcSize.y += srcPos.y; + srcPos.y = 0; + } + + if (dstPos.x < 0) { + srcSize.x += dstPos.x / sizeRatio.x; + srcPos.x -= (int) (dstPos.x / sizeRatio.x); + dstSize.x += dstPos.x; + dstPos.x = 0; + } + + if (dstPos.y < 0) { + srcSize.y += dstPos.y / sizeRatio.y; + srcPos.y -= (int) (dstPos.y / sizeRatio.y); + dstSize.y += dstPos.y; + dstPos.y = 0; + } + + if (srcPos.x + srcSize.x > src.width) { + srcSize.x = src.width - srcPos.x; + dstSize.x = (int) (srcSize.x * sizeRatio.x); + } + + if (srcPos.y + srcSize.y > src.height) { + srcSize.y = src.height - srcPos.y; + dstSize.y = (int) (srcSize.y * sizeRatio.y); + } + + if (dstPos.x + dstSize.x > dst.width) { + dstSize.x = dst.width - srcPos.x; + srcSize.x = (int) (dstSize.x / sizeRatio.x); + } + + if (dstPos.y + dstSize.y > dst.height) { + dstSize.y = dst.height - srcPos.y; + srcSize.y = (int) (dstSize.y / sizeRatio.y); + } + + var srcPixel = new Vector2(1.0f / src.width, 1.0f / src.height); + + var srcStart = (srcPos * srcPixel) + (srcPixel / 2); + var srcStep = sizeRatio * srcPixel; + + var srcY = srcStart.y; + int dstIndex = dstPos.x + dstPos.y * dst.width; + + for (int dy = 0; dy < dstSize.y; dy++) { + var srcX = srcStart.x; + + for (int dx = 0; dx < dstSize.x; dx++) { + dstColors[dstIndex + dx] = src.GetPixelBilinear(srcX, srcY); + srcX += srcStep.x; + } + + srcY += srcStep.y; + dstIndex += dst.width; + } + } + } +} \ No newline at end of file