mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-15 17:52:57 -05:00
InternalTPose.cs
This commit is contained in:
parent
78cda85380
commit
59eb769cd6
95
Assets/VRM/Editor/Format/InternalTPose.cs
Normal file
95
Assets/VRM/Editor/Format/InternalTPose.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UniGLTF;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public static class InternalTPose
|
||||
{
|
||||
struct TRS
|
||||
{
|
||||
public Vector3 T;
|
||||
public Quaternion R;
|
||||
public Vector3 S;
|
||||
|
||||
public void Apply(Transform t)
|
||||
{
|
||||
t.localPosition = T;
|
||||
t.localRotation = R;
|
||||
t.localScale = S;
|
||||
}
|
||||
|
||||
public static TRS From(Transform t)
|
||||
{
|
||||
return new TRS
|
||||
{
|
||||
T = t.localPosition,
|
||||
R = t.localRotation,
|
||||
S = t.localScale,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void BuildMap(Transform t, Dictionary<string, TRS> map, Transform root = null)
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
root = t;
|
||||
}
|
||||
|
||||
map.Add(t.RelativePathFrom(root), TRS.From(t));
|
||||
|
||||
foreach (Transform child in t)
|
||||
{
|
||||
BuildMap(child, map, root);
|
||||
}
|
||||
}
|
||||
|
||||
static void ApplyMap(Transform t, Dictionary<string, TRS> map, Transform root = null)
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
root = t;
|
||||
}
|
||||
|
||||
map[t.RelativePathFrom(root)].Apply(t);
|
||||
|
||||
foreach (Transform child in t)
|
||||
{
|
||||
ApplyMap(child, map, root);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TrySampleBindPose(GameObject go)
|
||||
{
|
||||
// https://forum.unity.com/threads/mesh-bindposes.383752/
|
||||
var type = Type.GetType("UnityEditor.AvatarSetupTool, UnityEditor");
|
||||
if (type != null)
|
||||
{
|
||||
var info = type.GetMethod("SampleBindPose", BindingFlags.Static | BindingFlags.Public);
|
||||
if (info != null)
|
||||
{
|
||||
// prefab cause error message. create copy
|
||||
var clone = GameObject.Instantiate(go);
|
||||
try
|
||||
{
|
||||
info.Invoke(null, new object[] { clone });
|
||||
var map = new Dictionary<string, TRS>();
|
||||
BuildMap(clone.transform, map);
|
||||
ApplyMap(go.transform, map);
|
||||
}
|
||||
finally
|
||||
{
|
||||
GameObject.DestroyImmediate(clone);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM/Editor/Format/InternalTPose.cs.meta
Normal file
11
Assets/VRM/Editor/Format/InternalTPose.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 42e52c1a93301da4eb0435ed00bdf8c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -4,6 +4,9 @@ using UnityEditor;
|
|||
using UnityEngine;
|
||||
using MeshUtility.M17N;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
|
|
@ -49,7 +52,7 @@ namespace VRM
|
|||
return MeshUtility.M17N.Getter.Msg(key);
|
||||
}
|
||||
|
||||
enum Options
|
||||
public enum Options
|
||||
{
|
||||
[LangMsg(Languages.ja, "エクスポート時に強制的にT-Pose化する。これを使わずに手動でT-Poseを作っても問題ありません")]
|
||||
[LangMsg(Languages.en, "Force T-Pose before export. Manually making T-Pose for model without enabling this is ok")]
|
||||
|
|
@ -110,23 +113,6 @@ namespace VRM
|
|||
m_divideVertexBuffer = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.DivideVertexBuffer)), Options.DIVIDE_VERTEX_BUFFER);
|
||||
}
|
||||
|
||||
static bool TrySampleBindPose(GameObject go)
|
||||
{
|
||||
// https://forum.unity.com/threads/mesh-bindposes.383752/
|
||||
var type = Type.GetType("UnityEditor.AvatarSetupTool, UnityEditor");
|
||||
if (type != null)
|
||||
{
|
||||
var info = type.GetMethod("SampleBindPose", BindingFlags.Static | BindingFlags.Public);
|
||||
if (info != null)
|
||||
{
|
||||
var clone = GameObject.Instantiate(go);
|
||||
info.Invoke(null, new object[] { clone });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
|
@ -143,19 +129,26 @@ namespace VRM
|
|||
{
|
||||
EditorGUILayout.HelpBox(Options.DISABLE_TPOSE_BUTTON.Msg(), MessageType.Warning);
|
||||
}
|
||||
if (GUILayout.Button(Options.DO_TPOSE.Msg()))
|
||||
|
||||
//
|
||||
// T-Pose
|
||||
//
|
||||
if (GUILayout.Button(VRMExportSettingsEditor.Options.DO_TPOSE.Msg()))
|
||||
{
|
||||
if (settings.Root != null)
|
||||
{
|
||||
// fallback
|
||||
Undo.RecordObjects(settings.Root.GetComponentsInChildren<Transform>(), "tpose");
|
||||
VRMBoneNormalizer.EnforceTPose(settings.Root);
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button(Options.DO_TPOSE.Msg() + "(internal)"))
|
||||
|
||||
if (GUILayout.Button(VRMExportSettingsEditor.Options.DO_TPOSE.Msg() + "(internal)"))
|
||||
{
|
||||
if (settings.Root != null)
|
||||
{
|
||||
if (TrySampleBindPose(settings.Root))
|
||||
Undo.RecordObjects(settings.Root.GetComponentsInChildren<Transform>(), "tpose.internal");
|
||||
if (InternalTPose.TrySampleBindPose(settings.Root))
|
||||
{
|
||||
// done
|
||||
}
|
||||
|
|
@ -165,6 +158,7 @@ namespace VRM
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUI.enabled = backup;
|
||||
GUILayout.Space(20);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user