144 lines
4.4 KiB
C#
144 lines
4.4 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 || maskTex == null)
|
|||
|
{
|
|||
|
DebugMode.Message("mainTex or 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 ApplyGraphicWithMasks(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();
|
|||
|
graphic.MatAt(new Rot4(i)).mainTexture = ApplyMaskToTexture2D(mainTex, maskTex, writeOverMainTex);
|
|||
|
}
|
|||
|
|
|||
|
return graphic;
|
|||
|
}
|
|||
|
|
|||
|
public static Graphic ApplyGraphicWithMasks(Graphic graphic, string mask, bool writeOverMainTex)
|
|||
|
{
|
|||
|
for (int i = 0; i < 4; i++)
|
|||
|
{
|
|||
|
Texture2D mainTex = (Texture2D)graphic.MatAt(new Rot4(i)).mainTexture;
|
|||
|
|
|||
|
if (mainTex == null)
|
|||
|
{ DebugMode.Message("Main Texture2D not found for " + graphic.path + ". Rotation: " + i.ToString()); continue; }
|
|||
|
|
|||
|
string suffix = string.Empty;
|
|||
|
switch (i)
|
|||
|
{
|
|||
|
case 0: suffix = "_north"; break;
|
|||
|
case 1: suffix = "_east"; break;
|
|||
|
case 2: suffix = "_south"; break;
|
|||
|
case 3: suffix = "_west"; break;
|
|||
|
}
|
|||
|
|
|||
|
Texture2D maskTex = ContentFinder<Texture2D>.Get(mask + suffix, false);
|
|||
|
|
|||
|
if (maskTex == null)
|
|||
|
{ DebugMode.Message("Mask Texture2D not found for " + mask + ". Rotation: " + i.ToString()); continue; }
|
|||
|
|
|||
|
graphic.MatAt(new Rot4(i)).mainTexture = ApplyMaskToTexture2D(mainTex, maskTex, writeOverMainTex);
|
|||
|
}
|
|||
|
|
|||
|
return graphic;
|
|||
|
}
|
|||
|
|
|||
|
public static void ResetGraphic(Graphic graphic)
|
|||
|
{
|
|||
|
for (int i = 0; i < 4; i++)
|
|||
|
{
|
|||
|
string suffix = string.Empty;
|
|||
|
switch (i)
|
|||
|
{
|
|||
|
case 0: suffix = "_north"; break;
|
|||
|
case 1: suffix = "_east"; break;
|
|||
|
case 2: suffix = "_south"; break;
|
|||
|
case 3: suffix = "_west"; break;
|
|||
|
}
|
|||
|
|
|||
|
Texture2D texture2D = ContentFinder<Texture2D>.Get(graphic.path + suffix, false);
|
|||
|
|
|||
|
if (texture2D == null && i == 3)
|
|||
|
{ texture2D = ContentFinder<Texture2D>.Get(graphic.path + "_east", false); }
|
|||
|
|
|||
|
if (texture2D == null)
|
|||
|
{ texture2D = ContentFinder<Texture2D>.Get(graphic.path + "_north", false); }
|
|||
|
|
|||
|
if (texture2D != null)
|
|||
|
{ graphic.MatAt(new Rot4(i)).mainTexture = texture2D; }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|