121 lines
4.0 KiB
C#
121 lines
4.0 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UniGLTF.M17N;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace UniGLTF.MeshUtility
|
|
{
|
|
public static class TabMeshIntegrator
|
|
{
|
|
public static bool TryExecutable(GameObject root, out string msg)
|
|
{
|
|
// check
|
|
if (root == null)
|
|
{
|
|
msg = MeshProcessingMessages.NO_GAMEOBJECT_SELECTED.Msg();
|
|
return false;
|
|
}
|
|
|
|
if (HasVrm(root))
|
|
{
|
|
msg = MeshProcessingMessages.VRM_DETECTED.Msg();
|
|
return false;
|
|
}
|
|
|
|
if (root.GetComponentsInChildren<SkinnedMeshRenderer>().Length == 0 && root.GetComponentsInChildren<MeshFilter>().Length == 0)
|
|
{
|
|
msg = MeshProcessingMessages.NO_MESH.Msg();
|
|
return false;
|
|
}
|
|
|
|
msg = "";
|
|
return true;
|
|
}
|
|
|
|
const string VRM_META = "VRMMeta";
|
|
static bool HasVrm(GameObject root)
|
|
{
|
|
var allComponents = root.GetComponents(typeof(Component));
|
|
foreach (var component in allComponents)
|
|
{
|
|
if (component == null) continue;
|
|
var sourceString = component.ToString();
|
|
if (sourceString.Contains(VRM_META))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const string ASSET_SUFFIX = ".mesh.asset";
|
|
|
|
static string GetMeshWritePath(Mesh mesh)
|
|
{
|
|
if (!string.IsNullOrEmpty((AssetDatabase.GetAssetPath(mesh))))
|
|
{
|
|
var directory = Path.GetDirectoryName(AssetDatabase.GetAssetPath(mesh)).Replace("\\", "/");
|
|
return $"{directory}/{Path.GetFileNameWithoutExtension(mesh.name)}{ASSET_SUFFIX}";
|
|
}
|
|
else
|
|
{
|
|
return $"Assets/{Path.GetFileNameWithoutExtension(mesh.name)}{ASSET_SUFFIX}";
|
|
}
|
|
}
|
|
|
|
/// <param name="src">GameObject instance in scene or prefab</param>
|
|
public static bool Execute(GameObject src, bool onlyBlendShapeRenderers)
|
|
{
|
|
var results = new List<MeshIntegrationResult>();
|
|
|
|
// instance or prefab => copy
|
|
var copy = GameObject.Instantiate(src);
|
|
copy.name = copy.name + "_mesh_integration";
|
|
|
|
// integrate
|
|
if (onlyBlendShapeRenderers)
|
|
{
|
|
results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithBlendShape));
|
|
results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithoutBlendShape));
|
|
}
|
|
else
|
|
{
|
|
results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.All));
|
|
}
|
|
|
|
// replace
|
|
MeshIntegratorUtility.ReplaceMeshWithResults(copy, results);
|
|
|
|
// write mesh asset.
|
|
foreach (var result in results)
|
|
{
|
|
var mesh = result.IntegratedRenderer.sharedMesh;
|
|
var assetPath = GetMeshWritePath(mesh);
|
|
Debug.LogFormat("CreateAsset: {0}", assetPath);
|
|
AssetDatabase.CreateAsset(mesh, assetPath);
|
|
}
|
|
|
|
if (src.GetGameObjectType() == GameObjectType.AssetPrefab)
|
|
{
|
|
// write prefab.
|
|
{
|
|
var prefabPath = UnityPath.FromAsset(src);
|
|
prefabPath = prefabPath.Parent.Child($"{prefabPath.FileNameWithoutExtension}_integrated.prefab");
|
|
Debug.LogFormat("WritePrefab: {0}", prefabPath);
|
|
PrefabUtility.SaveAsPrefabAsset(copy, prefabPath.Value);
|
|
}
|
|
|
|
// destroy copy in scene.
|
|
GameObject.DestroyImmediate(copy);
|
|
}
|
|
else
|
|
{
|
|
// do nothing. keep copy.
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|