Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MeshWithRenderer を MeshExportInfo に統合 #1005

Merged
merged 7 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ protected override IEnumerable<Validator> ValidatorFactory()

protected override void OnLayout()
{
m_meshes.SetRoot(State.ExportRoot, m_settings.MeshExportSettings);
m_meshes.SetRoot(State.ExportRoot, m_settings.MeshExportSettings, new DefualtBlendShapeExportFilter());
}

protected override bool DoGUI(bool isValid)
Expand Down
154 changes: 9 additions & 145 deletions Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,148 +31,12 @@ public static Mesh GetMesh(Renderer r)

public int ExpectedExportByteSize => Meshes.Where(x => x.IsRendererActive).Sum(x => x.ExportByteSize);

public MeshExportSettings Settings;

public virtual bool UseBlendShape(int index, string relativePath) => true;

public virtual void CalcMeshSize(ref MeshExportInfo info,
string relativePath)
{
var sb = new StringBuilder();
if (!info.IsRendererActive)
{
sb.Append("[NotActive]");
}

info.VertexCount = info.Mesh.vertexCount;
info.ExportVertexSize = 0;
info.TotalBlendShapeCount = 0;
info.ExportBlendShapeCount = 0;

// float4 x 3
// vertices
sb.Append($"(Pos");
if (info.HasNormal)
{
sb.Append("+Nom");
info.ExportVertexSize += 4 * 3;
}
if (info.HasUV)
{
sb.Append("+UV");
info.ExportVertexSize += 4 * 2;
}
if (info.HasVertexColor)
{
sb.Append("+Col");
info.ExportVertexSize += 4 * 4;
}
if (info.HasSkinning)
{
// short, float x 4 weights
sb.Append("+Skin");
info.ExportVertexSize += (2 + 4) * 4;
}
// indices
info.IndexCount = info.Mesh.triangles.Length;

// postion + normal ?. always tangent is ignored
info.TotalBlendShapeCount = info.Mesh.blendShapeCount;
info.ExportBlendShapeVertexSize = Settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3);
for (var i = 0; i < info.Mesh.blendShapeCount; ++i)
{
if (!UseBlendShape(i, relativePath))
{
continue;
}

++info.ExportBlendShapeCount;
}

if (info.ExportBlendShapeCount > 0)
{
sb.Append($"+Morph x {info.ExportBlendShapeCount}");
}
sb.Append($") x {info.Mesh.vertexCount}");
switch (info.VertexColor)
{
case VertexColorState.ExistsAndIsUsed:
case VertexColorState.ExistsAndMixed: // エクスポートする
sb.Insert(0, "[use vcolor]");
break;
case VertexColorState.ExistsButNotUsed:
sb.Insert(0, "[remove vcolor]");
break;
}
if (info.ExportBlendShapeCount > 0 && !info.HasSkinning)
{
sb.Insert(0, "[morph without skin]");
}

// total bytes
sb.Insert(0, $"{info.ExportByteSize:#,0} Bytes = ");
info.Summary = sb.ToString();
}

bool TryGetMeshInfo(GameObject root, Renderer renderer, out MeshExportInfo info)
{
info = default;
if (root == null)
{
info.Summary = "";
return false;
}
if (renderer == null)
{
info.Summary = "no Renderer";
return false;
}
info.Renderer = renderer;

if (renderer is SkinnedMeshRenderer smr)
{
info.Skinned = true;
info.Mesh = smr.sharedMesh;
info.IsRendererActive = smr.EnableForExport();
}
else if (renderer is MeshRenderer mr)
{
var filter = mr.GetComponent<MeshFilter>();
if (filter != null)
{
info.Mesh = filter.sharedMesh;
}
info.IsRendererActive = mr.EnableForExport();
}
else
{
info.Summary = "no Mesh";
return false;
}

info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Renderer.sharedMaterials);

var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform);
CalcMeshSize(ref info, relativePath);

return true;
}

public void SetRoot(GameObject ExportRoot, MeshExportSettings settings)
public void SetRoot(GameObject ExportRoot, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter)
{
Settings = settings;
Meshes.Clear();
if (ExportRoot == null)
MeshExportInfo.GetInfo(ExportRoot.transform.Traverse().Skip(1), Meshes, settings);
foreach(var info in Meshes)
{
return;
}

foreach (var renderer in ExportRoot.GetComponentsInChildren<Renderer>(true))
{
if (TryGetMeshInfo(ExportRoot, renderer, out MeshExportInfo info))
{
Meshes.Add(info);
}
info.CalcMeshSize(ExportRoot, info.Renderers[0].Item1, settings, blendShapeFilter);
}
}

Expand Down Expand Up @@ -204,28 +68,28 @@ public IEnumerable<Validation> Validate(GameObject ExportRoot)
foreach (var info in Meshes)
{
// invalid materials.len
if (info.Renderer.sharedMaterials.Length < info.Mesh.subMeshCount)
if (info.Materials.Length < info.Mesh.subMeshCount)
{
// submesh より material の方が少ない
yield return Validation.Error(Messages.MATERIALS_LESS_THAN_SUBMESH_COUNT.Msg());
}
else
{
if (info.Renderer.sharedMaterials.Length > info.Mesh.subMeshCount)
if (info.Materials.Length > info.Mesh.subMeshCount)
{
// submesh より material の方が多い
yield return Validation.Warning(Messages.MATERIALS_GREATER_THAN_SUBMESH_COUNT.Msg());
}

if (info.Renderer.sharedMaterials.Take(info.Mesh.subMeshCount).Any(x => x == null))
if (info.Materials.Take(info.Mesh.subMeshCount).Any(x => x == null))
{
// material に null が含まれる(unity で magenta になっているはず)
yield return Validation.Error($"{info.Renderer}: {Messages.MATERIALS_CONTAINS_NULL.Msg()}");
yield return Validation.Error($"{info.Renderers}: {Messages.MATERIALS_CONTAINS_NULL.Msg()}");
}
}
}

foreach (var m in Meshes.SelectMany(x => x.Renderer.sharedMaterials).Distinct())
foreach (var m in Meshes.SelectMany(x => x.Materials).Distinct())
{
if (m == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@ void DrawElement(int i, UniGLTF.MeshExportInfo info)
var (left, right) = LeftRight(r.x, r.y, col0, r.width - col0, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(left, $"{i,3}");

GUI.enabled = false;
EditorGUI.ObjectField(right, info.Renderer, info.Renderer.GetType(), true);

right.y += EditorGUIUtility.singleLineHeight;
EditorGUI.ObjectField(right, info.Mesh, info.Renderer.GetType(), true);
GUI.enabled = true;
using (new EditorGUI.DisabledScope(false))
{
foreach (var (renderer, _) in info.Renderers)
{
EditorGUI.ObjectField(right, renderer, info.Renderers.GetType(), true);
}
right.y += EditorGUIUtility.singleLineHeight;
EditorGUI.ObjectField(right, info.Mesh, info.Renderers.GetType(), true);
}

right.y += EditorGUIUtility.singleLineHeight;
EditorGUI.LabelField(right, info.Summary);
Expand Down
12 changes: 11 additions & 1 deletion Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public static Transform GetFromPath(this Transform self, string path)
{
var current = self;

var split = path.Split(new [] {'/'}, StringSplitOptions.RemoveEmptyEntries);
var split = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

foreach (var childName in split)
{
Expand Down Expand Up @@ -334,5 +334,15 @@ public static T GetOrAddComponent<T>(this GameObject go) where T : Component
}
return go.AddComponent<T>();
}

public static bool EnableForExport(this Component mono)
{
if (mono.transform.Ancestors().Any(x => !x.gameObject.activeSelf))
{
// 自分か祖先に !activeSelf がいる
return false;
}
return true;
}
}
}
18 changes: 18 additions & 0 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace UniGLTF
{
public interface IBlendShapeExportFilter
{
bool UseBlendShape(int blendShapeIndex, string relativePath);
}

public class DefualtBlendShapeExportFilter : IBlendShapeExportFilter
{
/// <summary>
/// Export all blendshape
/// </summary>
/// <param name="blendShapeIndex"></param>
/// <param name="relativePath"></param>
/// <returns></returns>
public bool UseBlendShape(int blendShapeIndex, string relativePath) => true;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading