Skip to content

Commit

Permalink
first pass at validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaimi committed Mar 22, 2021
1 parent 6caebf6 commit 459e8a0
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 25 deletions.
36 changes: 36 additions & 0 deletions UMAProject/Assets/UMA/Core/Editor/Scripts/AssetIndexerWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AssetIndexerWindow : EditorWindow
GenericMenu _FileMenu;
GenericMenu _AddressablesMenu;
GenericMenu _ItemsMenu;
GenericMenu _ToolsMenu;
bool ShowUtilities;
UMAMaterial Replacement;

Expand Down Expand Up @@ -53,6 +54,18 @@ private GenericMenu ItemsMenu
}
}

private GenericMenu ToolsMenu
{
get
{
if (_ToolsMenu == null)
{
SetupMenus();
}
return _ToolsMenu;
}
}

private GenericMenu AddressablesMenu
{
get
Expand Down Expand Up @@ -178,6 +191,7 @@ private void SetupMenus()
_FileMenu = new GenericMenu();
_AddressablesMenu = new GenericMenu();
_ItemsMenu = new GenericMenu();
_ToolsMenu = new GenericMenu();

AddPlugins(GetAddressablePlugins());

Expand Down Expand Up @@ -440,6 +454,28 @@ private void SetupMenus()
return;
});


AddMenuItemWithCallback(ToolsMenu, "Validate All Indexed Slots", () =>
{
EditorUtility.DisplayProgressBar("Validating", "Validating Slots", 0.0f);
List<SlotDataAsset> slots = UMAAssetIndexer.Instance.GetAllAssets<SlotDataAsset>();
List<SlotDataAsset> BadSlots = new List<SlotDataAsset>();

for(int i=0;i<slots.Count;i++)
{
SlotDataAsset sda = slots[i];
if (!sda.ValidateMeshData())
{
BadSlots.Add(sda);
}
float perc = (float)i /(float)slots.Count;
EditorUtility.DisplayProgressBar("Validating", "Validating Slots", perc);
}
return;
});



foreach (RaceData rc in UAI.GetAllAssets<RaceData>())
{
if (rc != null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#if UNITY_EDITOR
using System.Text;
using UnityEditorInternal;
#endif
using UnityEngine;
Expand All @@ -16,8 +17,55 @@ public partial class SlotDataAsset : ScriptableObject, ISerializationCallbackRec
public string slotName;
[System.NonSerialized]
public int nameHash;

#if UNITY_EDITOR
public ReorderableList tagList { get; set; }
private StringBuilder errorBuilder = new StringBuilder();


public bool HasErrors
{
get
{
return (!string.IsNullOrEmpty(Errors));
}
}
public string Errors;

/// <summary>
/// Returns true if meshdata is valid or null (a utility slot).
/// </summary>
/// <returns></returns>
public bool ValidateMeshData()
{
Errors = "";
errorBuilder.Clear();

if (meshData == null)
{
return true;
}
if (material == null)
{
AddError("material is null. A valid UMAMaterial that matches the overlay should be assigned.");
}
Errors = meshData.Validate();
return true;
}

private void AddError(string v)
{
if (errorBuilder.Length == 0)
{
errorBuilder.Append(v);
}
else
{
errorBuilder.Append("; ");
errorBuilder.Append(v);
}
}

public ReorderableList tagList { get; set; }
public bool tagListInitialized { get; set; } = false;
public bool eventsFoldout { get; set; } = false;
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,11 @@ public void UpdateMeshHideMasks()
if (MeshHideDictionary.ContainsKey(sd.slotName))
{ //If this slotDataAsset is found in the MeshHideDictionary then we need to supply the SlotData with the bitArray.
sd.meshHideMask = MeshHideAsset.GenerateMask(MeshHideDictionary[sd.slotName]);

if (sd.meshHideMask.Length != sd.asset.meshData.submeshes[sd.asset.subMeshIndex].triangles.Length)
{
var mha = MeshHideDictionary[sd.slotName];
}
}
}
}
Expand Down
126 changes: 102 additions & 24 deletions UMAProject/Assets/UMA/Core/StandardAssets/UMA/Scripts/UMAMeshData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using UnityEngine.Profiling;
using Unity.Collections;
using UnityEngine.Serialization;
using System.Text;

namespace UMA
{
Expand Down Expand Up @@ -241,6 +242,7 @@ public class UMAMeshData
static List<Color32> gColors32 = new List<Color32>(MAX_VERTEX_COUNT);
static Color32[] gColors32Array;

/*
const int UNUSED_SUBMESH = -1;
static List<int>[] gSubmeshTris = {
// Order gSubmeshTris list from smallest to largest so they can be
Expand All @@ -265,7 +267,7 @@ public class UMAMeshData
UNUSED_SUBMESH,
UNUSED_SUBMESH,
UNUSED_SUBMESH
};
}; */

// They forgot the List<> method for bone weights.
#if USE_UNSAFE_CODE
Expand Down Expand Up @@ -309,6 +311,7 @@ public bool ClaimSharedBuffers()
gColors32Array = gColors32.GetBackingArray();
if (gColors32Array == null) haveBackingArrays = false;

/*
gSubmeshTriIndices = new int[gSubmeshTris.Length];
gSubmeshTriArrays = new int[gSubmeshTris.Length][];
for (int i = 0; i < gSubmeshTris.Length; i++)
Expand All @@ -322,7 +325,7 @@ public bool ClaimSharedBuffers()
{
if (Debug.isDebugBuild)
Debug.LogError("Unable to access backing arrays for shared UMAMeshData!");
}
}*/
}

if (!haveBackingArrays)
Expand Down Expand Up @@ -355,22 +358,6 @@ public bool ClaimSharedBuffers()
/// <returns>Either a shared or allocated int array for submesh triangles.</returns>
public int[] GetSubmeshBuffer(int size, int submeshIndex)
{
if (OwnSharedBuffers())
{
for (int i = 0; i < gSubmeshTris.Length; i++)
{
if ((gSubmeshTriIndices[i] == UNUSED_SUBMESH) && (size < gSubmeshTris[i].Capacity))
{
gSubmeshTriIndices[i] = submeshIndex;
gSubmeshTris[i].SetActiveSize(size);
return gSubmeshTriArrays[i];
}
}

if (Debug.isDebugBuild)
Debug.LogWarning("Could not claim shared submesh buffer of size: " + size);
}

return new int[size];
}

Expand Down Expand Up @@ -398,11 +385,12 @@ public void ReleaseSharedBuffers()
gColors32.SetActiveSize(0);
colors32 = null;

/*
for (int i = 0; i < gSubmeshTris.Length; i++)
{
gSubmeshTriIndices[i] = UNUSED_SUBMESH;
gSubmeshTris[i].SetActiveSize(0);
}
} */

bufferLockOwner = null;
}
Expand Down Expand Up @@ -671,24 +659,28 @@ public void ApplyDataToUnityMesh(SkinnedMeshRenderer renderer, UMASkeleton skele
mesh.subMeshCount = subMeshCount;
for (int i = 0; i < subMeshCount; i++)
{
/*
bool sharedBuffer = false;
for (int j = 0; j < gSubmeshTris.Length; j++)
{
if (gSubmeshTriIndices[j] == i)
{
sharedBuffer = true;
#if VALIDATE_TRIANGLES
#else
#endif
mesh.SetTriangles(gSubmeshTris[j], i);
gSubmeshTriIndices[j] = UNUSED_SUBMESH;
break;
}
}
if (!sharedBuffer)
mesh.SetTriangles(submeshes[i].triangles, i);
if (!sharedBuffer)*/
mesh.SetTriangles(submeshes[i].triangles, i);
}

//Apply the blendshape data from the slot asset back to the combined UMA unity mesh.
#region Blendshape
#region Blendshape
mesh.ClearBlendShapes();
if (blendShapes != null && blendShapes.Length > 0)
{
Expand Down Expand Up @@ -721,7 +713,7 @@ public void ApplyDataToUnityMesh(SkinnedMeshRenderer renderer, UMASkeleton skele
}
}
}
#endregion
#endregion

mesh.RecalculateBounds();
renderer.bones = bones != null ? bones : skeleton.HashesToTransforms(boneNameHashes);
Expand Down Expand Up @@ -1185,6 +1177,92 @@ public UMAMeshData DeepCopy()
newMeshData.RootBoneName = RootBoneName;

return newMeshData;
}
}

#if UNITY_EDITOR
internal string Validate()
{
StringBuilder errors = new StringBuilder();

if (vertices.Length != vertexCount)
{
errors.Append("; Vertices length of " + vertices.Length+" != vertexCount (" +vertexCount+ ")");
}
if (normals != null && normals.Length != vertices.Length)
{
errors.Append("; Normals length of " + normals.Length + " != vertexCount (" + vertexCount + ")");
}
if (tangents != null && tangents.Length != vertices.Length)
{
errors.Append("; tangents length of " + tangents.Length + " != vertexCount (" + vertexCount + ")");
}
if (colors32 != null && colors32.Length != vertices.Length)
{
errors.Append("; colors32 length of " + colors32.Length + " != vertexCount (" + vertexCount + ")");
}
if (uv != null && uv.Length != vertices.Length)
{
errors.Append("; uv length of " + tangents.Length + " != vertexCount (" + vertexCount + ")");
}
if (uv2 != null && uv2.Length != vertices.Length)
{
errors.Append("; uv2 length of " + uv2.Length + " != vertexCount (" + vertexCount + ")");
}
if (ManagedBonesPerVertex != null && ManagedBonesPerVertex.Length != vertices.Length)
{
errors.Append("; ManagedBonesPerVertex length of " + ManagedBonesPerVertex.Length + " != vertexCount (" + vertexCount + ")");
}

if (ManagedBoneWeights != null)
{
foreach(BoneWeight1 bw in ManagedBoneWeights)
{
if (bw.boneIndex >= bones.Length)
{
errors.Append("; Boneweight references invalid bone index "+bw.boneIndex);
break;
}
}
}

if (umaBones.Length != umaBoneCount)
{
errors.Append("; umaBones != umaBoneCount");
}

if (submeshes == null)
{
errors.Append("; Meshdata has no submeshes");
}
else
{
if (submeshes.Length == 0)
{
errors.Append("; Meshdata submesh length == 0");
}
else
{
for (int i = 0; i < submeshes.Length; i++)
{
SubMeshTriangles smt = submeshes[i];
foreach(int tri in smt.triangles)
{
if (tri >= vertexCount)
{
errors.Append("; triangle "+tri+" out of bounds on submesh " + i);
break;
}
}
}
}
}

if (errors.Length > 0)
{
errors.Remove(0, 2);
}
return errors.ToString();
}
#endif
}
}

0 comments on commit 459e8a0

Please sign in to comment.