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
Binary file not shown.
|
@ -54,7 +54,7 @@ Here's a brief overview of what's included in this mod
|
||||||
- 2 animations for group sex
|
- 2 animations for group sex
|
||||||
- Animated hands for certain animations
|
- Animated hands for certain animations
|
||||||
- The option to have pawns in varying states of dress during sex (ranging from fully nude to almost entirely clothed)
|
- The option to have pawns in varying states of dress during sex (ranging from fully nude to almost entirely clothed)
|
||||||
- Apparel can be masked so that the bottom halves of pawns are visible when not wearing pants
|
- Apparel textures can be dynamically cropped, so that the bottom halves of pawns (and their bits) can be more easily seen when they are not wearing pants
|
||||||
- The option to hide the names of pawns while they have sex
|
- The option to hide the names of pawns while they have sex
|
||||||
- Automatic position scaling, to improve animations involving alien races which are larger or smaller than normal
|
- Automatic position scaling, to improve animations involving alien races which are larger or smaller than normal
|
||||||
- A GUI for customizing how RimNude body parts should be displayed when wearing different types of apparel, as well as toggling what apparel should be worn while having sex
|
- A GUI for customizing how RimNude body parts should be displayed when wearing different types of apparel, as well as toggling what apparel should be worn while having sex
|
||||||
|
@ -64,9 +64,8 @@ A full list of changes can be found in the main discussion thread on the forum
|
||||||
Known issues
|
Known issues
|
||||||
- For best results, turn off texture caching (this can be done by adding the Vanilla Expanded Framework to your mod list and enabling its 'Disable Texture Caching' setting)
|
- For best results, turn off texture caching (this can be done by adding the Vanilla Expanded Framework to your mod list and enabling its 'Disable Texture Caching' setting)
|
||||||
- The animations in this mod do not play any voices from Tory's VoicePatch mod
|
- The animations in this mod do not play any voices from Tory's VoicePatch mod
|
||||||
- Apparel masking cannot be used with the Sized Apparel mod
|
|
||||||
- This mod will result in floating body parts when using Pawnmorpher's 'Pawn scaling' setting
|
- This mod will result in floating body parts when using Pawnmorpher's 'Pawn scaling' setting
|
||||||
- If you're having some issues with frame rates on large colonies, try disabling hand rendering
|
- If you're having some issues with frame/tick rates on large colonies, try disabling hand rendering and/or apparel cropping
|
||||||
</description>
|
</description>
|
||||||
</ModMetaData>
|
</ModMetaData>
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
Change log v 2.0.2
|
||||||
|
- Implemented texture caching to reduce the performance hit induced by dynamically cropping apparel
|
||||||
|
- Dynamically cropping apparel is now compatible with Sized Apparel
|
||||||
|
|
||||||
Change log v 2.0.1
|
Change log v 2.0.1
|
||||||
- Fixed issue with a hand animation calling a missing method
|
- Fixed issue with a hand animation calling a missing method
|
||||||
- Fixed errored that was triggering at the end of sex
|
- Fixed errored that was triggering at the end of sex
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<Manifest>
|
<Manifest>
|
||||||
<version>2.0.1</version>
|
<version>2.0.2</version>
|
||||||
<downloadUri>https://gitgud.io/AbstractConcept/rimworld-animations-patch</downloadUri>
|
<downloadUri>https://gitgud.io/AbstractConcept/rimworld-animations-patch</downloadUri>
|
||||||
</Manifest>
|
</Manifest>
|
Binary file not shown.
|
@ -113,6 +113,7 @@
|
||||||
<Compile Include="Scripts\Comps\CompApparelVisibility.cs" />
|
<Compile Include="Scripts\Comps\CompApparelVisibility.cs" />
|
||||||
<Compile Include="Scripts\Comps\CompPawnSexData.cs" />
|
<Compile Include="Scripts\Comps\CompPawnSexData.cs" />
|
||||||
<Compile Include="Scripts\Defs\ActorAnimationData.cs" />
|
<Compile Include="Scripts\Defs\ActorAnimationData.cs" />
|
||||||
|
<Compile Include="Scripts\Defs\ApparelTexture2DPack.cs" />
|
||||||
<Compile Include="Scripts\Defs\BodyAddonData.cs" />
|
<Compile Include="Scripts\Defs\BodyAddonData.cs" />
|
||||||
<Compile Include="Scripts\Defs\HandAnimationDef.cs" />
|
<Compile Include="Scripts\Defs\HandAnimationDef.cs" />
|
||||||
<Compile Include="Scripts\Extensions\StringExtension.cs" />
|
<Compile Include="Scripts\Extensions\StringExtension.cs" />
|
||||||
|
|
|
@ -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)
|
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))
|
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>;
|
ApparelTexture2DPack pack = ApparelSettingsUtility.GetCachedApparelTextures(rec.graphic, bodyType);
|
||||||
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);
|
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);
|
if (pack.textures[i] == null) continue;
|
||||||
graphic = GraphicMaskingUtility.ApplyGraphicMasks(graphic, graphicWithApparelMasks, true);
|
rec.graphic.MatAt(new Rot4(i)).mainTexture = pack.textures[i];
|
||||||
|
|
||||||
//DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// Update all humanlike pawn graphics when settings window is closed
|
||||||
public void ApplySettings()
|
public void ApplySettings()
|
||||||
{
|
{
|
||||||
|
if (ApparelSettings.cropApparel == false)
|
||||||
|
{
|
||||||
|
DebugMode.Message("Clearing apparel texture cache");
|
||||||
|
ApparelSettingsUtility.ClearCachedApparelTextures();
|
||||||
|
}
|
||||||
|
|
||||||
if (Current.ProgramState == ProgramState.Playing)
|
if (Current.ProgramState == ProgramState.Playing)
|
||||||
{
|
{
|
||||||
foreach (Pawn pawn in Current.Game.CurrentMap.mapPawns.AllPawns)
|
foreach (Pawn pawn in Current.Game.CurrentMap.mapPawns.AllPawns)
|
||||||
|
|
|
@ -8,6 +8,30 @@ namespace Rimworld_Animations_Patch
|
||||||
{
|
{
|
||||||
public static class ApparelSettingsUtility
|
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()
|
public static List<ThingDef> GetApparelOfInterest()
|
||||||
{
|
{
|
||||||
List<ThingDef> thingDefs = new List<ThingDef>();
|
List<ThingDef> thingDefs = new List<ThingDef>();
|
||||||
|
|
|
@ -43,11 +43,8 @@ namespace Rimworld_Animations_Patch
|
||||||
|
|
||||||
public static Texture2D ApplyMaskToTexture2D(Texture2D mainTex, Texture2D maskTex, bool writeOverMainTex)
|
public static Texture2D ApplyMaskToTexture2D(Texture2D mainTex, Texture2D maskTex, bool writeOverMainTex)
|
||||||
{
|
{
|
||||||
if (mainTex == null || maskTex == null)
|
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; }
|
||||||
DebugMode.Message("mainTex or maskTex is missing!");
|
|
||||||
return mainTex;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color[] mainArray = GetReadableTexture2D(mainTex).GetPixels();
|
Color[] mainArray = GetReadableTexture2D(mainTex).GetPixels();
|
||||||
Color[] maskArray = GetReadableTexture2D(maskTex, mainTex.width, mainTex.height).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…
Reference in New Issue