mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-11 05:19:14 -05:00
fix GltfMeshUtility.WriteAssets
This commit is contained in:
@@ -3,7 +3,7 @@ using UnityEditor;
|
||||
using UniGLTF.M17N;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
|
||||
namespace UniGLTF.MeshUtility
|
||||
@@ -179,54 +179,50 @@ namespace UniGLTF.MeshUtility
|
||||
{
|
||||
/// [prefab]
|
||||
///
|
||||
/// * backup するのではなく 変更した copy を作成する。元は変えない
|
||||
/// * copy 先の統合前の renderer を disable で残さず destroy する
|
||||
/// * 実行すると mesh, blendshape, blendShape を新規に作成する
|
||||
/// * 新しいヒエラルキーを prefab に保存してから削除して終了する
|
||||
|
||||
// 出力フォルダを決める
|
||||
var folder = "Assets";
|
||||
var prefab = _exportTarget.GetPrefab();
|
||||
if (prefab != null)
|
||||
/// * prefab から instance を作る
|
||||
/// * instance に対して 焼き付け, 統合, 分離 を実行する
|
||||
/// * instance のヒエラルキーが改変され、mesh 等のアセットは改変版が作成される(元は変わらない)
|
||||
/// * instance を asset に保存してから prefab を削除して終了する
|
||||
///
|
||||
UnityPath assetFolder = default;
|
||||
try
|
||||
{
|
||||
folder = AssetDatabase.GetAssetPath(prefab);
|
||||
// Debug.Log(folder);
|
||||
assetFolder = PrefabContext.GetOutFolder(_exportTarget);
|
||||
}
|
||||
// 新規で作成されるアセットはすべてこのフォルダの中に作る。上書きチェックはしない
|
||||
var assetFolder = EditorUtility.SaveFolderPanel("select asset save folder", Path.GetDirectoryName(folder), "VrmIntegrated");
|
||||
var unityPath = UniGLTF.UnityPath.FromFullpath(assetFolder);
|
||||
if (!unityPath.IsUnderWritableFolder)
|
||||
catch (Exception)
|
||||
{
|
||||
EditorUtility.DisplayDialog("asset folder", "Target folder must be in the Assets or writable Packages folder", "cancel");
|
||||
return;
|
||||
}
|
||||
assetFolder = unityPath.Value;
|
||||
|
||||
var copy = GameObject.Instantiate(_exportTarget);
|
||||
if (PrefabUtility.IsOutermostPrefabInstanceRoot(copy))
|
||||
using (var context = new PrefabContext(_exportTarget, assetFolder))
|
||||
{
|
||||
PrefabUtility.UnpackPrefabInstance(copy, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
|
||||
try
|
||||
{
|
||||
var (results, created) = MeshUtility.Process(_exportTarget, context.Instance);
|
||||
|
||||
WriteAssets(context.Instance, context.AssetFolder, results);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
#if DEBUG
|
||||
Debug.LogException(ex, context.Instance);
|
||||
context.Keep = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
var (results, created) = MeshUtility.Process(_exportTarget, copy);
|
||||
|
||||
WriteAssets(copy, assetFolder, results);
|
||||
|
||||
// destroy scene
|
||||
UnityEngine.Object.DestroyImmediate(copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Undo.RegisterFullObjectHierarchyUndo(_exportTarget, "MeshUtility");
|
||||
using (var context = new UndoContext("MeshUtility", _exportTarget))
|
||||
{
|
||||
var (results, created) = MeshUtility.Process(_exportTarget, null);
|
||||
|
||||
if (_exportTarget.GetPrefabType() == UnityExtensions.PrefabType.PrefabInstance)
|
||||
{
|
||||
PrefabUtility.UnpackPrefabInstance(_exportTarget, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
|
||||
}
|
||||
var (results, created) = MeshUtility.Process(_exportTarget, null);
|
||||
foreach (var go in created)
|
||||
{
|
||||
Undo.RegisterCreatedObjectUndo(go, "MeshUtility");
|
||||
foreach (var go in created)
|
||||
{
|
||||
// 処理後の mesh をアタッチした Renderer.gameobject
|
||||
Undo.RegisterCreatedObjectUndo(go, "MeshUtility");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,68 +231,36 @@ namespace UniGLTF.MeshUtility
|
||||
}
|
||||
}
|
||||
|
||||
void WriteAssets(GameObject copy, string assetFolder, List<MeshIntegrationResult> results)
|
||||
/// <summary>
|
||||
/// Write Mesh & Prefab
|
||||
/// </summary>
|
||||
protected virtual void WriteAssets(GameObject copy, string assetFolder, List<MeshIntegrationResult> results)
|
||||
{
|
||||
//
|
||||
// write mesh asset
|
||||
foreach (var result in results)
|
||||
{
|
||||
var childAssetPath = $"{assetFolder}/{result.Integrated.IntegratedRenderer.gameObject.name}{ASSET_SUFFIX}";
|
||||
Debug.LogFormat("CreateAsset: {0}", childAssetPath);
|
||||
AssetDatabase.CreateAsset(result.Integrated.IntegratedRenderer.sharedMesh, childAssetPath);
|
||||
}
|
||||
|
||||
// 統合した結果をヒエラルキーに追加する
|
||||
foreach (var result in results)
|
||||
{
|
||||
if (result.Integrated.IntegratedRenderer != null)
|
||||
if (result.Integrated != null)
|
||||
{
|
||||
result.Integrated.IntegratedRenderer.transform.SetParent(copy.transform, false);
|
||||
var childAssetPath = $"{assetFolder}/{result.Integrated.IntegratedRenderer.gameObject.name}{ASSET_SUFFIX}";
|
||||
Debug.LogFormat("CreateAsset: {0}", childAssetPath);
|
||||
AssetDatabase.CreateAsset(result.Integrated.IntegratedRenderer.sharedMesh, childAssetPath);
|
||||
}
|
||||
if (result.IntegratedNoBlendShape != null)
|
||||
{
|
||||
var childAssetPath = $"{assetFolder}/{result.IntegratedNoBlendShape.IntegratedRenderer.gameObject.name}{ASSET_SUFFIX}";
|
||||
Debug.LogFormat("CreateAsset: {0}", childAssetPath);
|
||||
AssetDatabase.CreateAsset(result.IntegratedNoBlendShape.IntegratedRenderer.sharedMesh, childAssetPath);
|
||||
}
|
||||
}
|
||||
|
||||
// 統合した結果を反映した BlendShapeClip を作成して置き換える
|
||||
// var clips = VRMMeshIntegratorUtility.FollowBlendshapeRendererChange(results, copy, assetFolder);
|
||||
|
||||
// 用が済んだ 統合前 の renderer を削除する
|
||||
foreach (var result in results)
|
||||
{
|
||||
foreach (var renderer in result.SourceMeshRenderers)
|
||||
{
|
||||
GameObject.DestroyImmediate(renderer);
|
||||
}
|
||||
foreach (var renderer in result.SourceSkinnedMeshRenderers)
|
||||
{
|
||||
GameObject.DestroyImmediate(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
// reset firstperson
|
||||
// var firstperson = copy.GetComponent<VRMFirstPerson>();
|
||||
// if (firstperson != null)
|
||||
// {
|
||||
// firstperson.Reset();
|
||||
// }
|
||||
|
||||
// prefab
|
||||
var prefabPath = $"{assetFolder}/VrmIntegrated.prefab";
|
||||
var prefabPath = $"{assetFolder}/Integrated.prefab";
|
||||
Debug.Log(prefabPath);
|
||||
PrefabUtility.SaveAsPrefabAsset(copy, prefabPath, out bool success);
|
||||
if (!success)
|
||||
{
|
||||
throw new System.Exception($"PrefabUtility.SaveAsPrefabAsset: {prefabPath}");
|
||||
}
|
||||
|
||||
// var prefabReference = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
||||
// foreach (var clip in clips)
|
||||
// {
|
||||
// var so = new SerializedObject(clip);
|
||||
// so.Update();
|
||||
// // clip.Prefab = copy;
|
||||
// var prop = so.FindProperty("m_prefab");
|
||||
// prop.objectReferenceValue = prefabReference;
|
||||
// so.ApplyModifiedProperties();
|
||||
// }
|
||||
}
|
||||
|
||||
protected bool ToggleIsModified(string label, ref bool value)
|
||||
|
||||
63
Assets/UniGLTF/Editor/MeshUtility/PrefabContext.cs
Normal file
63
Assets/UniGLTF/Editor/MeshUtility/PrefabContext.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF.MeshUtility
|
||||
{
|
||||
// Instantiate
|
||||
class PrefabContext : IDisposable
|
||||
{
|
||||
public readonly GameObject Instance;
|
||||
|
||||
readonly UnityPath _assetFolder;
|
||||
|
||||
public bool Keep = false;
|
||||
|
||||
public string AssetFolder => _assetFolder.Value;
|
||||
|
||||
public PrefabContext(GameObject prefab, UnityPath assetFolder)
|
||||
{
|
||||
this._assetFolder = assetFolder;
|
||||
this.Instance = GameObject.Instantiate(prefab);
|
||||
if (PrefabUtility.IsOutermostPrefabInstanceRoot(this.Instance))
|
||||
{
|
||||
// どういう条件でここに来るかはよくわからない
|
||||
PrefabUtility.UnpackPrefabInstance(this.Instance, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
|
||||
}
|
||||
}
|
||||
|
||||
// - Instance を Asset に書き出す
|
||||
// - Instance を削除する
|
||||
public void Dispose()
|
||||
{
|
||||
if (Keep)
|
||||
{
|
||||
// for debug
|
||||
return;
|
||||
}
|
||||
UnityEngine.Object.DestroyImmediate(Instance);
|
||||
}
|
||||
|
||||
public static UnityPath GetOutFolder(GameObject _exportTarget)
|
||||
{
|
||||
// 出力フォルダを決める
|
||||
var folder = "Assets";
|
||||
var prefab = _exportTarget.GetPrefab();
|
||||
if (prefab != null)
|
||||
{
|
||||
folder = AssetDatabase.GetAssetPath(prefab);
|
||||
// Debug.Log(folder);
|
||||
}
|
||||
|
||||
// 新規で作成されるアセットはすべてこのフォルダの中に作る。上書きチェックはしない
|
||||
var assetFolder = EditorUtility.SaveFolderPanel("select asset save folder", Path.GetDirectoryName(folder), "Integrated");
|
||||
var unityPath = UniGLTF.UnityPath.FromFullpath(assetFolder);
|
||||
if (!unityPath.IsUnderWritableFolder)
|
||||
{
|
||||
throw new Exception("not in asset folder");
|
||||
}
|
||||
return unityPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Editor/MeshUtility/PrefabContext.cs.meta
Normal file
11
Assets/UniGLTF/Editor/MeshUtility/PrefabContext.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 948458ced6bcc904781eed04ebe7cd01
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/UniGLTF/Editor/MeshUtility/UndoContext.cs
Normal file
27
Assets/UniGLTF/Editor/MeshUtility/UndoContext.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF.MeshUtility
|
||||
{
|
||||
// Instantiate
|
||||
class UndoContext : IDisposable
|
||||
{
|
||||
public UndoContext(string undoName, GameObject go)
|
||||
{
|
||||
Undo.RegisterFullObjectHierarchyUndo(go, undoName);
|
||||
if (go.GetPrefabType() == UnityExtensions.PrefabType.PrefabInstance)
|
||||
{
|
||||
PrefabUtility.UnpackPrefabInstance(go, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// 特に何もしない
|
||||
// Undo すると元に戻ってしまう
|
||||
|
||||
// TODO: あれば一時オブジェクトの破棄
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Editor/MeshUtility/UndoContext.cs.meta
Normal file
11
Assets/UniGLTF/Editor/MeshUtility/UndoContext.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5019966789c0e094a8f58fc2734c9a35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -45,17 +45,11 @@ namespace UniGLTF.MeshUtility
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 回転とスケールを除去したヒエラルキーのコピーを作成する(MeshをBakeする)
|
||||
/// 各レンダラー(SkinnedMeshRenderer と MeshRenderer)にアタッチされた sharedMesh に対して
|
||||
/// 回転とスケールを除去し、BlendShape の現状を焼き付けた版を作成する(まだ、アタッチしない)
|
||||
/// </summary>
|
||||
/// <param name="go">対象のヒエラルキーのルート</param>
|
||||
/// <param name="bakeCurrentBlendShape">BlendShapeを0クリアするか否か。false の場合 BlendShape の現状を Bake する</param>
|
||||
/// <param name="createAvatar">Avatarを作る関数</param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<Transform, MeshAttachInfo> NormalizeHierarchyFreezeMesh(GameObject go)
|
||||
{
|
||||
//
|
||||
// 各メッシュから回転・スケールを取り除いてBinding行列を再計算する
|
||||
//
|
||||
var result = new Dictionary<Transform, MeshAttachInfo>();
|
||||
foreach (var src in go.transform.Traverse())
|
||||
{
|
||||
|
||||
@@ -174,33 +174,40 @@ namespace UniGLTF.MeshUtility
|
||||
}
|
||||
}
|
||||
|
||||
public virtual (List<MeshIntegrationResult>, List<GameObject>) Process(GameObject go, GameObject instance)
|
||||
public virtual (List<MeshIntegrationResult>, List<GameObject>) Process(GameObject _go, GameObject _instance)
|
||||
{
|
||||
var target = _instance ?? _go;
|
||||
if (FreezeBlendShape || FreezeRotation || FreezeScaling)
|
||||
{
|
||||
// MeshをBakeする
|
||||
var newMesh = BoneNormalizer.NormalizeHierarchyFreezeMesh(go);
|
||||
var newMesh = BoneNormalizer.NormalizeHierarchyFreezeMesh(target);
|
||||
|
||||
// - ヒエラルキーから回転・拡縮を除去する
|
||||
// - BakeされたMeshで置き換える
|
||||
// - bindPoses を再計算する
|
||||
BoneNormalizer.Replace(go, newMesh, FreezeRotation, FreezeScaling);
|
||||
BoneNormalizer.Replace(target, newMesh, FreezeRotation, FreezeScaling);
|
||||
}
|
||||
|
||||
var copy = CopyInstantiate(go, instance);
|
||||
// prefab が instantiate されていた場合に
|
||||
// Mesh統合設定を instantiate に置き換える
|
||||
var groupCopy = CopyInstantiate(_go, _instance);
|
||||
|
||||
var newList = new List<GameObject>();
|
||||
|
||||
var empty = GetOrCreateEmpty(instance ?? go, "mesh");
|
||||
var empty = GetOrCreateEmpty(target, "mesh");
|
||||
|
||||
var results = new List<MeshIntegrationResult>();
|
||||
foreach (var group in copy)
|
||||
foreach (var group in groupCopy)
|
||||
{
|
||||
var (result, newGo) = Integrate(empty, group);
|
||||
results.Add(result);
|
||||
newList.AddRange(newGo);
|
||||
if (TryIntegrate(empty, group, out var resultAndAdded))
|
||||
{
|
||||
var (result, newGo) = resultAndAdded;
|
||||
results.Add(result);
|
||||
newList.AddRange(newGo);
|
||||
}
|
||||
}
|
||||
|
||||
// // 用が済んだ 統合前 の renderer を削除する
|
||||
foreach (var result in results)
|
||||
{
|
||||
foreach (var r in result.SourceMeshRenderers)
|
||||
@@ -212,22 +219,37 @@ namespace UniGLTF.MeshUtility
|
||||
RemoveComponent(r);
|
||||
}
|
||||
}
|
||||
// foreach (var result in results)
|
||||
// {
|
||||
// foreach (var renderer in result.SourceMeshRenderers)
|
||||
// {
|
||||
// GameObject.DestroyImmediate(renderer);
|
||||
// }
|
||||
// foreach (var renderer in result.SourceSkinnedMeshRenderers)
|
||||
// {
|
||||
// GameObject.DestroyImmediate(renderer);
|
||||
// }
|
||||
// }
|
||||
|
||||
MeshIntegrationGroups.Clear();
|
||||
|
||||
return (results, newList);
|
||||
}
|
||||
|
||||
protected virtual (MeshIntegrationResult, GameObject[]) Integrate(GameObject empty,
|
||||
MeshIntegrationGroup group)
|
||||
protected virtual bool TryIntegrate(GameObject empty,
|
||||
MeshIntegrationGroup group, out (MeshIntegrationResult, GameObject[]) resultAndAdded)
|
||||
{
|
||||
var result = MeshIntegrator.Integrate(group, SplitByBlendShape
|
||||
if (MeshIntegrator.TryIntegrate(group, SplitByBlendShape
|
||||
? MeshIntegrator.BlendShapeOperation.Split
|
||||
: MeshIntegrator.BlendShapeOperation.Use);
|
||||
: MeshIntegrator.BlendShapeOperation.Use, out var result))
|
||||
{
|
||||
var newGo = result.AddIntegratedRendererTo(empty).ToArray();
|
||||
resultAndAdded = (result, newGo);
|
||||
return true;
|
||||
}
|
||||
|
||||
var newGo = result.AddIntegratedRendererTo(empty).ToArray();
|
||||
|
||||
return (result, newGo);
|
||||
resultAndAdded = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -11,23 +12,46 @@ namespace UniGLTF.MeshUtility
|
||||
public Transform RootBone;
|
||||
public void ReplaceMesh(GameObject dst)
|
||||
{
|
||||
if (dst == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
if (Bones != null)
|
||||
{
|
||||
// recalc bindposes
|
||||
Mesh.bindposes = Bones.Select(x => x.worldToLocalMatrix * dst.transform.localToWorldMatrix).ToArray();
|
||||
|
||||
var dstRenderer = dst.GetComponent<SkinnedMeshRenderer>();
|
||||
dstRenderer.sharedMesh = Mesh;
|
||||
dstRenderer.sharedMaterials = Materials;
|
||||
dstRenderer.bones = Bones;
|
||||
dstRenderer.rootBone = RootBone;
|
||||
if (dst.GetComponent<SkinnedMeshRenderer>() is SkinnedMeshRenderer dstRenderer)
|
||||
{
|
||||
dstRenderer.sharedMesh = Mesh;
|
||||
dstRenderer.sharedMaterials = Materials;
|
||||
dstRenderer.bones = Bones;
|
||||
dstRenderer.rootBone = RootBone;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"SkinnedMeshRenderer not found", dst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var dstFilter = dst.GetComponent<MeshFilter>();
|
||||
dstFilter.sharedMesh = Mesh;
|
||||
var dstRenderer = dst.gameObject.AddComponent<MeshRenderer>();
|
||||
dstRenderer.sharedMaterials = Materials;
|
||||
if (dst.GetComponent<MeshFilter>() is MeshFilter dstFilter)
|
||||
{
|
||||
dstFilter.sharedMesh = Mesh;
|
||||
if (dst.gameObject.GetComponent<MeshRenderer>() is MeshRenderer dstRenderer)
|
||||
{
|
||||
dstRenderer.sharedMaterials = Materials;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"MeshRenderer not found", dst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"MeshFilter not found", dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,16 +48,24 @@ namespace UniGLTF.MeshUtility
|
||||
|
||||
public IEnumerable<GameObject> AddIntegratedRendererTo(GameObject parent)
|
||||
{
|
||||
int count = 0;
|
||||
if (Integrated != null)
|
||||
{
|
||||
Integrated.AddIntegratedRendererTo(parent, Bones);
|
||||
++count;
|
||||
yield return Integrated.IntegratedRenderer.gameObject;
|
||||
}
|
||||
if (IntegratedNoBlendShape != null)
|
||||
{
|
||||
IntegratedNoBlendShape.AddIntegratedRendererTo(parent, Bones);
|
||||
++count;
|
||||
yield return IntegratedNoBlendShape.IntegratedRenderer.gameObject;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,8 @@ namespace UniGLTF.MeshUtility
|
||||
return found;
|
||||
}
|
||||
|
||||
public static MeshIntegrationResult Integrate(MeshIntegrationGroup group, BlendShapeOperation op)
|
||||
public static bool TryIntegrate(MeshIntegrationGroup group, BlendShapeOperation op,
|
||||
out MeshIntegrationResult result)
|
||||
{
|
||||
var integrator = new MeshUtility.MeshIntegrator();
|
||||
foreach (var x in group.Renderers)
|
||||
@@ -289,7 +290,15 @@ namespace UniGLTF.MeshUtility
|
||||
integrator.Push(mr);
|
||||
}
|
||||
}
|
||||
return integrator.Integrate(group.Name, op);
|
||||
result = integrator.Integrate(group.Name, op);
|
||||
if (result.Integrated != null || result.IntegratedNoBlendShape != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
delegate bool TriangleFilter(int i0, int i1, int i2);
|
||||
@@ -351,7 +360,7 @@ namespace UniGLTF.MeshUtility
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public MeshIntegrationResult Integrate(string name, BlendShapeOperation op)
|
||||
MeshIntegrationResult Integrate(string name, BlendShapeOperation op)
|
||||
{
|
||||
if (_Bones.Count != _BindPoses.Count)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,8 @@ using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UniGLTF.M17N;
|
||||
using UniGLTF;
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF.MeshUtility;
|
||||
|
||||
|
||||
namespace VRM
|
||||
@@ -48,6 +50,32 @@ namespace VRM
|
||||
return firstPerson || mod;
|
||||
}
|
||||
|
||||
protected override void WriteAssets(GameObject copy, string assetFolder, List<MeshIntegrationResult> results)
|
||||
{
|
||||
base.WriteAssets(copy, assetFolder, results);
|
||||
|
||||
// 統合した結果を反映した BlendShapeClip を作成して置き換える
|
||||
// var clips = VRMMeshIntegratorUtility.FollowBlendshapeRendererChange(results, copy, assetFolder);
|
||||
|
||||
// reset firstperson
|
||||
// var firstperson = copy.GetComponent<VRMFirstPerson>();
|
||||
// if (firstperson != null)
|
||||
// {
|
||||
// firstperson.Reset();
|
||||
// }
|
||||
|
||||
// var prefabReference = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
||||
// foreach (var clip in clips)
|
||||
// {
|
||||
// var so = new SerializedObject(clip);
|
||||
// so.Update();
|
||||
// // clip.Prefab = copy;
|
||||
// var prop = so.FindProperty("m_prefab");
|
||||
// prop.objectReferenceValue = prefabReference;
|
||||
// so.ApplyModifiedProperties();
|
||||
// }
|
||||
}
|
||||
|
||||
protected override void DialogMessage()
|
||||
{
|
||||
EditorGUILayout.HelpBox(Message.MESH_UTILITY.Msg(), MessageType.Info);
|
||||
|
||||
@@ -38,13 +38,19 @@ namespace VRM
|
||||
return copy;
|
||||
}
|
||||
|
||||
protected override
|
||||
(UniGLTF.MeshUtility.MeshIntegrationResult, GameObject[]) Integrate(
|
||||
protected override bool
|
||||
TryIntegrate(
|
||||
GameObject empty,
|
||||
UniGLTF.MeshUtility.MeshIntegrationGroup group)
|
||||
UniGLTF.MeshUtility.MeshIntegrationGroup group,
|
||||
out (UniGLTF.MeshUtility.MeshIntegrationResult, GameObject[]) resultAndAdded)
|
||||
{
|
||||
var (result, newList) = base.Integrate(empty, group);
|
||||
if (!base.TryIntegrate(empty, group, out resultAndAdded))
|
||||
{
|
||||
resultAndAdded = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
var (result, newGo) = resultAndAdded;
|
||||
if (_generateFirstPerson && group.Name == nameof(FirstPersonFlag.Auto))
|
||||
{
|
||||
// Mesh 統合の後処理
|
||||
@@ -62,8 +68,7 @@ namespace VRM
|
||||
_ProcessFirstPerson(_vrmInstance.FirstPersonBone, result.IntegratedNoBlendShape.IntegratedRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
return (result, newList);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void _ProcessFirstPerson(Transform firstPersonBone, SkinnedMeshRenderer smr)
|
||||
|
||||
@@ -39,11 +39,16 @@ namespace UniVRM10
|
||||
}
|
||||
|
||||
protected override
|
||||
(UniGLTF.MeshUtility.MeshIntegrationResult, GameObject[]) Integrate(
|
||||
bool TryIntegrate(
|
||||
GameObject empty,
|
||||
UniGLTF.MeshUtility.MeshIntegrationGroup group)
|
||||
UniGLTF.MeshUtility.MeshIntegrationGroup group,
|
||||
out (UniGLTF.MeshUtility.MeshIntegrationResult, GameObject[]) resultAndAdded)
|
||||
{
|
||||
var (result, newList) = base.Integrate(empty, group);
|
||||
if (!base.TryIntegrate(empty, group, out resultAndAdded))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var (result, newList) = resultAndAdded;
|
||||
|
||||
if (_generateFirstPerson && group.Name == nameof(UniGLTF.Extensions.VRMC_vrm.FirstPersonType.auto))
|
||||
{
|
||||
@@ -62,8 +67,7 @@ namespace UniVRM10
|
||||
_ProcessFirstPerson(_vrmInstance.Humanoid.Head, result.IntegratedNoBlendShape.IntegratedRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
return (result, newList);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void _ProcessFirstPerson(Transform firstPersonBone, SkinnedMeshRenderer smr)
|
||||
|
||||
Reference in New Issue
Block a user