mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-25 12:05:08 -05:00
vrm-0.x firstperson
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UniGLTF.M17N;
|
||||
using UniGLTF;
|
||||
|
||||
|
||||
namespace VRM
|
||||
@@ -9,7 +10,6 @@ namespace VRM
|
||||
public class VrmMeshIntegratorWizard : UniGLTF.MeshUtility.MeshUtilityDialog
|
||||
{
|
||||
public new const string MENU_NAME = "VRM 0.x MeshUtility";
|
||||
|
||||
public new static void OpenWindow()
|
||||
{
|
||||
var window =
|
||||
@@ -17,29 +17,36 @@ namespace VRM
|
||||
window.titleContent = new GUIContent(MENU_NAME);
|
||||
window.Show();
|
||||
}
|
||||
protected override void Validate()
|
||||
{
|
||||
base.Validate();
|
||||
if (_exportTarget.GetComponent<VRMMeta>() == null)
|
||||
{
|
||||
_validations.Add(Validation.Error("target is not vrm1"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// void Integrate()
|
||||
// {
|
||||
// // 統合
|
||||
// var excludes = m_excludes.Where(x => x.Exclude).Select(x => x.Mesh);
|
||||
// var results = Integrate(copy, excludes, m_separateByBlendShape);
|
||||
VrmMeshUtility _meshUtil;
|
||||
VrmMeshUtility VrmMeshUtility
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_meshUtil == null)
|
||||
{
|
||||
_meshUtil = new VrmMeshUtility();
|
||||
}
|
||||
return _meshUtil;
|
||||
}
|
||||
}
|
||||
protected override UniGLTF.MeshUtility.GltfMeshUtility MeshUtility => VrmMeshUtility;
|
||||
|
||||
// }
|
||||
|
||||
// static List<UniGLTF.MeshUtility.MeshIntegrationResult> Integrate(GameObject root, IEnumerable<Mesh> excludes, bool separateByBlendShape)
|
||||
// {
|
||||
// var results = new List<UniGLTF.MeshUtility.MeshIntegrationResult>();
|
||||
// if (separateByBlendShape)
|
||||
// {
|
||||
// results.Add(MeshIntegratorUtility.Integrate(root, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithoutBlendShape, excludes: excludes));
|
||||
// results.Add(MeshIntegratorUtility.Integrate(root, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithBlendShape, excludes: excludes));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// results.Add(MeshIntegratorUtility.Integrate(root, onlyBlendShapeRenderers: MeshEnumerateOption.All, excludes: excludes));
|
||||
// }
|
||||
// return results;
|
||||
// }
|
||||
protected override bool MeshIntegrateGui()
|
||||
{
|
||||
var firstPerson = ToggleIsModified("FirstPerson == AUTO の生成", ref MeshUtility.GenerateMeshForFirstPersonAuto);
|
||||
var mod = base.MeshIntegrateGui();
|
||||
return firstPerson || mod;
|
||||
}
|
||||
|
||||
protected override void DialogMessage()
|
||||
{
|
||||
|
||||
@@ -367,6 +367,17 @@ namespace VRM
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// for MeshUtility interface
|
||||
/// </summary>
|
||||
public Mesh ProcessFirstPerson(Transform firstPersonBone, SkinnedMeshRenderer smr)
|
||||
{
|
||||
SetVisibilityFunc dummy = (Renderer renderer, bool firstPerson, bool thirdPerson) =>
|
||||
{
|
||||
};
|
||||
return CreateHeadlessModel(smr, FirstPersonBone, dummy);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
foreach (var mesh in m_headlessMeshes)
|
||||
|
||||
138
Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs
Normal file
138
Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniHumanoid;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class VrmMeshUtility : UniGLTF.MeshUtility.GltfMeshUtility
|
||||
{
|
||||
bool _generateFirstPerson = false;
|
||||
protected override List<UniGLTF.MeshUtility.MeshIntegrationGroup> CopyMeshIntegrationGroups()
|
||||
{
|
||||
var copy = new List<UniGLTF.MeshUtility.MeshIntegrationGroup>();
|
||||
_generateFirstPerson = false;
|
||||
if (GenerateMeshForFirstPersonAuto)
|
||||
{
|
||||
foreach (var g in MeshIntegrationGroups)
|
||||
{
|
||||
if (g.Name == "auto")
|
||||
{
|
||||
_generateFirstPerson = true;
|
||||
// 元のメッシュを三人称に変更
|
||||
copy.Add(new UniGLTF.MeshUtility.MeshIntegrationGroup
|
||||
{
|
||||
Name = FirstPersonFlag.ThirdPersonOnly.ToString(),
|
||||
Renderers = g.Renderers.ToList(),
|
||||
});
|
||||
}
|
||||
copy.Add(g);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copy.AddRange(MeshIntegrationGroups);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
protected override
|
||||
(UniGLTF.MeshUtility.MeshIntegrationResult, GameObject[]) Integrate(
|
||||
GameObject empty,
|
||||
UniGLTF.MeshUtility.MeshIntegrationGroup group)
|
||||
{
|
||||
var (result, newList) = base.Integrate(empty, group);
|
||||
|
||||
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 (result, newList);
|
||||
}
|
||||
|
||||
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 go)
|
||||
{
|
||||
_vrmInstance = go.GetComponent<VRMFirstPerson>();
|
||||
if (_vrmInstance == null)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
if (ForceUniqueName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
// 必用?
|
||||
var animator = go.GetComponent<Animator>();
|
||||
var newAvatar = AvatarDescription.RecreateAvatar(animator);
|
||||
animator.avatar = newAvatar;
|
||||
}
|
||||
|
||||
// TODO: update: spring
|
||||
// TODO: update: constraint
|
||||
// TODO: update: firstPerson offset
|
||||
var (list, newList) = base.Process(go);
|
||||
|
||||
if (FreezeBlendShape || FreezeRotation || FreezeScaling)
|
||||
{
|
||||
var animator = go.GetComponent<Animator>();
|
||||
var newAvatar = AvatarDescription.RecreateAvatar(animator);
|
||||
animator.avatar = newAvatar;
|
||||
}
|
||||
|
||||
return (list, newList);
|
||||
}
|
||||
|
||||
public override void UpdateMeshIntegrationGroups(GameObject root)
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var vrm1 = root.GetComponent<VRMFirstPerson>();
|
||||
if (vrm1 == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var a in vrm1.Renderers)
|
||||
{
|
||||
var g = _GetOrCreateGroup(a.FirstPersonFlag.ToString());
|
||||
g.Renderers.Add(a.Renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs.meta
Normal file
11
Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb346da8b7688c74eb627bebe1b21060
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF.MeshUtility;
|
||||
using UniHumanoid;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
@@ -46,27 +45,51 @@ namespace UniVRM10
|
||||
{
|
||||
var (result, newList) = base.Integrate(empty, group);
|
||||
|
||||
if (_generateFirstPerson && group.Name == "auto")
|
||||
if (_generateFirstPerson && group.Name == nameof(UniGLTF.Extensions.VRMC_vrm.FirstPersonType.auto))
|
||||
{
|
||||
// Mesh 統合の後処理
|
||||
// FirstPerson == "auto" の場合に
|
||||
// 頭部の無いモデルを追加で作成する
|
||||
Debug.Log("generateFirstPerson");
|
||||
if (result.Integrated.Mesh != null)
|
||||
{
|
||||
_ProcessFirstPerson(_vrmInstance, result.Integrated);
|
||||
// BlendShape 有り
|
||||
_ProcessFirstPerson(_vrmInstance.Humanoid.Head, result.Integrated.IntegratedRenderer);
|
||||
}
|
||||
if (result.IntegratedNoBlendShape.Mesh != null)
|
||||
{
|
||||
_ProcessFirstPerson(_vrmInstance, result.IntegratedNoBlendShape);
|
||||
// BlendShape 無しの方
|
||||
_ProcessFirstPerson(_vrmInstance.Humanoid.Head, result.IntegratedNoBlendShape.IntegratedRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
return (result, newList);
|
||||
}
|
||||
|
||||
private void _ProcessFirstPerson(Transform firstPersonBone, SkinnedMeshRenderer smr)
|
||||
{
|
||||
var task = VRM10ObjectFirstPerson.CreateErasedMeshAsync(
|
||||
smr,
|
||||
firstPersonBone,
|
||||
new VRMShaders.ImmediateCaller());
|
||||
task.Wait();
|
||||
var mesh = task.Result;
|
||||
if (mesh != null)
|
||||
{
|
||||
smr.sharedMesh = mesh;
|
||||
smr.name = "auto.headless";
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("no result");
|
||||
}
|
||||
}
|
||||
|
||||
Vrm10Instance _vrmInstance = null;
|
||||
/// <summary>
|
||||
/// glTF に比べて Humanoid や FirstPerson の処理が追加される
|
||||
/// </summary>
|
||||
public override (List<MeshIntegrationResult>, List<GameObject>) Process(GameObject go)
|
||||
public override (List<UniGLTF.MeshUtility.MeshIntegrationResult>, List<GameObject>) Process(GameObject go)
|
||||
{
|
||||
_vrmInstance = go.GetComponent<Vrm10Instance>();
|
||||
if (_vrmInstance == null)
|
||||
@@ -99,26 +122,6 @@ namespace UniVRM10
|
||||
return (list, newList);
|
||||
}
|
||||
|
||||
void _ProcessFirstPerson(Vrm10Instance vrmInstance, UniGLTF.MeshUtility.MeshInfo info)
|
||||
{
|
||||
var firstPersonBone = vrmInstance.Humanoid.Head;
|
||||
var task = VRM10ObjectFirstPerson.CreateErasedMeshAsync(
|
||||
info.IntegratedRenderer,
|
||||
firstPersonBone,
|
||||
new VRMShaders.ImmediateCaller());
|
||||
task.Wait();
|
||||
|
||||
if (task.Result != null)
|
||||
{
|
||||
info.IntegratedRenderer.sharedMesh = task.Result;
|
||||
info.IntegratedRenderer.name = "auto.headless";
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("no result");
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateMeshIntegrationGroups(GameObject root)
|
||||
{
|
||||
if (root == null)
|
||||
|
||||
Reference in New Issue
Block a user