rimworld-animations-patch_m.../Source/Scripts/Utilities/GraphicMaskingUtility.cs
AbstractConcept 9144029fec v2.0.2
- Implemented texture caching to reduce the performance hit induced by dynamically cropping apparel
- Dynamically cropping apparel is now compatible with Sized Apparel
2023-02-07 19:30:02 -06:00

92 lines
No EOL
3.1 KiB
C#

using System;
using System.Collections.Generic;
using HarmonyLib;
using RimWorld;
using UnityEngine;
using Verse;
namespace Rimworld_Animations_Patch
{
public static class GraphicMaskingUtility
{
public static Texture2D GetReadableTexture2D(Texture2D source, int newWidth, int newHeight, Material mat = null) //rescales texture to newWidth and newHeight
{
source.filterMode = FilterMode.Trilinear;
RenderTexture rt = RenderTexture.GetTemporary(newWidth, newHeight);
rt.filterMode = FilterMode.Trilinear;
RenderTexture.active = rt;
if (mat != null)
{ Graphics.Blit(source, rt, mat); }
else
{ Graphics.Blit(source, rt); }
Texture2D nTex = new Texture2D(newWidth, newHeight, TextureFormat.RGBA32, mipChain: true);
nTex.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0);
nTex.name = source.name;
nTex.filterMode = FilterMode.Trilinear;
nTex.anisoLevel = 2;
nTex.Apply(updateMipmaps: true);
GL.Clear(true, true, Color.clear);
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(rt);
return nTex;
}
public static Texture2D GetReadableTexture2D(Texture2D source, Material mat = null)
{
return GetReadableTexture2D(source, source.width, source.height, mat);
}
public static Texture2D ApplyMaskToTexture2D(Texture2D mainTex, Texture2D maskTex, bool writeOverMainTex)
{
if (mainTex == null) { DebugMode.Message("ERROR: Cannot mask texture, mainTex is missing!"); return mainTex; }
if (mainTex == null) { DebugMode.Message("ERROR: Cannot mask texture, maskTex is missing!"); return mainTex; }
Color[] mainArray = GetReadableTexture2D(mainTex).GetPixels();
Color[] maskArray = GetReadableTexture2D(maskTex, mainTex.width, mainTex.height).GetPixels();
for (int j = 0; j < mainArray.Length; j++)
{
if (maskArray[j] == Color.white)
{ /*null*/ }
else if (maskArray[j].a == 0)
{ mainArray[j].a = 0; }
else if (mainArray[j].a > 0 && maskArray[j].a > 0 && writeOverMainTex)
{ mainArray[j] = new Color(Mathf.Min(mainArray[j].r, maskArray[j].r), Mathf.Min(mainArray[j].g, maskArray[j].g), Mathf.Min(mainArray[j].b, maskArray[j].b), Mathf.Min(mainArray[j].a, maskArray[j].a)); }
}
Texture2D newTex = new Texture2D(mainTex.width, mainTex.height, TextureFormat.RGBA32, mipChain: true);
newTex.SetPixels(mainArray);
newTex.filterMode = FilterMode.Trilinear;
newTex.anisoLevel = 2;
newTex.Apply(updateMipmaps: true);
return newTex;
}
public static Graphic ApplyGraphicMasks(Graphic graphic, Graphic graphicWithMask, bool writeOverMainTex)
{
for (int i = 0; i < 4; i++)
{
Texture2D mainTex = (Texture2D)graphic.MatAt(new Rot4(i)).mainTexture;
Texture2D maskTex = graphicWithMask.MatAt(new Rot4(i)).GetMaskTexture();
if (mainTex == null)
{ DebugMode.Message("Main Texture2D not found for " + graphic.path + ". Rotation: " + i.ToString()); continue; }
if (maskTex == null)
{ DebugMode.Message("Mask Texture2D not found for " + graphic.path + ". Rotation: " + i.ToString()); continue; }
graphic.MatAt(new Rot4(i)).mainTexture = ApplyMaskToTexture2D(mainTex, maskTex, writeOverMainTex);
}
return graphic;
}
}
}