Skip to content

Commit

Permalink
Merge pull request #412 from ousttrue/update_vrmfirstperson
Browse files Browse the repository at this point in the history
VrmFirstPersonを修正
  • Loading branch information
hiroj authored May 25, 2020
2 parents 36362b1 + d234fe0 commit 56cdfe8
Showing 1 changed file with 76 additions and 38 deletions.
114 changes: 76 additions & 38 deletions Assets/VRM/UniVRM/Scripts/FirstPerson/VRMFirstPerson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static FirstPersonFlag GetFirstPersonFlag(VRMImporterContext context, Renderer r
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)
{
Expand All @@ -136,14 +136,16 @@ static FirstPersonFlag GetFirstPersonFlag(VRMImporterContext context, Renderer r
return FirstPersonFlag.Auto;
}

void CreateHeadlessModel(Renderer _renderer, Transform EraseRoot)
/// <summary>
/// ヘッドレスモデルを作成した場合に返す
/// </summary>
Mesh CreateHeadlessModel(Renderer _renderer, Transform EraseRoot)
{
{
var renderer = _renderer as SkinnedMeshRenderer;
if (renderer != null)
{
CreateHeadlessModelForSkinnedMeshRenderer(renderer, EraseRoot);
return;
return CreateHeadlessModelForSkinnedMeshRenderer(renderer, EraseRoot);
}
}

Expand All @@ -153,16 +155,18 @@ void CreateHeadlessModel(Renderer _renderer, Transform EraseRoot)
if (renderer != null)
{
CreateHeadlessModelForMeshRenderer(renderer, EraseRoot);
return;
return null;
}
}

// ここには来ない
return null;
}

public static void SetupLayers()
{
if (!TriedSetupLayer) {
if (!TriedSetupLayer)
{
TriedSetupLayer = true;
int layer = LayerMask.NameToLayer("VRMFirstPersonOnly");
FIRSTPERSON_ONLY_LAYER = (layer == -1) ? FIRSTPERSON_ONLY_LAYER : layer;
Expand All @@ -185,54 +189,69 @@ private static void CreateHeadlessModelForMeshRenderer(MeshRenderer renderer, Tr
}
}

private static void CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRenderer renderer, Transform eraseRoot)
/// <summary>
/// ヘッドレスモデルを作成する。
///
/// 以下の場合は作成しない。
///
/// * 削除対象が無い場合
/// * 全部削除対象の場合
///
/// </summary>
private static Mesh CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRenderer renderer, Transform eraseRoot)
{
SetupLayers();
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 bones = renderer.bones;

var m_eraseBones = renderer.bones.Select(x =>
var eraseBones = bones.Select((x, i) =>
{
var eb = new BoneMeshEraser.EraseBone
// 祖先に削除対象が存在するか
bool erase = x.Ancestor().Any(y => y == eraseRoot);
return new
{
Bone = x,
i,
erase,
};
if (eraseRoot != null)
{
// 首の子孫を消去
if (eb.Bone.Ancestor().Any(y => y == eraseRoot))
{
//Debug.LogFormat("erase {0}", x);
eb.Erase = true;
}
}
return eb;
})
.ToArray();
.Where(x => x.erase)
.Select(x => x.i)
.ToArray()
;
if (eraseBones.Length == 0)
{
// 削除対象が存在しない
return null;
}

var bones = renderer.bones;
var eraseBones = m_eraseBones
.Where(x => x.Erase)
.Select(x => bones.IndexOf(x.Bone))
.ToArray();
// 元のメッシュを三人称に変更(自分からは見えない)
renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER;

var mesh = BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones);
// 削除対象のボーンに対するウェイトを保持する三角形を除外して、一人称用のモデルを複製する
var headlessMesh = BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones);
if (headlessMesh.triangles.Length == 0)
{
// 一人称用のmeshには描画すべき部分が無い(全部削除された)
UnityEngine.Object.Destroy(headlessMesh);
return null;
}

// 一人称用のモデルのセットアップ
var go = new GameObject("_headless_" + renderer.name);
go.layer = FIRSTPERSON_ONLY_LAYER;
go.transform.SetParent(renderer.transform, false);
var erased = go.AddComponent<SkinnedMeshRenderer>();
erased.sharedMesh = mesh;
erased.sharedMesh = headlessMesh;
erased.sharedMaterials = renderer.sharedMaterials;
erased.bones = renderer.bones;
erased.bones = bones;
erased.rootBone = renderer.rootBone;
erased.updateWhenOffscreen = true;
return headlessMesh;
}

bool m_done;

List<Mesh> m_headlessMeshes = new List<Mesh>();

/// <summary>
/// 配下のモデルのレイヤー設定など
/// </summary>
Expand All @@ -246,7 +265,13 @@ public void Setup()
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:
Expand All @@ -263,5 +288,18 @@ public void Setup()
}
}
}

void OnDestroy()
{
foreach (var mesh in m_headlessMeshes)
{
if (mesh != null)
{
// Debug.LogFormat("[VRMFirstPerson] OnDestroy: {0}", mesh);
UnityEngine.Object.Destroy(mesh);
}
}
m_headlessMeshes.Clear();
}
}
}

0 comments on commit 56cdfe8

Please sign in to comment.