mirror of
				https://gitgud.io/AbstractConcept/rimworld-animations-patch.git
				synced 2024-08-15 00:43:27 +00:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									767317773b
								
							
						
					
					
						commit
						9144029fec
					
				
					 15 changed files with 108 additions and 25 deletions
				
			
		
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -113,6 +113,7 @@
 | 
			
		|||
    <Compile Include="Scripts\Comps\CompApparelVisibility.cs" />
 | 
			
		||||
    <Compile Include="Scripts\Comps\CompPawnSexData.cs" />
 | 
			
		||||
    <Compile Include="Scripts\Defs\ActorAnimationData.cs" />
 | 
			
		||||
    <Compile Include="Scripts\Defs\ApparelTexture2DPack.cs" />
 | 
			
		||||
    <Compile Include="Scripts\Defs\BodyAddonData.cs" />
 | 
			
		||||
    <Compile Include="Scripts\Defs\HandAnimationDef.cs" />
 | 
			
		||||
    <Compile Include="Scripts\Extensions\StringExtension.cs" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										57
									
								
								Source/Scripts/Defs/ApparelTexture2DPack.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								Source/Scripts/Defs/ApparelTexture2DPack.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
    public class ApparelTexture2DPack
 | 
			
		||||
    {
 | 
			
		||||
        public List<Texture2D> textures = new List<Texture2D>();
 | 
			
		||||
 | 
			
		||||
        private static Dictionary<string, ApparelTexture2DPack> cachedMaskTextures = new Dictionary<string, ApparelTexture2DPack>();
 | 
			
		||||
 | 
			
		||||
        public static ApparelTexture2DPack PackMaskTextures(string path)
 | 
			
		||||
        {
 | 
			
		||||
            ApparelTexture2DPack pack = new ApparelTexture2DPack();
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < 3; i++)
 | 
			
		||||
            {
 | 
			
		||||
                string direction = new Rot4(i).ToStringWord().ToLower();
 | 
			
		||||
                Texture2D maskTexture = ContentFinder<Texture2D>.Get(path + "_" + direction, true);
 | 
			
		||||
 | 
			
		||||
                pack.textures.Add(maskTexture);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return pack;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static ApparelTexture2DPack GetCachedMaskTexturesForBodyType(BodyTypeDef bodyType)
 | 
			
		||||
        {
 | 
			
		||||
            string path = "Masks/apparel_shirt_mask_" + bodyType.defName;
 | 
			
		||||
 | 
			
		||||
            if (cachedMaskTextures.TryGetValue(path, out ApparelTexture2DPack pack) == false)
 | 
			
		||||
            { pack = PackMaskTextures(path); }
 | 
			
		||||
 | 
			
		||||
            return pack;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PackTexturesForBodyType(Graphic graphic, BodyTypeDef bodyType)
 | 
			
		||||
        {
 | 
			
		||||
            textures.Clear();
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < 3; i++)
 | 
			
		||||
            {
 | 
			
		||||
                Texture2D origTexture = (Texture2D)graphic.MatAt(new Rot4(i)).mainTexture;
 | 
			
		||||
                Texture2D maskTexture = GetCachedMaskTexturesForBodyType(bodyType).textures[i];
 | 
			
		||||
                Texture2D maskedTexture = GraphicMaskingUtility.ApplyMaskToTexture2D(origTexture, maskTexture, true);
 | 
			
		||||
 | 
			
		||||
                textures.Add(maskedTexture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -30,29 +30,24 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
			} 
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[HarmonyAfter("SizedApparelforRJW")]
 | 
			
		||||
		public static void Postfix(ref bool __result, ref Apparel apparel, ref BodyTypeDef bodyType, ref ApparelGraphicRecord rec)
 | 
			
		||||
		{
 | 
			
		||||
			if (__result == false || apparel == null || bodyType == null || rec.graphic == null || ApparelSettings.cropApparel == false || IsRunningSizedApparel) return;
 | 
			
		||||
			if (__result == false || apparel == null || bodyType == null || rec.graphic == null || apparel?.Wearer?.RaceProps?.Humanlike != true || ApparelSettings.cropApparel == false) return;
 | 
			
		||||
 | 
			
		||||
			// Get graphic
 | 
			
		||||
			Graphic graphic = rec.graphic;
 | 
			
		||||
 | 
			
		||||
			// This graphic may need to be masked if the apparel sits on the skin layer and does not cover the legs
 | 
			
		||||
			if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.OnSkin && apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso) && !apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Legs))
 | 
			
		||||
			{
 | 
			
		||||
				Dictionary<GraphicRequest, Graphic> allGraphics = Traverse.Create(typeof(GraphicDatabase)).Field("allGraphics").GetValue() as Dictionary<GraphicRequest, Graphic>;
 | 
			
		||||
				GraphicRequest graphicRequest = new GraphicRequest(typeof(Graphic_Multi), graphic.path, ShaderDatabase.CutoutComplex, graphic.drawSize, apparel.DrawColor, apparel.DrawColor, null, 0, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
 | 
			
		||||
				ApparelTexture2DPack pack = ApparelSettingsUtility.GetCachedApparelTextures(rec.graphic, bodyType);
 | 
			
		||||
				if (pack == null) return;
 | 
			
		||||
 | 
			
		||||
				if (allGraphics.TryGetValue(graphicRequest) == null)
 | 
			
		||||
				for (int i = 0; i < 3; i++)
 | 
			
		||||
				{
 | 
			
		||||
					Graphic graphicWithApparelMasks = GraphicDatabase.Get<Graphic_Multi>(graphic.path, ShaderDatabase.CutoutComplex, graphic.drawSize, apparel.DrawColor, apparel.DrawColor, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
 | 
			
		||||
					graphic = GraphicMaskingUtility.ApplyGraphicMasks(graphic, graphicWithApparelMasks, true);
 | 
			
		||||
 | 
			
		||||
					//DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");	
 | 
			
		||||
					if (pack.textures[i] == null) continue;
 | 
			
		||||
					rec.graphic.MatAt(new Rot4(i)).mainTexture = pack.textures[i];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			rec = new ApparelGraphicRecord(graphic, apparel);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//"Masks/apparel_shirt_mask_" + bodyType.defName
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +82,12 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
		// Update all humanlike pawn graphics when settings window is closed
 | 
			
		||||
		public void ApplySettings()
 | 
			
		||||
		{
 | 
			
		||||
			if (ApparelSettings.cropApparel == false)
 | 
			
		||||
			{
 | 
			
		||||
				DebugMode.Message("Clearing apparel texture cache");
 | 
			
		||||
				ApparelSettingsUtility.ClearCachedApparelTextures(); 
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (Current.ProgramState == ProgramState.Playing)
 | 
			
		||||
			{
 | 
			
		||||
				foreach (Pawn pawn in Current.Game.CurrentMap.mapPawns.AllPawns)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,30 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
{
 | 
			
		||||
	public static class ApparelSettingsUtility
 | 
			
		||||
	{
 | 
			
		||||
		private static Dictionary<string, ApparelTexture2DPack> cachedApparelTextures = new Dictionary<string, ApparelTexture2DPack>();
 | 
			
		||||
 | 
			
		||||
		public static ApparelTexture2DPack GetCachedApparelTextures(Graphic graphic, BodyTypeDef bodyType)
 | 
			
		||||
		{
 | 
			
		||||
			if (ApparelSettings.cropApparel == false) return null;
 | 
			
		||||
			if (graphic?.path == null) return null;
 | 
			
		||||
 | 
			
		||||
			if (cachedApparelTextures.TryGetValue(graphic.path, out ApparelTexture2DPack pack) == false)
 | 
			
		||||
			{
 | 
			
		||||
				pack = new ApparelTexture2DPack();
 | 
			
		||||
				pack.PackTexturesForBodyType(graphic, bodyType);
 | 
			
		||||
 | 
			
		||||
				cachedApparelTextures.Add(graphic.path, pack);
 | 
			
		||||
				DebugMode.Message("Cropped textures have been cached for " + graphic.path);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return pack;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ClearCachedApparelTextures()
 | 
			
		||||
		{
 | 
			
		||||
			cachedApparelTextures.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static List<ThingDef> GetApparelOfInterest()
 | 
			
		||||
		{
 | 
			
		||||
			List<ThingDef> thingDefs = new List<ThingDef>();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,11 +43,8 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
 | 
			
		||||
		public static Texture2D ApplyMaskToTexture2D(Texture2D mainTex, Texture2D maskTex, bool writeOverMainTex)
 | 
			
		||||
		{
 | 
			
		||||
			if (mainTex == null || maskTex == null)
 | 
			
		||||
			{
 | 
			
		||||
				DebugMode.Message("mainTex or maskTex is missing!");
 | 
			
		||||
				return mainTex;
 | 
			
		||||
			}
 | 
			
		||||
			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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
fff727b2ad4bd81d64cd84c1b3509271d8320a48
 | 
			
		||||
6fac2a07a07edab552d2d2c7e0803d0524758bd1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue