Skip to content

Commit

Permalink
Merge pull request #662 from ousttrue/feature/firstperson_for_other
Browse files Browse the repository at this point in the history
add VRMFirstPerson.SetVisiblity
  • Loading branch information
hiroj authored Jan 14, 2021
2 parents d756127 + 5c8859b commit 221945f
Showing 1 changed file with 102 additions and 29 deletions.
131 changes: 102 additions & 29 deletions Assets/VRM/Runtime/FirstPerson/VRMFirstPerson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ static FirstPersonFlag GetFirstPersonFlag(VRMImporterContext context, Renderer r
/// <summary>
/// ヘッドレスモデルを作成した場合に返す
/// </summary>
Mesh CreateHeadlessModel(Renderer _renderer, Transform EraseRoot)
Mesh CreateHeadlessModel(Renderer _renderer, Transform EraseRoot, SetVisiblityFunc setVisiblity)
{
{
var renderer = _renderer as SkinnedMeshRenderer;
if (renderer != null)
{
return CreateHeadlessModelForSkinnedMeshRenderer(renderer, EraseRoot);
return CreateHeadlessModelForSkinnedMeshRenderer(renderer, EraseRoot, setVisiblity);
}
}

Expand All @@ -143,7 +143,7 @@ Mesh CreateHeadlessModel(Renderer _renderer, Transform EraseRoot)
var renderer = _renderer as MeshRenderer;
if (renderer != null)
{
CreateHeadlessModelForMeshRenderer(renderer, EraseRoot);
CreateHeadlessModelForMeshRenderer(renderer, EraseRoot, setVisiblity);
return null;
}
}
Expand All @@ -164,13 +164,12 @@ public static void SetupLayers()
}
}

private static void CreateHeadlessModelForMeshRenderer(MeshRenderer renderer, Transform eraseRoot)
private static void CreateHeadlessModelForMeshRenderer(MeshRenderer renderer, Transform eraseRoot, SetVisiblityFunc setVisiblity)
{
if (renderer.transform.Ancestors().Any(x => x == eraseRoot))
{
// 祖先に削除ボーンが居る
SetupLayers();
renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER;
setVisiblity(renderer, false, true);
}
else
{
Expand All @@ -187,9 +186,8 @@ private static void CreateHeadlessModelForMeshRenderer(MeshRenderer renderer, Tr
/// * 全部削除対象の場合
///
/// </summary>
private static Mesh CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRenderer renderer, Transform eraseRoot)
private static Mesh CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRenderer renderer, Transform eraseRoot, SetVisiblityFunc setVisiblity)
{
SetupLayers();
var bones = renderer.bones;

var eraseBones = bones.Select((x, i) =>
Expand All @@ -213,7 +211,7 @@ private static Mesh CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRendere
}

// 元のメッシュを三人称に変更(自分からは見えない)
renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER;
setVisiblity(renderer, false, true);

// 削除対象のボーンに対するウェイトを保持する三角形を除外して、一人称用のモデルを複製する
var headlessMesh = MeshUtility.BoneMeshEraser.CreateErasedMesh(renderer.sharedMesh, eraseBones);
Expand Down Expand Up @@ -242,38 +240,113 @@ private static Mesh CreateHeadlessModelForSkinnedMeshRenderer(SkinnedMeshRendere
List<Mesh> m_headlessMeshes = new List<Mesh>();

/// <summary>
/// 配下のモデルのレイヤー設定など
/// Set target renderer visibility
///
/// https://github.com/vrm-c/UniVRM/issues/633#issuecomment-758454045
///
/// </summary>
public void Setup()
/// <param name="renderer">Target renderer. Player avatar or other</param>
/// <param name="firstPerson">visibility in HMD camera</param>
/// <param name="thirdPerson">other camera visibility</param>
public delegate void SetVisiblityFunc(Renderer renderer, bool firstPerson, bool thirdPerson);

/// <summary>
/// Default implementation.
/// Threre are 4 cases.
/// </summary>
/// <param name="renderer"></param>
/// <param name="firstPerson"></param>
/// <param name="thirdPerson"></param>
public static void SetVisiblity(Renderer renderer, bool firstPerson, bool thirdPerson)
{
SetupLayers();

if (firstPerson && thirdPerson)
{
// both
// do nothing
}
else if (firstPerson)
{
// only first person
renderer.gameObject.layer = FIRSTPERSON_ONLY_LAYER;
}
else if (thirdPerson)
{
// only third person
renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER;
}
else
{
// invisible
renderer.enabled = false;
}
}

public void Setup()
{
// same as v0.63.2
Setup(true, SetVisiblity);
}

/// <summary>
/// from v0.64.0
/// </summary>
/// <param name="isSelf"></param>
public void Setup(bool isSelf, SetVisiblityFunc setVisiblity)
{
if (m_done) return;
m_done = true;
foreach (var x in Renderers)

if (isSelf)
{
switch (x.FirstPersonFlag)
// self avatar
foreach (var x in Renderers)
{
case FirstPersonFlag.Auto:
{
var headlessMesh = CreateHeadlessModel(x.Renderer, FirstPersonBone);
if (headlessMesh != null)
switch (x.FirstPersonFlag)
{
case FirstPersonFlag.Auto:
{
m_headlessMeshes.Add(headlessMesh);
var headlessMesh = CreateHeadlessModel(x.Renderer, FirstPersonBone, setVisiblity);
if (headlessMesh != null)
{
m_headlessMeshes.Add(headlessMesh);
}
}
}
break;
break;

case FirstPersonFlag.FirstPersonOnly:
x.Renderer.gameObject.layer = FIRSTPERSON_ONLY_LAYER;
break;
case FirstPersonFlag.FirstPersonOnly:
setVisiblity(x.Renderer, true, false);
break;

case FirstPersonFlag.ThirdPersonOnly:
x.Renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER;
break;
case FirstPersonFlag.ThirdPersonOnly:
setVisiblity(x.Renderer, false, true);
break;

case FirstPersonFlag.Both:
//x.Renderer.gameObject.layer = 0;
break;
case FirstPersonFlag.Both:
setVisiblity(x.Renderer, true, true);
break;
}
}
}
else
{
// other avatar
foreach (var x in Renderers)
{
switch (x.FirstPersonFlag)
{
case FirstPersonFlag.FirstPersonOnly:
setVisiblity(x.Renderer, false, false);
break;

case FirstPersonFlag.Auto:
// => Same as Both
case FirstPersonFlag.Both:
case FirstPersonFlag.ThirdPersonOnly:
setVisiblity(x.Renderer, true, true);
break;
}
}
}
}
Expand Down

0 comments on commit 221945f

Please sign in to comment.