Skip to content

Commit

Permalink
Merge pull request #442 from umasteeringgroup/Feature-13
Browse files Browse the repository at this point in the history
Feature 13
  • Loading branch information
Jaimi authored Jun 12, 2024
2 parents bd94a2d + f134cd1 commit 2a2658c
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 75 deletions.
8 changes: 0 additions & 8 deletions UMAProject/Assets/Plugins.meta

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.IO;
using UMA.Examples;
using UMA.PoseTools;
using static UMA.UMAData;
using UnityEngine.Experimental.Rendering;

namespace UMA.Editors
{
Expand Down Expand Up @@ -185,7 +187,7 @@ public static void ConvertToNonUMA(GameObject baseObject, UMAAvatarBase avatar,
}


[UnityEditor.MenuItem("GameObject/UMA/Save Atlas Textures (runtime only)")]
[UnityEditor.MenuItem("GameObject/UMA/Save Atlas Textures")]
[MenuItem("CONTEXT/DynamicCharacterAvatar/Save Selected Avatars generated textures to PNG", false, 10)]
[MenuItem("UMA/Runtime/Save Selected Avatar Atlas Textures")]
public static void SaveSelectedAvatarsPNG()
Expand Down Expand Up @@ -217,6 +219,38 @@ public static void SaveSelectedAvatarsPNG()
{
string basename = System.IO.Path.GetFileNameWithoutExtension(path);
string pathname = System.IO.Path.GetDirectoryName(path);

// Get the UMAMaterials for each atlas.

UMAData umaData = avatar.umaData;
GeneratedMaterials gmatContainer = umaData.generatedMaterials;

int i = 0;
foreach (var gm in gmatContainer.materials)
{
UMAMaterial umat = gm.umaMaterial;
Material mat = gm.skinnedMeshRenderer.sharedMaterials[gm.materialIndex];
Material omat = gm.material;
foreach(var tex in umat.GetTexturePropertyNames())
{
Texture texture = mat.GetTexture(tex);
if (texture != null)
{
string tname = $"{pathname}/{basename}_{i}_{umat.name}{tex}.PNG";
try
{
SaveTexture(texture, tname);
}
catch
{
// Not a readable texture. This is actually OK. Wish isReadable wasn't broken.
}
}
}
i++;
}

/*
// save the diffuse texture
for (int i = 0; i < smr.materials.Length; i++)
{
Expand All @@ -234,8 +268,8 @@ public static void SaveSelectedAvatarsPNG()
SaveTexture(texture, texname);
}
}
}
}
}*/
}
}

private static void SaveTexture(Texture texture, string diffuseName, bool isNormal = false)
Expand Down Expand Up @@ -315,6 +349,9 @@ private static Texture2D sconvertNormalMap(Texture tex)

static public Texture2D GetRTPixels(RenderTexture rt)
{
// Remember crrently active render texture
RenderTexture currentActiveRT = RenderTexture.active;

/// Some goofiness ends up with the texture being too dark unless
/// I send it to a new render texture.
RenderTexture outputMap = new RenderTexture(rt.width, rt.height, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
Expand All @@ -325,8 +362,6 @@ static public Texture2D GetRTPixels(RenderTexture rt)
Graphics.Blit(rt, outputMap);


// Remember crrently active render texture
RenderTexture currentActiveRT = RenderTexture.active;

// Set the supplied RenderTexture as the active one
RenderTexture.active = outputMap;
Expand Down Expand Up @@ -376,15 +411,14 @@ public static void SaveRenderTexture(RenderTexture texture, string textureName,

private static void SaveTexture2D(Texture2D texture, string textureName)
{
if (texture.isReadable)
{
byte[] data = texture.EncodeToPNG();
// ?? texture.isReadable seems to always return true, regardless of whether the texture is readable or not
// so we'll just try to encode it and see if it throws an exception
// This didn't use to be the case, and may be fixed in various Unity versions...
//if (texture.isReadable)
{
byte[] data = texture.EncodeToPNG();
System.IO.File.WriteAllBytes(textureName, data);
}
else
{
Debug.LogError("Texture: " + texture.name + " is not readable. Skipping.");
}
}

[UnityEditor.MenuItem("CONTEXT/DynamicCharacterAvatar/Save as UMA Preset")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public string ToCompressedString(string seperator = "\n")
theString.Append(scd.name);
theString.Append(',');
theString.Append(scd.count);
theString.Append('=');
theString.Append('>');
for (int i1 = 0; i1 < scd.channels.Length; i1++)
{
ColorDef c = scd.channels[i1];
Expand All @@ -256,8 +256,9 @@ public string ToCompressedString(string seperator = "\n")
theString.Append(';');
}
}
theString.Append(seperator);
theString.Append('<');
}
theString.Append(seperator);
}

if (Dna != null)
Expand Down Expand Up @@ -386,7 +387,7 @@ public static AvatarDefinition FromCompressedStringV2(string compressed,char sep
AvatarDefinition adf = new AvatarDefinition();
splitter[0] = seperator;
string[] SplitLines = compressed.Split(splitter);
List<SharedColorDef> Colors = new List<SharedColorDef>();
// List<SharedColorDef> Colors = new List<SharedColorDef>();

for (int i = 0; i < SplitLines.Length; i++)
{
Expand All @@ -409,57 +410,7 @@ public static AvatarDefinition FromCompressedStringV2(string compressed,char sep
break;
case 'C':
// Unpack Colors
splitter[0] = '=';
string[] SharedColor = s.Substring(2).Trim().Split(splitter, StringSplitOptions.RemoveEmptyEntries);
if (SharedColor.Length > 1)
{
SharedColorDef scd = new SharedColorDef();
List<string> ShaderParms = new List<string>();
splitter[0] = ',';
string[] maincol = SharedColor[0].Split(splitter, StringSplitOptions.RemoveEmptyEntries);
if (maincol.Length > 1)
{
scd.name = maincol[0];
scd.count = Convert.ToInt32(maincol[1]);

splitter[0] = ';';
string[] ColorDefs = SharedColor[1].Split(splitter, StringSplitOptions.RemoveEmptyEntries);
List<ColorDef> theColors = new List<ColorDef>();
if (ColorDefs != null)
{
if (ColorDefs.Length > 0)
{
for (int i1 = 0; i1 < ColorDefs.Length; i1++)
{
if (String.IsNullOrEmpty(ColorDefs[i1]))
continue;
if (ColorDefs[i1][0] == 'P')
{
ShaderParms.Add(Base64Decode(ColorDefs[i1].Substring(2)));
continue;
}
string c = ColorDefs[i1];
splitter[0] = ',';
string[] vals = c.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
if (vals.Length == 2)
{
ColorDef cdef = new ColorDef(Convert.ToInt32(vals[0]), Convert.ToUInt32(vals[1], 16), 0);
theColors.Add(cdef);
}
else if (vals.Length == 3)
{
ColorDef cdef = new ColorDef(Convert.ToInt32(vals[0]), Convert.ToUInt32(vals[1], 16), Convert.ToUInt32(vals[2], 16));
theColors.Add(cdef);
}
}
}

}
scd.channels = theColors.ToArray();
scd.shaderParms = ShaderParms.ToArray();
Colors.Add(scd);
}
}
adf.Colors = UnpackColors(s);
break;
case 'D':
// Unpack DNA
Expand All @@ -485,10 +436,75 @@ public static AvatarDefinition FromCompressedStringV2(string compressed,char sep
}
}

adf.Colors = Colors.ToArray();
//adf.Colors = Colors.ToArray();
return adf;
}

private static SharedColorDef[] UnpackColors(string s)
{
List<SharedColorDef> colors = new List<SharedColorDef>();

string[] encodedColors = s.Split(new char[] { '<' }, StringSplitOptions.RemoveEmptyEntries);


return colors.ToArray();
}

private static void UnpackAColor(char[] splitter, List<SharedColorDef> Colors, string s)
{
splitter[0] = '>';
string[] SharedColor = s.Substring(2).Trim().Split(splitter, StringSplitOptions.RemoveEmptyEntries);
if (SharedColor.Length > 1)
{
SharedColorDef scd = new SharedColorDef();
List<string> ShaderParms = new List<string>();
splitter[0] = ',';
string[] maincol = SharedColor[0].Split(splitter, StringSplitOptions.RemoveEmptyEntries);
if (maincol.Length > 1)
{
scd.name = maincol[0];
scd.count = Convert.ToInt32(maincol[1]);

splitter[0] = ';';
string[] ColorDefs = SharedColor[1].Split(splitter, StringSplitOptions.RemoveEmptyEntries);
List<ColorDef> theColors = new List<ColorDef>();
if (ColorDefs != null)
{
if (ColorDefs.Length > 0)
{
for (int i1 = 0; i1 < ColorDefs.Length; i1++)
{
if (String.IsNullOrEmpty(ColorDefs[i1]))
continue;
if (ColorDefs[i1][0] == 'P')
{
ShaderParms.Add(Base64Decode(ColorDefs[i1].Substring(2)));
continue;
}
string c = ColorDefs[i1];
splitter[0] = ',';
string[] vals = c.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
if (vals.Length == 2)
{
ColorDef cdef = new ColorDef(Convert.ToInt32(vals[0]), Convert.ToUInt32(vals[1], 16), 0);
theColors.Add(cdef);
}
else if (vals.Length == 3)
{
ColorDef cdef = new ColorDef(Convert.ToInt32(vals[0]), Convert.ToUInt32(vals[1], 16), Convert.ToUInt32(vals[2], 16));
theColors.Add(cdef);
}
}
}

}
scd.channels = theColors.ToArray();
scd.shaderParms = ShaderParms.ToArray();
Colors.Add(scd);
}
}
}

// Ascii version of the string. Not as good as binary formatter,
// but 1/2 the size of a string.
public byte[] ToASCIIString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,21 @@ public static void CreateMaterialAsset()
}
#endif

public List<string> GetTexturePropertyNames()
{
List<string> names = new List<string>();


foreach (MaterialChannel channel in channels)
{
if (channel.channelType == ChannelType.Texture || channel.channelType == ChannelType.TintedTexture || channel.channelType == ChannelType.DiffuseTexture)
{
names.Add(channel.materialPropertyName);
}
}
return names;
}

private bool isGeneratedTextures
{
get
Expand Down

0 comments on commit 2a2658c

Please sign in to comment.