diff --git a/Assets/UniGLTF/Runtime/MeshUtility/BoneMeshEraser.cs b/Assets/UniGLTF/Runtime/MeshUtility/BoneMeshEraser.cs
index fd34c2584..88d614ca3 100644
--- a/Assets/UniGLTF/Runtime/MeshUtility/BoneMeshEraser.cs
+++ b/Assets/UniGLTF/Runtime/MeshUtility/BoneMeshEraser.cs
@@ -131,7 +131,7 @@ namespace UniGLTF.MeshUtility
///
///
///
- public static int[] GetExcludedIndices(int[] indices, BoneWeight[] boneWeights, int[] eraseBoneIndices)
+ static int[] GetExcludedIndices(int[] indices, BoneWeight[] boneWeights, int[] eraseBoneIndices)
{
var count = ExcludeTriangles(indices, boneWeights, eraseBoneIndices);
var dst = new int[count];
diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs
index b24c16ce1..8ecb955fe 100644
--- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs
+++ b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs
@@ -165,6 +165,12 @@ namespace UniGLTF.MeshUtility
public void Push(SkinnedMeshRenderer renderer)
{
+ if (renderer == null)
+ {
+ // Debug.LogWarningFormat("{0} was destroyed", renderer);
+ return;
+ }
+
var mesh = renderer.sharedMesh;
if (mesh == null)
{
diff --git a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectFirstPerson.cs b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectFirstPerson.cs
index af956c287..e8db4b7e7 100644
--- a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectFirstPerson.cs
+++ b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectFirstPerson.cs
@@ -29,7 +29,7 @@ namespace UniVRM10
}
}
- public static int[] GetBonesThatHasAncestor(SkinnedMeshRenderer smr, Transform ancestor)
+ static int[] GetBonesThatHasAncestor(SkinnedMeshRenderer smr, Transform ancestor)
{
var eraseBones = smr.bones
.Where(x => x.Ancestor().Any(y => y == ancestor))
@@ -38,24 +38,46 @@ namespace UniVRM10
return eraseBones;
}
+ public static async Task CreateErasedMeshAsync(SkinnedMeshRenderer smr,
+ Transform firstPersonBone,
+ IAwaitCaller awaitCaller)
+ {
+ var eraseBones = GetBonesThatHasAncestor(smr, firstPersonBone);
+ if (eraseBones.Any())
+ {
+ return await BoneMeshEraser.CreateErasedMeshAsync(smr.sharedMesh, eraseBones, awaitCaller);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
//
// 頭部を取り除いたモデルを複製する
//
// renderer: 元になるSkinnedMeshRenderer
// eraseBones: 削除対象になるボーンのindex
- private async static Task CreateHeadlessMeshAsync(SkinnedMeshRenderer renderer, int[] eraseBones, IAwaitCaller awaitCaller)
+ public async static Task CreateHeadlessMeshAsync(SkinnedMeshRenderer renderer,
+ Transform firstPersonBone, IAwaitCaller awaitCaller)
{
- var mesh = await BoneMeshEraser.CreateErasedMeshAsync(renderer.sharedMesh, eraseBones, awaitCaller);
-
- var go = new GameObject("_headless_" + renderer.name);
- var erased = go.AddComponent();
- erased.enabled = false; // hide
- erased.sharedMesh = mesh;
- erased.sharedMaterials = renderer.sharedMaterials;
- erased.bones = renderer.bones;
- erased.rootBone = renderer.rootBone;
-
- return erased;
+ var mesh = await CreateErasedMeshAsync(renderer, firstPersonBone, awaitCaller);
+ if (mesh != null)
+ {
+ var go = new GameObject("_headless_" + renderer.name);
+ var erased = go.AddComponent();
+ erased.enabled = false; // hide
+ erased.sharedMesh = mesh;
+ erased.sharedMaterials = renderer.sharedMaterials;
+ erased.bones = renderer.bones;
+ erased.rootBone = renderer.rootBone;
+ return erased;
+ }
+ else
+ {
+ // 削除対象が含まれないので何もしない
+ return null;
+ }
}
bool m_done;
@@ -70,14 +92,13 @@ namespace UniVRM10
{
if (x.GetRenderer(go.transform) is SkinnedMeshRenderer smr)
{
- var eraseBones = GetBonesThatHasAncestor(smr, firstPersonBone);
- if (eraseBones.Any())
- {
- // オリジナルのモデルを3人称用にする
- smr.gameObject.layer = layer.ThirdPersonOnly;
+ // オリジナルのモデルを3人称用にする
+ smr.gameObject.layer = layer.ThirdPersonOnly;
- // 頭を取り除いた複製モデルを作成し、1人称用にする
- var headless = await CreateHeadlessMeshAsync(smr, eraseBones, awaitCaller);
+ // 頭を取り除いた複製モデルを作成し、1人称用にする
+ var headless = await CreateHeadlessMeshAsync(smr, firstPersonBone, awaitCaller);
+ if (headless != null)
+ {
headless.gameObject.layer = layer.FirstPersonOnly;
headless.transform.SetParent(smr.transform, false);
if (runtime != null)
@@ -85,10 +106,6 @@ namespace UniVRM10
runtime.AddRenderer(headless);
}
}
- else
- {
- // 削除対象が含まれないので何もしない
- }
}
else if (x.GetRenderer(go.transform) is MeshRenderer mr)
{
diff --git a/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs b/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs
index 7f3a6fa91..39614d2d9 100644
--- a/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs
+++ b/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using UniGLTF;
-using UniGLTF.Extensions.VRMC_vrm;
using UniGLTF.MeshUtility;
using UniHumanoid;
using UnityEngine;
@@ -122,6 +120,10 @@ namespace UniVRM10
void RemoveComponent(T c) where T : Component
{
+ if (c == null)
+ {
+ return;
+ }
var t = c.transform;
if (Application.isPlaying)
{
@@ -225,12 +227,40 @@ namespace UniVRM10
{
// TODO: UNDO
+ var results = new List();
foreach (var group in copy)
{
var result = MeshIntegrator.Integrate(group, SplitByBlendShape
? MeshIntegrator.BlendShapeOperation.Split
: MeshIntegrator.BlendShapeOperation.None);
+ results.Add(result);
+ result.AddIntegratedRendererTo(go);
+
+ if (generateFirstPerson && group.Name == "auto")
+ {
+ Debug.Log("generateFirstPerson");
+ var firstPersonBone = vrmInstance.Humanoid.Head;
+ var task = VRM10ObjectFirstPerson.CreateErasedMeshAsync(
+ result.IntegratedRenderer,
+ firstPersonBone,
+ new ImmediateCaller());
+ task.Wait();
+
+ if (task.Result != null)
+ {
+ result.IntegratedRenderer.sharedMesh = task.Result;
+ result.IntegratedRenderer.name = "auto.headless";
+ }
+ else
+ {
+ Debug.LogWarning("no result");
+ }
+ }
+ }
+
+ foreach (var result in results)
+ {
foreach (var r in result.SourceMeshRenderers)
{
RemoveComponent(r);
@@ -239,27 +269,6 @@ namespace UniVRM10
{
RemoveComponent(r);
}
-
- result.AddIntegratedRendererTo(go);
-
- if (generateFirstPerson && group.Name == "auto")
- {
- var firstPersonBone = vrmInstance.Humanoid.Head;
- var eraseBones = VRM10ObjectFirstPerson.GetBonesThatHasAncestor(
- result.IntegratedRenderer, firstPersonBone);
- var task = BoneMeshEraser.CreateErasedMeshAsync(result.MeshMap.Integrated, eraseBones,
- new ImmediateCaller());
- task.Wait();
-
- if (task.Result.vertexCount > 0)
- {
- var headless = new GameObject("auto.headless");
- var smr = headless.AddComponent();
- smr.sharedMesh = task.Result;
-
- headless.transform.SetParent(go.transform);
- }
- }
}
}
}