From 03e9cfb43e8568ab0940a8baafbeb54079a838b5 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 25 May 2020 18:31:13 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E5=89=8A=E9=99=A4=E5=AF=BE=E8=B1=A1?= =?UTF-8?q?=E3=81=AE=E3=83=9C=E3=83=BC=E3=83=B3=E3=81=8C=E3=82=A6=E3=82=A7?= =?UTF-8?q?=E3=82=A4=E3=83=88=E3=81=8C=E5=90=AB=E3=81=BE=E3=82=8C=E3=81=AA?= =?UTF-8?q?=E3=81=84=E5=A0=B4=E5=90=88=E3=81=AB=E3=80=81=E4=B8=80=E4=BA=BA?= =?UTF-8?q?=E7=A7=B0=E7=94=A8=E3=83=98=E3=83=83=E3=83=89=E3=83=AC=E3=82=B9?= =?UTF-8?q?=E3=83=A2=E3=83=87=E3=83=AB=E3=82=92=E4=BD=9C=E6=88=90=E3=81=97?= =?UTF-8?q?=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Scripts/FirstPerson/VRMFirstPerson.cs | 65 +++++++++---------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs index e6a8ab9bf..8147b8995 100644 --- a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs +++ b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs @@ -125,7 +125,7 @@ namespace VRM return FirstPersonFlag.Auto; } - foreach(var x in context.GLTF.extensions.VRM.firstPerson.meshAnnotations) + foreach (var x in context.GLTF.extensions.VRM.firstPerson.meshAnnotations) { if (x.mesh == index) { @@ -159,10 +159,11 @@ namespace VRM // ここには来ない } - + public static void SetupLayers() { - if (!TriedSetupLayer) { + if (!TriedSetupLayer) + { TriedSetupLayer = true; int layer = LayerMask.NameToLayer("VRMFirstPersonOnly"); FIRSTPERSON_ONLY_LAYER = (layer == -1) ? FIRSTPERSON_ONLY_LAYER : layer; @@ -188,45 +189,39 @@ namespace VRM private static void CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRenderer renderer, Transform eraseRoot) { SetupLayers(); + var bones = renderer.bones; + + var eraseBones = bones.Select((x, i) => + { + // 祖先に削除対象が存在するか + bool erase = x.Ancestor().Any(y => y == eraseRoot); + return new + { + i, + erase, + }; + }) + .Where(x => x.erase) + .Select(x => x.i) + .ToArray() + ; + if (eraseBones.Length == 0) + { + // 削除対象が存在しない + return; + } + + // 元のメッシュを三人称に変更(自分からは見えない) renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER; + // 新規に一人称用のモデルを複製する var go = new GameObject("_headless_" + renderer.name); go.layer = FIRSTPERSON_ONLY_LAYER; go.transform.SetParent(renderer.transform, false); - - var m_eraseBones = renderer.bones.Select(x => - { - var eb = new BoneMeshEraser.EraseBone - { - Bone = x, - }; - - if (eraseRoot != null) - { - // 首の子孫を消去 - if (eb.Bone.Ancestor().Any(y => y == eraseRoot)) - { - //Debug.LogFormat("erase {0}", x); - eb.Erase = true; - } - } - - return eb; - }) - .ToArray(); - - var bones = renderer.bones; - var eraseBones = m_eraseBones - .Where(x => x.Erase) - .Select(x => bones.IndexOf(x.Bone)) - .ToArray(); - - var mesh = BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones); - var erased = go.AddComponent(); - erased.sharedMesh = mesh; + erased.sharedMesh = BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones); erased.sharedMaterials = renderer.sharedMaterials; - erased.bones = renderer.bones; + erased.bones = bones; erased.rootBone = renderer.rootBone; erased.updateWhenOffscreen = true; } From 4d3d41104fa8252100126055823d71e98ecd2406 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 25 May 2020 18:37:27 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E9=99=A4=E5=A4=96=E3=81=97=E3=81=9F?= =?UTF-8?q?=E7=B5=90=E6=9E=9C=E7=A9=BA=E3=81=AB=E3=81=AA=E3=82=8B=E5=A0=B4?= =?UTF-8?q?=E5=90=88=E3=81=AB=E3=83=A1=E3=83=83=E3=82=B7=E3=83=A5=E3=82=92?= =?UTF-8?q?=E7=A0=B4=E6=A3=84=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs index 8147b8995..4667098bd 100644 --- a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs +++ b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs @@ -214,12 +214,21 @@ namespace VRM // 元のメッシュを三人称に変更(自分からは見えない) renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER; - // 新規に一人称用のモデルを複製する + // 削除対象のボーンに対するウェイトを保持する三角形を除外して、一人称用のモデルを複製する + var headlessMesh = BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones); + if (headlessMesh.triangles.Length == 0) + { + UnityEngine.Object.Destroy(headlessMesh); + // 一人称用のmeshには描画すべき部分が無い(全部削除された) + return; + } + + // 一人称用のモデルのセットアップ var go = new GameObject("_headless_" + renderer.name); go.layer = FIRSTPERSON_ONLY_LAYER; go.transform.SetParent(renderer.transform, false); var erased = go.AddComponent(); - erased.sharedMesh = BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones); + erased.sharedMesh = headlessMesh; erased.sharedMaterials = renderer.sharedMaterials; erased.bones = bones; erased.rootBone = renderer.rootBone; From d234fe070224e36ba64913d743b4c1846713870b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 25 May 2020 18:44:35 +0900 Subject: [PATCH 3/3] =?UTF-8?q?OnDestory=E3=81=A7=E4=B8=80=E4=BA=BA?= =?UTF-8?q?=E7=A7=B0=E7=94=A8=E3=81=AE=E3=83=98=E3=83=83=E3=83=89=E3=83=AC?= =?UTF-8?q?=E3=82=B9=E3=83=A2=E3=83=87=E3=83=AB=E3=82=92=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #138 --- .../Scripts/FirstPerson/VRMFirstPerson.cs | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs index 4667098bd..7f1bd1ef6 100644 --- a/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs +++ b/Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs @@ -136,14 +136,16 @@ namespace VRM return FirstPersonFlag.Auto; } - void CreateHeadlessModel(Renderer _renderer, Transform EraseRoot) + /// + /// ヘッドレスモデルを作成した場合に返す + /// + Mesh CreateHeadlessModel(Renderer _renderer, Transform EraseRoot) { { var renderer = _renderer as SkinnedMeshRenderer; if (renderer != null) { - CreateHeadlessModelForSkinnedMeshRenderer(renderer, EraseRoot); - return; + return CreateHeadlessModelForSkinnedMeshRenderer(renderer, EraseRoot); } } @@ -153,11 +155,12 @@ namespace VRM if (renderer != null) { CreateHeadlessModelForMeshRenderer(renderer, EraseRoot); - return; + return null; } } // ここには来ない + return null; } public static void SetupLayers() @@ -186,7 +189,16 @@ namespace VRM } } - private static void CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRenderer renderer, Transform eraseRoot) + /// + /// ヘッドレスモデルを作成する。 + /// + /// 以下の場合は作成しない。 + /// + /// * 削除対象が無い場合 + /// * 全部削除対象の場合 + /// + /// + private static Mesh CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRenderer renderer, Transform eraseRoot) { SetupLayers(); var bones = renderer.bones; @@ -208,7 +220,7 @@ namespace VRM if (eraseBones.Length == 0) { // 削除対象が存在しない - return; + return null; } // 元のメッシュを三人称に変更(自分からは見えない) @@ -218,9 +230,9 @@ namespace VRM var headlessMesh = BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones); if (headlessMesh.triangles.Length == 0) { - UnityEngine.Object.Destroy(headlessMesh); // 一人称用のmeshには描画すべき部分が無い(全部削除された) - return; + UnityEngine.Object.Destroy(headlessMesh); + return null; } // 一人称用のモデルのセットアップ @@ -233,10 +245,13 @@ namespace VRM erased.bones = bones; erased.rootBone = renderer.rootBone; erased.updateWhenOffscreen = true; + return headlessMesh; } bool m_done; + List m_headlessMeshes = new List(); + /// /// 配下のモデルのレイヤー設定など /// @@ -250,7 +265,13 @@ namespace VRM switch (x.FirstPersonFlag) { case FirstPersonFlag.Auto: - CreateHeadlessModel(x.Renderer, FirstPersonBone); + { + var headlessMesh = CreateHeadlessModel(x.Renderer, FirstPersonBone); + if (headlessMesh != null) + { + m_headlessMeshes.Add(headlessMesh); + } + } break; case FirstPersonFlag.FirstPersonOnly: @@ -267,5 +288,18 @@ namespace VRM } } } + + void OnDestroy() + { + foreach (var mesh in m_headlessMeshes) + { + if (mesh != null) + { + // Debug.LogFormat("[VRMFirstPerson] OnDestroy: {0}", mesh); + UnityEngine.Object.Destroy(mesh); + } + } + m_headlessMeshes.Clear(); + } } }