159 lines
5.4 KiB
C#
159 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UniHumanoid;
|
|
using UnityEngine;
|
|
using UnityEngine.XR;
|
|
|
|
|
|
namespace VRM
|
|
{
|
|
public class VrmMeshUtility : UniGLTF.MeshUtility.GltfMeshUtility
|
|
{
|
|
bool _generateFirstPerson = false;
|
|
public override IEnumerable<UniGLTF.MeshUtility.MeshIntegrationGroup> CopyInstantiate(GameObject go, GameObject instance)
|
|
{
|
|
_generateFirstPerson = false;
|
|
|
|
var copy = base.CopyInstantiate(go, instance);
|
|
if (GenerateMeshForFirstPersonAuto)
|
|
{
|
|
foreach (var g in copy)
|
|
{
|
|
if (g.Name == "auto")
|
|
{
|
|
_generateFirstPerson = true;
|
|
// 元のメッシュを三人称に変更
|
|
yield return new UniGLTF.MeshUtility.MeshIntegrationGroup
|
|
{
|
|
Name = FirstPersonFlag.ThirdPersonOnly.ToString(),
|
|
IntegrationType = UniGLTF.MeshUtility.MeshIntegrationGroup.MeshIntegrationTypes.ThirdPersonOnly,
|
|
Renderers = g.Renderers.ToList(),
|
|
};
|
|
}
|
|
yield return g;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var g in copy)
|
|
{
|
|
yield return g;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override bool
|
|
TryIntegrate(
|
|
GameObject empty,
|
|
UniGLTF.MeshUtility.MeshIntegrationGroup group,
|
|
out (UniGLTF.MeshUtility.MeshIntegrationResult, GameObject[]) resultAndAdded)
|
|
{
|
|
if (!base.TryIntegrate(empty, group, out resultAndAdded))
|
|
{
|
|
resultAndAdded = default;
|
|
return false;
|
|
}
|
|
|
|
var (result, newGo) = resultAndAdded;
|
|
if (_generateFirstPerson && group.Name == nameof(FirstPersonFlag.Auto))
|
|
{
|
|
// Mesh 統合の後処理
|
|
// FirstPerson == "auto" の場合に
|
|
// 頭部の無いモデルを追加で作成する
|
|
Debug.Log("generateFirstPerson");
|
|
if (result.Integrated.Mesh != null)
|
|
{
|
|
// BlendShape 有り
|
|
_ProcessFirstPerson(_vrmInstance.FirstPersonBone, result.Integrated.IntegratedRenderer);
|
|
}
|
|
if (result.IntegratedNoBlendShape.Mesh != null)
|
|
{
|
|
// BlendShape 無しの方
|
|
_ProcessFirstPerson(_vrmInstance.FirstPersonBone, result.IntegratedNoBlendShape.IntegratedRenderer);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void _ProcessFirstPerson(Transform firstPersonBone, SkinnedMeshRenderer smr)
|
|
{
|
|
var mesh = _vrmInstance.ProcessFirstPerson(firstPersonBone, smr);
|
|
if (mesh != null)
|
|
{
|
|
smr.sharedMesh = mesh;
|
|
smr.name = "auto.headless";
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("no result");
|
|
}
|
|
}
|
|
|
|
VRMFirstPerson _vrmInstance = null;
|
|
/// <summary>
|
|
/// glTF に比べて Humanoid や FirstPerson の処理が追加される
|
|
/// </summary>
|
|
public override (List<UniGLTF.MeshUtility.MeshIntegrationResult>, List<GameObject>) Process(
|
|
GameObject target, IEnumerable<UniGLTF.MeshUtility.MeshIntegrationGroup> copyGroup)
|
|
{
|
|
_vrmInstance = target.GetComponent<VRMFirstPerson>();
|
|
if (_vrmInstance == null)
|
|
{
|
|
throw new ArgumentException();
|
|
}
|
|
|
|
// TODO: update: spring
|
|
// TODO: update: constraint
|
|
// TODO: update: firstPerson offset
|
|
var (list, newList) = base.Process(target, copyGroup);
|
|
|
|
if (FreezeBlendShapeRotationAndScaling)
|
|
{
|
|
var animator = target.GetComponent<Animator>();
|
|
var newAvatar = AvatarDescription.RecreateAvatar(animator);
|
|
|
|
// ??? clear old avatar ???
|
|
var t = animator.gameObject;
|
|
if (Application.isPlaying)
|
|
{
|
|
GameObject.Destroy(animator);
|
|
}
|
|
else
|
|
{
|
|
GameObject.DestroyImmediate(animator);
|
|
}
|
|
|
|
t.AddComponent<Animator>().avatar = newAvatar;
|
|
}
|
|
|
|
return (list, newList);
|
|
}
|
|
|
|
public override void UpdateMeshIntegrationGroups(GameObject root)
|
|
{
|
|
MeshIntegrationGroups.Clear();
|
|
if (root == null)
|
|
{
|
|
return;
|
|
}
|
|
var vrm0 = root.GetComponent<VRMFirstPerson>();
|
|
if (vrm0 == null)
|
|
{
|
|
return;
|
|
}
|
|
foreach (var a in vrm0.Renderers)
|
|
{
|
|
var g = _GetOrCreateGroup(a.FirstPersonFlag.ToString());
|
|
g.Renderers.Add(a.Renderer);
|
|
}
|
|
|
|
var orphan = root.GetComponentsInChildren<Renderer>().Where(x => !_HasRenderer(x)).ToArray();
|
|
if (orphan.Length > 0)
|
|
{
|
|
var g = _GetOrCreateGroup("both");
|
|
g.Renderers.AddRange(orphan);
|
|
}
|
|
}
|
|
}
|
|
} |