add VRMBlendShapeProxyValidator

This commit is contained in:
ousttrue 2020-09-15 13:31:13 +09:00
parent e96fc796de
commit c26e3fa169
4 changed files with 111 additions and 24 deletions

View File

@ -0,0 +1,73 @@
using System.Collections.Generic;
using UnityEngine;
namespace VRM
{
public static class VRMBlendShapeProxyValidator
{
public static IEnumerable<Validation> Validate(this VRMBlendShapeProxy p)
{
if (p == null)
{
yield return Validation.Error("VRMBlendShapeProxy is null");
yield break;
}
if (p.BlendShapeAvatar == null)
{
yield return Validation.Error("BlendShapeAvatar is null");
yield break;
}
// presetがユニークか
var used = new HashSet<BlendShapeKey>();
foreach (var c in p.BlendShapeAvatar.Clips)
{
var key = c.Key;
if (used.Contains(key))
{
yield return Validation.Error($"duplicated BlendShapeKey: {c}");
}
else
{
used.Add(key);
}
}
var materialNames = new HashSet<string>();
foreach (var r in p.GetComponentsInChildren<Renderer>(true))
{
foreach (var m in r.sharedMaterials)
{
if (!materialNames.Contains(m.name))
{
materialNames.Add(m.name);
}
}
}
// 参照が生きているか
foreach (var c in p.BlendShapeAvatar.Clips)
{
for (int i = 0; i < c.Values.Length; ++i)
{
var v = c.Values[i];
var target = p.transform.Find(v.RelativePath);
if (target == null)
{
yield return Validation.Error($"{c}.Values[{i}].RelativePath({v.RelativePath} is not found");
}
}
for (int i = 0; i < c.MaterialValues.Length; ++i)
{
var v = c.MaterialValues[i];
if (!materialNames.Contains(v.MaterialName))
{
yield return Validation.Error($"{c}.MaterialValues[{i}].MaterialName({v.MaterialName} is not found");
}
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50a28b39ccee4874b85d99c095180e5a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -182,7 +182,7 @@ namespace VRM
}
/// <summary>
/// エクスポート可能か検証する
/// エクスポート可能か検証する
/// </summary>
/// <returns></returns>
public void Validate(GameObject ExportRoot, VRMExportSettings m_settings, VRMMetaObject meta)
@ -192,34 +192,35 @@ namespace VRM
{
return;
}
var proxy = ExportRoot.GetComponent<VRMBlendShapeProxy>();
m_validations.AddRange(_Validate(ExportRoot, m_settings));
if (ExportRoot != null)
m_validations.AddRange(VRMSpringBoneValidator.Validate(ExportRoot));
var firstPerson = ExportRoot.GetComponent<VRMFirstPerson>();
if (firstPerson != null)
{
m_validations.AddRange(VRMSpringBoneValidator.Validate(ExportRoot));
var firstPerson = ExportRoot.GetComponent<VRMFirstPerson>();
if (firstPerson != null)
m_validations.AddRange(firstPerson.Validate());
}
if (proxy != null)
{
m_validations.AddRange(proxy.Validate());
// Export サイズ の 計算
var clips = new List<BlendShapeClip>();
if (proxy.BlendShapeAvatar != null)
{
m_validations.AddRange(firstPerson.Validate());
clips.AddRange(proxy.BlendShapeAvatar.Clips);
}
ExpectedByteSize = 0;
foreach (var renderer in ExportRoot.GetComponentsInChildren<Renderer>())
{
var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, ExportRoot.transform);
var mesh = GetMesh(renderer);
ExpectedByteSize += CalcMeshSize(relativePath, mesh, m_settings, clips);
}
}
MetaHasError = meta.Validate().Any();
// サイズ の 計算
var proxy = ExportRoot.GetComponent<VRMBlendShapeProxy>();
var clips = new List<BlendShapeClip>();
if (proxy != null && proxy.BlendShapeAvatar != null)
{
clips.AddRange(proxy.BlendShapeAvatar.Clips);
}
ExpectedByteSize = 0;
foreach (var renderer in ExportRoot.GetComponentsInChildren<Renderer>())
{
var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, ExportRoot.transform);
var mesh = GetMesh(renderer);
ExpectedByteSize += CalcMeshSize(relativePath, mesh, m_settings, clips);
}
}
static bool ClipsContainsName(List<BlendShapeClip> clips, bool onlyPreset, BlendShapeBinding binding)

View File

@ -178,6 +178,8 @@ namespace VRM
if (Event.current.type == EventType.Layout)
{
// ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint Aborting
// Validation により GUI の表示項目が変わる場合があるので、
// EventType.Layout と EventType.Repaint 間で内容が変わらないようしている。
if (m_requireValidation)
{
m_validator.Validate(ExportRoot, m_settings, Meta != null ? Meta : m_tmpMeta);
@ -186,7 +188,7 @@ namespace VRM
}
//
// 事前チェック。ここで失敗する場合は Export UI を表示しない
// Humanoid として適正か? ここで失敗する場合は Export UI を表示しない
//
if (!m_validator.RootAndHumanoidCheck(ExportRoot, m_settings))
{
@ -202,7 +204,7 @@ namespace VRM
GUIUtility.GetControlID(645789, FocusType.Passive);
//
// その他の Validation
// VRM の Validation
//
foreach (var v in m_validator.Validations)
{