WIP VRM10Object

This commit is contained in:
ousttrue
2021-06-15 19:02:48 +09:00
parent 1a063ff3f6
commit cb59024f8e
40 changed files with 636 additions and 809 deletions

View File

@@ -7,10 +7,10 @@ namespace UniVRM10.Samples
public class AIUEO : MonoBehaviour
{
[SerializeField]
public VRM10Controller VRM;
public VRM10Controller Controller;
private void Reset()
{
VRM = GetComponent<VRM10Controller>();
Controller = GetComponent<VRM10Controller>();
}
Coroutine m_coroutine;
@@ -20,9 +20,9 @@ namespace UniVRM10.Samples
private void Awake()
{
if (VRM == null)
if (Controller == null)
{
VRM = GetComponent<VRM10Controller>();
Controller = GetComponent<VRM10Controller>();
}
}
@@ -30,17 +30,17 @@ namespace UniVRM10.Samples
{
for (var value = 0.0f; value <= 1.0f; value += velocity)
{
VRM.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
Controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
yield return null;
}
VRM.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 1.0f);
Controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 1.0f);
yield return new WaitForSeconds(wait);
for (var value = 1.0f; value >= 0; value -= velocity)
{
VRM.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
Controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
yield return null;
}
VRM.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 0);
Controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 0);
yield return new WaitForSeconds(wait * 2);
}

View File

@@ -72,10 +72,10 @@ namespace UniVRM10.Samples
break;
}
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), value);
m_controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), value);
yield return null;
}
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), 1.0f);
m_controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), 1.0f);
// wait...
yield return new WaitForSeconds(ClosingTime);
@@ -91,10 +91,10 @@ namespace UniVRM10.Samples
break;
}
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), value);
m_controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), value);
yield return null;
}
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), 0);
m_controller.Vrm.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), 0);
}
}

View File

@@ -84,7 +84,7 @@ namespace UniVRM10.Samples
m_textDistributionOther.text = "";
}
public void UpdateMeta(VRM10MetaObject meta)
public void UpdateMeta(VRM10ObjectMeta meta)
{
if (meta == null)
{
@@ -379,9 +379,9 @@ namespace UniVRM10.Samples
if (m_controller != null)
{
m_texts.UpdateMeta(m_controller.Meta.Meta);
m_texts.UpdateMeta(m_controller.Vrm.Meta);
m_controller.Controller.UpdateType = VRM10Controller.VRM10ControllerImpl.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
m_controller.UpdateType = VRM10Controller.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
{
m_loaded = go.AddComponent<HumanPoseTransfer>();
m_loaded.Source = m_src;
@@ -390,7 +390,7 @@ namespace UniVRM10.Samples
m_lipSync = go.AddComponent<AIUEO>();
m_blink = go.AddComponent<Blinker>();
m_controller.LookAt.Gaze = m_target.transform;
m_controller.Vrm.LookAt.Gaze = m_target.transform;
}
}

View File

@@ -1,4 +1,5 @@
using UnityEditor;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace UniVRM10
@@ -254,5 +255,18 @@ namespace UniVRM10
}
}
}
public static VRM10Expression CreateExpression(string path)
{
//Debug.LogFormat("{0}", path);
var clip = ScriptableObject.CreateInstance<VRM10Expression>();
clip.ExpressionName = Path.GetFileNameWithoutExtension(path);
AssetDatabase.CreateAsset(clip, path);
AssetDatabase.ImportAsset(path);
return clip;
//Clips.Add(clip);
//EditorUtility.SetDirty(this);
//AssetDatabase.SaveAssets();
}
}
}

View File

@@ -11,7 +11,7 @@ namespace UniVRM10
/// </summary>
class ExpressionClipSelector
{
VRM10ExpressionAvatar m_avatar;
VRM10ObjectExpression m_avatar;
int m_mode;
static readonly string[] MODES = new string[]{
@@ -60,21 +60,21 @@ namespace UniVRM10
}
}
public ExpressionClipSelector(VRM10ExpressionAvatar avatar, SerializedObject serializedObject)
public ExpressionClipSelector(VRM10ObjectExpression avatar, string dir, SerializedObject serializedObject)
{
avatar.RemoveNullClip();
m_avatar = avatar;
var prop = serializedObject.FindProperty("Clips");
m_clipList = new ReorderableExpressionList(serializedObject, prop, avatar);
m_clipList = new ReorderableExpressionList(serializedObject, prop, dir);
m_clipList.Selected += (selected) =>
{
SelectedIndex = avatar.Clips.IndexOf(selected);
};
}
public void DrawGUI()
public void DrawGUI(string dir)
{
var backup = GUI.enabled;
try
@@ -87,7 +87,7 @@ namespace UniVRM10
switch (m_mode)
{
case 0:
SelectGUI();
SelectGUI(dir);
break;
case 1:
@@ -104,7 +104,7 @@ namespace UniVRM10
}
}
void SelectGUI()
void SelectGUI(string dir)
{
if (m_avatar != null && m_avatar.Clips != null)
{
@@ -118,7 +118,6 @@ namespace UniVRM10
if (GUILayout.Button("Add Expression"))
{
var dir = Path.GetDirectoryName(AssetDatabase.GetAssetPath(m_avatar));
var path = EditorUtility.SaveFilePanel(
"Create Expression",
dir,
@@ -126,7 +125,7 @@ namespace UniVRM10
"asset");
if (!string.IsNullOrEmpty(path))
{
var clip = VRM10ExpressionAvatar.CreateExpression(path.ToUnityRelativePath());
var clip = ExpressionEditorBase.CreateExpression(path.ToUnityRelativePath());
//clip.Prefab = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GetAssetPath(target));
m_avatar.Clips.Add(clip);

View File

@@ -2,6 +2,7 @@ using System;
using System.IO;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace UniVRM10
{
@@ -25,7 +26,7 @@ namespace UniVRM10
m_list.index = index;
}
public ReorderableExpressionList(SerializedObject serializedObject, SerializedProperty prop, UnityEngine.Object target)
public ReorderableExpressionList(SerializedObject serializedObject, SerializedProperty prop, string dir)
{
m_list = new ReorderableList(serializedObject, prop);
@@ -50,7 +51,7 @@ namespace UniVRM10
var element = prop.GetArrayElementAtIndex(list.index);
element.objectReferenceValue = null;
var dir = Path.GetDirectoryName(AssetDatabase.GetAssetPath(target));
// var dir = Path.GetDirectoryName(AssetDatabase.GetAssetPath(target));
var path = EditorUtility.SaveFilePanel(
"Create Expression",
dir,
@@ -58,7 +59,7 @@ namespace UniVRM10
"asset");
if (!string.IsNullOrEmpty(path))
{
var clip = VRM10ExpressionAvatar.CreateExpression(path.ToUnityRelativePath());
var clip = ExpressionEditorBase.CreateExpression(path.ToUnityRelativePath());
//clip.Prefab = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GetAssetPath(target));
element.objectReferenceValue = clip;

View File

@@ -20,8 +20,8 @@ namespace UniVRM10
{
m_target = target;
m_expressionKeyWeights = m_target.Expression.Clips.ToDictionary(x => ExpressionKey.CreateFromClip(x), x => 0.0f);
m_sliders = m_target.Expression.Clips
m_expressionKeyWeights = m_target.Vrm.Expression.Clips.ToDictionary(x => ExpressionKey.CreateFromClip(x), x => 0.0f);
m_sliders = m_target.Vrm.Expression.Clips
.Where(x => x != null)
.Select(x => new ExpressionSlider(m_expressionKeyWeights, ExpressionKey.CreateFromClip(x)))
.ToList()
@@ -48,16 +48,16 @@ namespace UniVRM10
{
m_expressionKeyWeights[slider.Key] = slider.Value;
}
m_target.Expression.SetWeights(m_expressionKeyWeights);
m_target.Vrm.Expression.SetWeights(m_expressionKeyWeights);
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Override rates", EditorStyles.boldLabel);
EditorGUI.BeginDisabledGroup(true);
{
EditorGUILayout.Slider("Blink override rate", m_target.Expression.BlinkOverrideRate, 0f, 1f);
EditorGUILayout.Slider("LookAt override rate", m_target.Expression.LookAtOverrideRate, 0f, 1f);
EditorGUILayout.Slider("Mouth override rate", m_target.Expression.MouthOverrideRate, 0f, 1f);
EditorGUILayout.Slider("Blink override rate", m_target.Vrm.Expression.BlinkOverrideRate, 0f, 1f);
EditorGUILayout.Slider("LookAt override rate", m_target.Vrm.Expression.LookAtOverrideRate, 0f, 1f);
EditorGUILayout.Slider("Mouth override rate", m_target.Vrm.Expression.MouthOverrideRate, 0f, 1f);
}
EditorGUI.EndDisabledGroup();
}

View File

@@ -1,84 +0,0 @@
using UnityEditor;
using UnityEngine;
namespace UniVRM10
{
[CustomEditor(typeof(VRM10ExpressionAvatar))]
public class ExpressionAvatarEditor : ExpressionEditorBase
{
/// <summary>
/// ExpressionAvatar から 編集対象の Expression を選択する
/// </summary>
ExpressionClipSelector m_selector;
ExpressionClipSelector Selector
{
get
{
if (m_selector == null)
{
m_selector = new ExpressionClipSelector((VRM10ExpressionAvatar)target, serializedObject);
m_selector.Selected += OnSelected;
OnSelected(m_selector.GetSelected());
}
return m_selector;
}
}
protected override GameObject GetPrefab()
{
return PrefabUtility.GetCorrespondingObjectFromSource(target as VRM10ExpressionAvatar)?.gameObject;
}
/// <summary>
/// 選択中の Expression のエディタ
/// </summary>
SerializedExpressionEditor m_serializedEditor;
protected override VRM10Expression CurrentExpression()
{
return Selector.GetSelected();
}
void OnSelected(VRM10Expression clip)
{
if (PreviewSceneManager == null)
{
m_serializedEditor = null;
return;
}
if (clip != null)
{
// select clip
var status = SerializedExpressionEditor.EditorStatus.Default;
if (m_serializedEditor != null)
{
status = m_serializedEditor.Status;
}
m_serializedEditor = new SerializedExpressionEditor(clip, PreviewSceneManager, status);
}
else
{
// clear selection
m_serializedEditor = null;
PreviewSceneManager.Bake(default, 1.0f);
}
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
// selector
Selector.DrawGUI();
// editor
if (m_serializedEditor != null)
{
Separator();
m_serializedEditor.Draw(out VRM10Expression bakeValue);
PreviewSceneManager.Bake(bakeValue, 1.0f);
}
}
}
}

View File

@@ -25,25 +25,25 @@ namespace UniVRM10
if (!Application.isPlaying)
{
// offset
var p = target.LookAt.OffsetFromHead;
var p = target.Vrm.LookAt.OffsetFromHead;
Handles.Label(head.position, $"fromHead: [{p.x:0.00}, {p.y:0.00}, {p.z:0.00}]");
}
else
{
target.LookAt.OnSceneGUILookAt(head);
target.Vrm.LookAt.OnSceneGUILookAt(head);
}
}
static void OnSceneGUIOffset(VRM10Controller m_target, Transform head)
{
if (!m_target.LookAt.DrawGizmo)
if (!m_target.Vrm.LookAt.DrawGizmo)
{
return;
}
EditorGUI.BeginChangeCheck();
var worldOffset = head.localToWorldMatrix.MultiplyPoint(m_target.LookAt.OffsetFromHead);
var worldOffset = head.localToWorldMatrix.MultiplyPoint(m_target.Vrm.LookAt.OffsetFromHead);
worldOffset = Handles.PositionHandle(worldOffset, head.rotation);
Handles.DrawDottedLine(head.position, worldOffset, 5);
@@ -54,7 +54,7 @@ namespace UniVRM10
{
Undo.RecordObject(m_target, "Changed FirstPerson");
m_target.LookAt.OffsetFromHead = head.worldToLocalMatrix.MultiplyPoint(worldOffset);
m_target.Vrm.LookAt.OffsetFromHead = head.worldToLocalMatrix.MultiplyPoint(worldOffset);
}
}
}

View File

@@ -211,9 +211,9 @@ namespace UniVRM10
rect.y += 2;
SerializedProperty element = prop.GetArrayElementAtIndex(index);
var elements = target.SpringBone.ColliderGroups;
var elements = target.Vrm.SpringBone.ColliderGroups;
var element_index = elements.IndexOf(element.objectReferenceValue as VRM10SpringBoneColliderGroup);
var colliderGroups = target.SpringBone.ColliderGroups.Select((x, y) => x.GUIName(y)).ToArray();
var colliderGroups = target.Vrm.SpringBone.ColliderGroups.Select((x, y) => x.GUIName(y)).ToArray();
var new_index = EditorGUI.Popup(rect, element_index, colliderGroups);
if (new_index != element_index)
{

View File

@@ -37,9 +37,9 @@ namespace UniVRM10
// load
_map = new Dictionary<int, object>();
for (var i = 0; i < target.SpringBone.ColliderGroups.Count; ++i)
for (var i = 0; i < target.Vrm.SpringBone.ColliderGroups.Count; ++i)
{
var colliderGroup = target.SpringBone.ColliderGroups[i];
var colliderGroup = target.Vrm.SpringBone.ColliderGroups[i];
var name = colliderGroup.GUIName(i);
var id = _nextNodeID++;
var item = new TreeViewItem(id, 2, name);
@@ -47,9 +47,9 @@ namespace UniVRM10
_colliderGroups.AddChild(item);
}
for (var i = 0; i < target.SpringBone.Springs.Count; ++i)
for (var i = 0; i < target.Vrm.SpringBone.Springs.Count; ++i)
{
var spring = target.SpringBone.Springs[i];
var spring = target.Vrm.SpringBone.Springs[i];
var name = spring.GUIName(i);
var id = _nextNodeID++;
var item = new TreeViewItem(id, 2, name);
@@ -72,12 +72,12 @@ namespace UniVRM10
{
if (value is VRM10SpringBoneColliderGroup colliderGroup)
{
var i = Target.SpringBone.ColliderGroups.IndexOf(colliderGroup);
var i = Target.Vrm.SpringBone.ColliderGroups.IndexOf(colliderGroup);
_selected = new SelectedColliderGroupGUI(_so, i);
}
else if (value is VRM10ControllerSpringBone.Spring spring)
{
var i = Target.SpringBone.Springs.IndexOf(spring);
var i = Target.Vrm.SpringBone.Springs.IndexOf(spring);
_selected = new SelectedSpringGUI(Target, _so, i);
}
}

View File

@@ -1,27 +1,18 @@
using UniGLTF;
using System;
using System.IO;
using UniGLTF;
using UnityEditor;
using UnityEngine;
namespace UniVRM10
{
/// <summary>
/// VRM10Controller CustomEditor
///
/// * Controller
/// * Meta
/// * Expression
/// * LookAt
/// * ForstPerson
///
/// </summary>
[CustomEditor(typeof(VRM10Controller))]
public class VRM10ControllerEditor : Editor
[CustomEditor(typeof(VRM10Object))]
public class VRM10ObjectEditor : Editor
{
VRM10Controller m_target;
VRM10Object m_target;
enum Tabs
{
Controller,
Meta,
Expression,
LookAt,
@@ -30,14 +21,8 @@ namespace UniVRM10
}
Tabs _tab = Tabs.Meta;
// for ScriptedObject
Editor m_metaEditor;
// expression
VRM10ControllerEditorExpression m_expression;
// for SerializedProperty
PropGui m_controller;
PropGui m_expression;
PropGui m_meta;
PropGui m_lookAt;
PropGui m_springBone;
@@ -46,28 +31,15 @@ namespace UniVRM10
void OnEnable()
{
m_target = (VRM10Controller)target;
m_expression = new VRM10ControllerEditorExpression(m_target);
if (m_target?.Meta.Meta != null)
{
m_metaEditor = Editor.CreateEditor(m_target.Meta.Meta);
}
m_controller = new PropGui(serializedObject.FindProperty(nameof(m_target.Controller)));
m_target = (VRM10Object)target;
m_expression = new PropGui(serializedObject.FindProperty(nameof(m_target.Expression)));
m_meta = new PropGui(serializedObject.FindProperty(nameof(m_target.Meta)));
m_lookAt = new PropGui(serializedObject.FindProperty(nameof(m_target.LookAt)));
m_springBone = new PropGui(serializedObject.FindProperty(nameof(m_target.SpringBone)));
m_firstPerson = new PropGui(serializedObject.FindProperty(nameof(m_target.FirstPerson)));
}
void OnDisable()
{
if (m_metaEditor)
{
UnityEditor.Editor.DestroyImmediate(m_metaEditor);
m_metaEditor = null;
}
}
public override void OnInspectorGUI()
{
// select sub editor
@@ -82,15 +54,10 @@ namespace UniVRM10
{
case Tabs.Meta:
m_meta.RecursiveProperty();
m_metaEditor?.OnInspectorGUI();
break;
case Tabs.Controller:
m_controller.RecursiveProperty();
break;
case Tabs.Expression:
m_expression.OnGUI();
m_expression.RecursiveProperty();
break;
case Tabs.LookAt:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d985854d00eb11241b09522432e2d057
guid: 545fc17b99797d442a476622ba04f8dd
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -17,7 +17,7 @@ namespace UniVRM10
{
public static void OnGUI(ScriptedImporter importer, GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)
{
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is VRM10MetaObject || x.Value is VRM10ExpressionAvatar || x.Value is VRM10Expression);
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is VRM10Object || x.Value is VRM10Expression);
using (new EditorGUI.DisabledScope(hasExternal))
{
if (GUILayout.Button("Extract Meta And Expressions ..."))
@@ -27,7 +27,7 @@ namespace UniVRM10
}
// meta
importer.DrawRemapGUI<VRM10MetaObject>(new SubAssetKey[] { VRM10MetaObject.SubAssetKey });
importer.DrawRemapGUI<VRM10Object>(new SubAssetKey[] { VRM10Object.SubAssetKey });
// expressions
importer.DrawRemapGUI<VRM10Expression>(vrm.Expressions.Select(x => ExpressionKey.CreateFromVrm10(x).SubAssetKey));
@@ -35,7 +35,7 @@ namespace UniVRM10
if (GUILayout.Button("Clear"))
{
importer.ClearExternalObjects(
typeof(VRM10MetaObject),
typeof(VRM10ObjectMeta),
typeof(VRM10Expression));
}
}
@@ -57,7 +57,12 @@ namespace UniVRM10
}
/// <summary>
/// SubAssetを外部ファイルに展開する
///
/// * VRM10Object
/// * VRM10Expression[]
///
/// が Extract 対象となる
///
/// </summary>
public static void Extract(ScriptedImporter importer, GltfParser parser)
{
@@ -66,23 +71,16 @@ namespace UniVRM10
return;
}
// meta
var path = GetAndCreateFolder(importer.assetPath, ".Vrm1Object");
{
var path = GetAndCreateFolder(importer.assetPath, ".vrm1.MetaObject");
foreach (var (key, asset) in importer.GetSubAssets<VRM10MetaObject>(importer.assetPath))
foreach (var (key, asset) in importer.GetSubAssets<VRM10Object>(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{asset.name}.asset", false);
}
}
{
// expressions
var path = GetAndCreateFolder(importer.assetPath, ".vrm1.Expressions");
foreach (var (key, asset) in importer.GetSubAssets<VRM10Expression>(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{asset.name}.asset", false);
}
}
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);

View File

@@ -1,291 +1,291 @@
using UnityEditor;
using UnityEngine;
using UniGLTF;
using UniGLTF.M17N;
// using UnityEditor;
// using UnityEngine;
// using UniGLTF;
// using UniGLTF.M17N;
namespace UniVRM10
{
[CustomEditor(typeof(VRM10MetaObject))]
public class VRMM10etaObjectEditor : Editor
{
class ValidateProperty
{
public SerializedProperty m_prop;
// namespace UniVRM10
// {
// [CustomEditor(typeof(VRM10ObjectMeta))]
// public class VRMM10etaObjectEditor : Editor
// {
// class ValidateProperty
// {
// public SerializedProperty m_prop;
public delegate (string, MessageType) Validator(SerializedProperty prop);
Validator m_validator;
// public delegate (string, MessageType) Validator(SerializedProperty prop);
// Validator m_validator;
public ValidateProperty(SerializedProperty prop, Validator validator)
{
m_prop = prop;
m_validator = validator;
}
// public ValidateProperty(SerializedProperty prop, Validator validator)
// {
// m_prop = prop;
// m_validator = validator;
// }
public void OnGUI()
{
// var old = m_prop.stringValue;
if (m_prop.propertyType == SerializedPropertyType.Generic)
{
if (m_prop.arrayElementType != null)
{
EditorGUILayout.LabelField(m_prop.name);
// public void OnGUI()
// {
// // var old = m_prop.stringValue;
// if (m_prop.propertyType == SerializedPropertyType.Generic)
// {
// if (m_prop.arrayElementType != null)
// {
// EditorGUILayout.LabelField(m_prop.name);
var depth = m_prop.depth;
var iterator = m_prop.Copy();
for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false)
{
if (iterator.depth < depth)
break;
// var depth = m_prop.depth;
// var iterator = m_prop.Copy();
// for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false)
// {
// if (iterator.depth < depth)
// break;
depth = iterator.depth;
// depth = iterator.depth;
// using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
EditorGUILayout.PropertyField(iterator, true);
}
}
else
{
throw new System.NotImplementedException();
}
}
else
{
EditorGUILayout.PropertyField(m_prop);
}
var (msg, msgType) = m_validator(m_prop);
if (!string.IsNullOrEmpty(msg))
{
EditorGUILayout.HelpBox(msg, msgType);
}
// return old != m_prop.stringValue;
}
}
// // using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
// EditorGUILayout.PropertyField(iterator, true);
// }
// }
// else
// {
// throw new System.NotImplementedException();
// }
// }
// else
// {
// EditorGUILayout.PropertyField(m_prop);
// }
// var (msg, msgType) = m_validator(m_prop);
// if (!string.IsNullOrEmpty(msg))
// {
// EditorGUILayout.HelpBox(msg, msgType);
// }
// // return old != m_prop.stringValue;
// }
// }
VRM10MetaObject m_target;
SerializedProperty m_Script;
SerializedProperty m_exporterVersion;
SerializedProperty m_thumbnail;
ValidateProperty m_title;
ValidateProperty m_version;
ValidateProperty m_author;
ValidateProperty m_contact;
ValidateProperty m_reference;
// VRM10ObjectMeta m_target;
// SerializedProperty m_Script;
// SerializedProperty m_exporterVersion;
// SerializedProperty m_thumbnail;
// ValidateProperty m_title;
// ValidateProperty m_version;
// ValidateProperty m_author;
// ValidateProperty m_contact;
// ValidateProperty m_reference;
SerializedProperty m_AllowedUser;
SerializedProperty m_ViolentUssage;
SerializedProperty m_SexualUssage;
SerializedProperty m_CommercialUssage;
SerializedProperty m_PoliticalOrReligiousUsage;
SerializedProperty m_OtherPermissionUrl;
// SerializedProperty m_AllowedUser;
// SerializedProperty m_ViolentUssage;
// SerializedProperty m_SexualUssage;
// SerializedProperty m_CommercialUssage;
// SerializedProperty m_PoliticalOrReligiousUsage;
// SerializedProperty m_OtherPermissionUrl;
SerializedProperty m_LicenseType;
SerializedProperty m_OtherLicenseUrl;
// SerializedProperty m_LicenseType;
// SerializedProperty m_OtherLicenseUrl;
static string RequiredMessage(string name)
{
switch (LanguageGetter.Lang)
{
case Languages.ja:
return $"必須項目。{name} を入力してください";
// static string RequiredMessage(string name)
// {
// switch (LanguageGetter.Lang)
// {
// case Languages.ja:
// return $"必須項目。{name} を入力してください";
case Languages.en:
return $"{name} is required";
// case Languages.en:
// return $"{name} is required";
default:
throw new System.NotImplementedException();
}
}
// default:
// throw new System.NotImplementedException();
// }
// }
private void OnEnable()
{
if (target == null)
{
return;
}
m_target = (VRM10MetaObject)target;
// private void OnEnable()
// {
// if (target == null)
// {
// return;
// }
// m_target = (VRM10ObjectMeta)target;
m_Script = serializedObject.FindProperty("m_Script");
m_exporterVersion = serializedObject.FindProperty(nameof(m_target.ExporterVersion));
m_thumbnail = serializedObject.FindProperty(nameof(m_target.Thumbnail));
// m_Script = serializedObject.FindProperty("m_Script");
// m_exporterVersion = serializedObject.FindProperty(nameof(m_target.ExporterVersion));
// m_thumbnail = serializedObject.FindProperty(nameof(m_target.Thumbnail));
m_title = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.Name)), prop =>
{
if (string.IsNullOrEmpty(prop.stringValue))
{
return (RequiredMessage(prop.name), MessageType.Error);
}
return ("", MessageType.None);
});
m_version = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.Version)), prop =>
{
// if (string.IsNullOrEmpty(prop.stringValue))
// {
// return (RequiredMessage(prop.name), MessageType.Error);
// }
return ("", MessageType.None);
});
m_author = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.Authors)), prop =>
{
if (prop.arraySize == 0)
{
return (RequiredMessage(prop.name), MessageType.Error);
}
return ("", MessageType.None);
});
m_contact = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.ContactInformation)), prop =>
{
return ("", MessageType.None);
});
m_reference = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.References)), prop =>
{
return ("", MessageType.None);
});
// m_title = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.Name)), prop =>
// {
// if (string.IsNullOrEmpty(prop.stringValue))
// {
// return (RequiredMessage(prop.name), MessageType.Error);
// }
// return ("", MessageType.None);
// });
// m_version = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.Version)), prop =>
// {
// // if (string.IsNullOrEmpty(prop.stringValue))
// // {
// // return (RequiredMessage(prop.name), MessageType.Error);
// // }
// return ("", MessageType.None);
// });
// m_author = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.Authors)), prop =>
// {
// if (prop.arraySize == 0)
// {
// return (RequiredMessage(prop.name), MessageType.Error);
// }
// return ("", MessageType.None);
// });
// m_contact = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.ContactInformation)), prop =>
// {
// return ("", MessageType.None);
// });
// m_reference = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.References)), prop =>
// {
// return ("", MessageType.None);
// });
m_AllowedUser = serializedObject.FindProperty(nameof(m_target.AllowedUser));
m_ViolentUssage = serializedObject.FindProperty(nameof(m_target.ViolentUsage));
m_SexualUssage = serializedObject.FindProperty(nameof(m_target.SexualUsage));
m_CommercialUssage = serializedObject.FindProperty(nameof(m_target.CommercialUsage));
m_PoliticalOrReligiousUsage = serializedObject.FindProperty(nameof(m_target.PoliticalOrReligiousUsage));
m_OtherPermissionUrl = serializedObject.FindProperty(nameof(m_target.OtherLicenseUrl));
// m_AllowedUser = serializedObject.FindProperty(nameof(m_target.AllowedUser));
// m_ViolentUssage = serializedObject.FindProperty(nameof(m_target.ViolentUsage));
// m_SexualUssage = serializedObject.FindProperty(nameof(m_target.SexualUsage));
// m_CommercialUssage = serializedObject.FindProperty(nameof(m_target.CommercialUsage));
// m_PoliticalOrReligiousUsage = serializedObject.FindProperty(nameof(m_target.PoliticalOrReligiousUsage));
// m_OtherPermissionUrl = serializedObject.FindProperty(nameof(m_target.OtherLicenseUrl));
// m_LicenseType = serializedObject.FindProperty(nameof(m_target.));
// // m_LicenseType = serializedObject.FindProperty(nameof(m_target.));
m_OtherLicenseUrl = serializedObject.FindProperty(nameof(m_target.OtherLicenseUrl));
}
// m_OtherLicenseUrl = serializedObject.FindProperty(nameof(m_target.OtherLicenseUrl));
// }
enum MessageKeys
{
[LangMsg(Languages.ja, "アバターの人格に関する許諾範囲")]
[LangMsg(Languages.en, "Personation / Characterization Permission")]
PERSONATION,
// enum MessageKeys
// {
// [LangMsg(Languages.ja, "アバターの人格に関する許諾範囲")]
// [LangMsg(Languages.en, "Personation / Characterization Permission")]
// PERSONATION,
[LangMsg(Languages.ja, "アバターに人格を与えることの許諾範囲")]
[LangMsg(Languages.en, "A person who can perform with this avatar")]
ALLOWED_USER,
// [LangMsg(Languages.ja, "アバターに人格を与えることの許諾範囲")]
// [LangMsg(Languages.en, "A person who can perform with this avatar")]
// ALLOWED_USER,
[LangMsg(Languages.ja, "このアバターを用いて暴力表現を演じることの許可")]
[LangMsg(Languages.en, "Violent acts using this avatar")]
VIOLENT_USAGE,
// [LangMsg(Languages.ja, "このアバターを用いて暴力表現を演じることの許可")]
// [LangMsg(Languages.en, "Violent acts using this avatar")]
// VIOLENT_USAGE,
[LangMsg(Languages.ja, "このアバターを用いて性的表現を演じることの許可")]
[LangMsg(Languages.en, "Sexuality acts using this avatar")]
SEXUAL_USAGE,
// [LangMsg(Languages.ja, "このアバターを用いて性的表現を演じることの許可")]
// [LangMsg(Languages.en, "Sexuality acts using this avatar")]
// SEXUAL_USAGE,
[LangMsg(Languages.ja, "商用利用の許可")]
[LangMsg(Languages.en, "For commercial use")]
COMMERCIAL_USAGE,
// [LangMsg(Languages.ja, "商用利用の許可")]
// [LangMsg(Languages.en, "For commercial use")]
// COMMERCIAL_USAGE,
[LangMsg(Languages.ja, "再配布・改変に関する許諾範囲")]
[LangMsg(Languages.en, "Redistribution / Modifications License")]
REDISTRIBUTION_MODIFICATIONS,
// [LangMsg(Languages.ja, "再配布・改変に関する許諾範囲")]
// [LangMsg(Languages.en, "Redistribution / Modifications License")]
// REDISTRIBUTION_MODIFICATIONS,
// [LangMsg(Languages.ja, "")]
// [LangMsg(Languages.en, "")]
}
// // [LangMsg(Languages.ja, "")]
// // [LangMsg(Languages.en, "")]
// }
static string Msg(MessageKeys key)
{
return LanguageGetter.Msg(key);
}
// static string Msg(MessageKeys key)
// {
// return LanguageGetter.Msg(key);
// }
bool m_foldoutInfo = true;
bool m_foldoutPermission = true;
bool m_foldoutDistribution = true;
// bool m_foldoutInfo = true;
// bool m_foldoutPermission = true;
// bool m_foldoutDistribution = true;
public override void OnInspectorGUI()
{
if (target == null)
{
return;
}
// public override void OnInspectorGUI()
// {
// if (target == null)
// {
// return;
// }
serializedObject.Update();
// serializedObject.Update();
if (VRMVersion.IsNewer(m_exporterVersion.stringValue))
{
EditorGUILayout.HelpBox("Check UniVRM new version. https://github.com/dwango/UniVRM/releases", MessageType.Warning);
}
// if (VRMVersion.IsNewer(m_exporterVersion.stringValue))
// {
// EditorGUILayout.HelpBox("Check UniVRM new version. https://github.com/dwango/UniVRM/releases", MessageType.Warning);
// }
// texture
EditorGUILayout.BeginHorizontal();
{
EditorGUILayout.BeginVertical();
GUI.enabled = false;
EditorGUILayout.PropertyField(m_exporterVersion);
GUI.enabled = true;
EditorGUILayout.PropertyField(m_thumbnail);
EditorGUILayout.EndVertical();
m_thumbnail.objectReferenceValue = TextureField("", (Texture2D)m_thumbnail.objectReferenceValue, 100);
}
EditorGUILayout.EndHorizontal();
// // texture
// EditorGUILayout.BeginHorizontal();
// {
// EditorGUILayout.BeginVertical();
// GUI.enabled = false;
// EditorGUILayout.PropertyField(m_exporterVersion);
// GUI.enabled = true;
// EditorGUILayout.PropertyField(m_thumbnail);
// EditorGUILayout.EndVertical();
// m_thumbnail.objectReferenceValue = TextureField("", (Texture2D)m_thumbnail.objectReferenceValue, 100);
// }
// EditorGUILayout.EndHorizontal();
m_foldoutInfo = EditorGUILayout.Foldout(m_foldoutInfo, "Information");
if (m_foldoutInfo)
{
m_title.OnGUI();
m_version.OnGUI();
m_author.OnGUI();
m_contact.OnGUI();
m_reference.OnGUI();
}
// EditorGUILayout.LabelField("License ", EditorStyles.boldLabel);
m_foldoutPermission = EditorGUILayout.Foldout(m_foldoutPermission, Msg(MessageKeys.PERSONATION));
if (m_foldoutPermission)
{
var backup = EditorGUIUtility.labelWidth;
RightFixedPropField(m_AllowedUser, Msg(MessageKeys.ALLOWED_USER));
RightFixedPropField(m_ViolentUssage, Msg(MessageKeys.VIOLENT_USAGE));
RightFixedPropField(m_SexualUssage, Msg(MessageKeys.SEXUAL_USAGE));
RightFixedPropField(m_CommercialUssage, Msg(MessageKeys.COMMERCIAL_USAGE));
EditorGUILayout.PropertyField(m_OtherPermissionUrl, new GUIContent("Other License Url"));
EditorGUIUtility.labelWidth = backup;
}
// m_foldoutInfo = EditorGUILayout.Foldout(m_foldoutInfo, "Information");
// if (m_foldoutInfo)
// {
// m_title.OnGUI();
// m_version.OnGUI();
// m_author.OnGUI();
// m_contact.OnGUI();
// m_reference.OnGUI();
// }
// // EditorGUILayout.LabelField("License ", EditorStyles.boldLabel);
// m_foldoutPermission = EditorGUILayout.Foldout(m_foldoutPermission, Msg(MessageKeys.PERSONATION));
// if (m_foldoutPermission)
// {
// var backup = EditorGUIUtility.labelWidth;
// RightFixedPropField(m_AllowedUser, Msg(MessageKeys.ALLOWED_USER));
// RightFixedPropField(m_ViolentUssage, Msg(MessageKeys.VIOLENT_USAGE));
// RightFixedPropField(m_SexualUssage, Msg(MessageKeys.SEXUAL_USAGE));
// RightFixedPropField(m_CommercialUssage, Msg(MessageKeys.COMMERCIAL_USAGE));
// EditorGUILayout.PropertyField(m_OtherPermissionUrl, new GUIContent("Other License Url"));
// EditorGUIUtility.labelWidth = backup;
// }
m_foldoutDistribution = EditorGUILayout.Foldout(m_foldoutDistribution, Msg(MessageKeys.REDISTRIBUTION_MODIFICATIONS));
if (m_foldoutDistribution)
{
// var licenseType = m_LicenseType;
// EditorGUILayout.PropertyField(licenseType);
// if ((LicenseType)licenseType.intValue == LicenseType.Other)
// {
// EditorGUILayout.PropertyField(m_OtherLicenseUrl);
// }
}
// m_foldoutDistribution = EditorGUILayout.Foldout(m_foldoutDistribution, Msg(MessageKeys.REDISTRIBUTION_MODIFICATIONS));
// if (m_foldoutDistribution)
// {
// // var licenseType = m_LicenseType;
// // EditorGUILayout.PropertyField(licenseType);
// // if ((LicenseType)licenseType.intValue == LicenseType.Other)
// // {
// // EditorGUILayout.PropertyField(m_OtherLicenseUrl);
// // }
// }
serializedObject.ApplyModifiedProperties();
}
// serializedObject.ApplyModifiedProperties();
// }
static (Rect, Rect) FixedRight(Rect r, int width)
{
if (width > r.width)
{
width = (int)r.width;
}
return (
new Rect(r.x, r.y, r.width - width, r.height),
new Rect(r.x + r.width - width, r.y, width, r.height)
);
}
// static (Rect, Rect) FixedRight(Rect r, int width)
// {
// if (width > r.width)
// {
// width = (int)r.width;
// }
// return (
// new Rect(r.x, r.y, r.width - width, r.height),
// new Rect(r.x + r.width - width, r.y, width, r.height)
// );
// }
static void RightFixedPropField(SerializedProperty prop, string label)
{
var r = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.Height(EditorGUIUtility.singleLineHeight));
var (left, right) = FixedRight(r, 64);
// Debug.Log($"{left}, {right}");
EditorGUI.LabelField(left, label);
EditorGUI.PropertyField(right, prop, new GUIContent(""), false);
}
// static void RightFixedPropField(SerializedProperty prop, string label)
// {
// var r = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.Height(EditorGUIUtility.singleLineHeight));
// var (left, right) = FixedRight(r, 64);
// // Debug.Log($"{left}, {right}");
// EditorGUI.LabelField(left, label);
// EditorGUI.PropertyField(right, prop, new GUIContent(""), false);
// }
private static Texture2D TextureField(string name, Texture2D texture, int size)
{
GUILayout.BeginHorizontal();
var style = new GUIStyle(GUI.skin.label);
style.alignment = TextAnchor.UpperCenter;
//style.fixedWidth = size;
GUILayout.Label(name, style);
var result = (Texture2D)EditorGUILayout.ObjectField(texture, typeof(Texture2D), false, GUILayout.Width(size), GUILayout.Height(size));
GUILayout.EndVertical();
return result;
}
}
}
// private static Texture2D TextureField(string name, Texture2D texture, int size)
// {
// GUILayout.BeginHorizontal();
// var style = new GUIStyle(GUI.skin.label);
// style.alignment = TextAnchor.UpperCenter;
// //style.fixedWidth = size;
// GUILayout.Label(name, style);
// var result = (Texture2D)EditorGUILayout.ObjectField(texture, typeof(Texture2D), false, GUILayout.Width(size), GUILayout.Height(size));
// GUILayout.EndVertical();
// return result;
// }
// }
// }

View File

@@ -40,17 +40,17 @@ namespace UniVRM10
MeshExportValidator m_meshes;
Editor m_meshesInspector;
VRM10MetaObject m_meta;
VRM10MetaObject Meta
VRM10Object m_meta;
VRM10Object Vrm
{
get { return m_meta; }
set
{
if (value != null && AssetDatabase.IsSubAsset(value))
{
Debug.Log("copy VRM10MetaObject");
value.CopyTo(m_tmpMeta);
// SubAsset is readonly. copy
Debug.Log("copy VRM10ObjectMeta");
value.CopyTo(m_tmpObject);
return;
}
@@ -66,15 +66,16 @@ namespace UniVRM10
m_meta = value;
}
}
VRM10MetaObject m_tmpMeta;
VRM10Object m_tmpObject;
Editor m_metaEditor;
protected override void Initialize()
{
m_tmpMeta = ScriptableObject.CreateInstance<VRM10MetaObject>();
m_tmpMeta.Authors = new List<string> { "" };
m_tmpObject = ScriptableObject.CreateInstance<VRM10Object>();
m_tmpObject.name = "_vrm1_";
m_tmpObject.Meta.Authors = new List<string> { "" };
m_settings = ScriptableObject.CreateInstance<VRM10ExportSettings>();
m_settingsInspector = Editor.CreateEditor(m_settings);
@@ -87,18 +88,18 @@ namespace UniVRM10
// update meta
if (root == null)
{
Meta = null;
Vrm = null;
}
else
{
var controller = root.GetComponent<VRM10Controller>();
if (controller != null)
{
Meta = controller.Meta.Meta;
Vrm = controller.Vrm;
}
else
{
Meta = null;
Vrm = null;
}
// default setting
@@ -119,9 +120,9 @@ namespace UniVRM10
UnityEditor.Editor.DestroyImmediate(m_meshesInspector);
m_meshesInspector = null;
// Meta
Meta = null;
ScriptableObject.DestroyImmediate(m_tmpMeta);
m_tmpMeta = null;
Vrm = null;
ScriptableObject.DestroyImmediate(m_tmpObject);
m_tmpObject = null;
// m_settings
ScriptableObject.DestroyImmediate(m_settings);
m_settings = null;
@@ -161,8 +162,8 @@ namespace UniVRM10
// yield return proxy.Validate;
// }
var meta = Meta ? Meta : m_tmpMeta;
yield return meta.Validate;
var vrm = Vrm ? Vrm : m_tmpObject;
yield return vrm.Validate;
}
protected override void OnLayout()
@@ -229,7 +230,7 @@ namespace UniVRM10
return false;
}
if (m_tmpMeta == null)
if (m_tmpObject == null)
{
// disabled
return false;
@@ -244,11 +245,11 @@ namespace UniVRM10
{
if (m_meta != null)
{
m_metaEditor = Editor.CreateEditor(Meta);
m_metaEditor = Editor.CreateEditor(Vrm);
}
else
{
m_metaEditor = Editor.CreateEditor(m_tmpMeta);
m_metaEditor = Editor.CreateEditor(m_tmpObject);
}
}
m_metaEditor.OnInspectorGUI();
@@ -300,7 +301,7 @@ namespace UniVRM10
// export vrm-1.0
var exporter = new UniVRM10.Vrm10Exporter(new EditorTextureSerializer());
var option = new VrmLib.ExportArgs();
exporter.Export(root, model, converter, option, Meta ? Meta : m_tmpMeta);
exporter.Export(root, model, converter, option, Vrm ? Vrm : m_tmpObject);
var exportedBytes = exporter.Storage.ToBytes();

View File

@@ -11,13 +11,13 @@ namespace UniVRM10
{
private readonly ExpressionKey[] _keys;
private readonly Dictionary<ExpressionKey, VRM10Expression> _expressions;
private DefaultExpressionValidator(VRM10ExpressionAvatar expressionAvatar)
private DefaultExpressionValidator(VRM10ObjectExpression expressionAvatar)
{
_keys = expressionAvatar.Clips.Select(ExpressionKey.CreateFromClip).ToArray();
_expressions = expressionAvatar.Clips.ToDictionary(ExpressionKey.CreateFromClip, x => x);
}
public void Validate(IReadOnlyDictionary<ExpressionKey, float> inputWeights, IDictionary<ExpressionKey, float> actualWeights,
LookAtEyeDirection inputEyeDirection, out LookAtEyeDirection actualEyeDirection,
out float blinkOverrideRate, out float lookAtOverrideRate, out float mouthOverrideRate)
@@ -26,7 +26,7 @@ namespace UniVRM10
blinkOverrideRate = 0f;
lookAtOverrideRate = 0f;
mouthOverrideRate = 0f;
// 1. Set weights and Accumulate override rates.
foreach (var key in _keys)
{
@@ -36,10 +36,10 @@ namespace UniVRM10
// Get weight with evaluation binary flag.
var weight = expression.IsBinary ? Mathf.Round(inputWeights[key]) : inputWeights[key];
// Set weight.
actualWeights[key] = weight;
// Override rate without targeting myself.
if (!key.IsBlink)
{
@@ -54,7 +54,7 @@ namespace UniVRM10
mouthOverrideRate += GetOverrideRate(expression.OverrideMouth, weight);
}
}
// 2. Saturate rate.
blinkOverrideRate = Mathf.Clamp01(blinkOverrideRate);
lookAtOverrideRate = Mathf.Clamp01(lookAtOverrideRate);
@@ -63,7 +63,7 @@ namespace UniVRM10
var blinkMultiplier = 1f - blinkOverrideRate;
var lookAtMultiplier = 1f - lookAtOverrideRate;
var mouthMultiplier = 1f - mouthOverrideRate;
// 3. Set procedural key's weights.
foreach (var key in _keys)
{
@@ -80,7 +80,7 @@ namespace UniVRM10
actualWeights[key] = inputWeights[key] * mouthMultiplier;
}
}
// 4. eye direction
actualEyeDirection = LookAtEyeDirection.Multiply(inputEyeDirection, 1f - lookAtOverrideRate);
}
@@ -102,7 +102,7 @@ namespace UniVRM10
public sealed class Factory : IExpressionValidatorFactory
{
public IExpressionValidator Create(VRM10ExpressionAvatar expressionAvatar)
public IExpressionValidator Create(VRM10ObjectExpression expressionAvatar)
{
return new DefaultExpressionValidator(expressionAvatar);
}

View File

@@ -2,6 +2,6 @@
{
public interface IExpressionValidatorFactory
{
IExpressionValidator Create(VRM10ExpressionAvatar expressionAvatar);
IExpressionValidator Create(VRM10ObjectExpression expressionAvatar);
}
}

View File

@@ -1,127 +0,0 @@
using UnityEngine;
using System.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using UniGLTF;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniVRM10
{
public sealed class VRM10ExpressionAvatar : MonoBehaviour
{
[SerializeField]
public List<VRM10Expression> Clips = new List<VRM10Expression>();
/// <summary>
/// NullのClipを削除して詰める
/// </summary>
public void RemoveNullClip()
{
if (Clips == null)
{
return;
}
for (int i = Clips.Count - 1; i >= 0; --i)
{
if (Clips[i] == null)
{
Clips.RemoveAt(i);
}
}
}
#if UNITY_EDITOR
[ContextMenu("Restore")]
void Restore()
{
var assetPath = UnityPath.FromAsset(this);
if (assetPath.IsNull)
{
return;
}
foreach (var x in assetPath.Parent.ChildFiles)
{
var clip = UnityEditor.AssetDatabase.LoadAssetAtPath<VRM10Expression>(x.Value);
if (clip == null) continue;
if (!Clips.Contains(clip))
{
Clips.Add(clip);
}
Debug.LogFormat("{0}", clip.name);
}
Clips = Clips.OrderBy(x => ExpressionKey.CreateFromClip(x)).ToList();
}
static public VRM10Expression CreateExpression(string path)
{
//Debug.LogFormat("{0}", path);
var clip = ScriptableObject.CreateInstance<VRM10Expression>();
clip.ExpressionName = Path.GetFileNameWithoutExtension(path);
AssetDatabase.CreateAsset(clip, path);
AssetDatabase.ImportAsset(path);
return clip;
//Clips.Add(clip);
//EditorUtility.SetDirty(this);
//AssetDatabase.SaveAssets();
}
#endif
/// <summary>
/// Unknown以外で存在しないものを全て作る
/// </summary>
public void CreateDefaultPreset()
{
foreach (var preset in ((UniGLTF.Extensions.VRMC_vrm.ExpressionPreset[])Enum.GetValues(typeof(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset)))
.Where(x => x != UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
)
{
CreateDefaultPreset(preset);
}
}
void CreateDefaultPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset preset)
{
var clip = GetClip(new ExpressionKey(preset));
if (clip != null) return;
clip = ScriptableObject.CreateInstance<VRM10Expression>();
clip.name = preset.ToString();
clip.ExpressionName = preset.ToString();
clip.Preset = preset;
Clips.Add(clip);
}
public void SetClip(ExpressionKey key, VRM10Expression clip)
{
int index = -1;
try
{
index = Clips.FindIndex(x => key.Match(x));
}
catch (Exception)
{
}
if (index == -1)
{
Clips.Add(clip);
}
else
{
Clips[index] = clip;
}
}
public VRM10Expression GetClip(ExpressionKey key)
{
if (Clips == null) return null;
return Clips.FirstOrDefault(x => key.Match(x));
}
}
}

View File

@@ -15,62 +15,28 @@ namespace UniVRM10
[DisallowMultipleComponent]
public class VRM10Controller : MonoBehaviour
{
[Serializable]
public class VRM10ControllerImpl
public enum UpdateTypes
{
public enum UpdateTypes
{
None,
Update,
LateUpdate,
}
[SerializeField, Header("UpdateSetting")]
public UpdateTypes UpdateType = UpdateTypes.LateUpdate;
[SerializeField, Header("SpringBone")]
public Transform SpringBoneCenter;
None,
Update,
LateUpdate,
}
[SerializeField]
public VRM10ControllerImpl Controller = new VRM10ControllerImpl();
[SerializeField, Header("Runtime")]
public UpdateTypes UpdateType = UpdateTypes.LateUpdate;
[SerializeField]
public VRM10ControllerMeta Meta = new VRM10ControllerMeta();
public Transform SpringBoneCenter;
[SerializeField]
public VRM10ControllerExpression Expression = new VRM10ControllerExpression();
[SerializeField]
public VRM10ControllerLookAt LookAt = new VRM10ControllerLookAt();
[SerializeField]
public VRM10ControllerFirstPerson FirstPerson = new VRM10ControllerFirstPerson();
[SerializeField]
public VRM10ControllerSpringBone SpringBone = new VRM10ControllerSpringBone();
void OnDestroy()
{
if (Expression != null)
{
Expression.Restore();
}
}
private void OnValidate()
{
if (LookAt != null)
{
LookAt.HorizontalInner.OnValidate();
LookAt.HorizontalOuter.OnValidate();
LookAt.VerticalUp.OnValidate();
LookAt.VerticalDown.OnValidate();
}
}
[SerializeField, Header("VRM1")]
public VRM10Object Vrm;
VRM10ControllerRuntime m_runtime;
/// <summary>
/// delay new VRM10ControllerRuntime
/// </summary>
/// <returns></returns>
VRM10ControllerRuntime GetOrCreate()
{
if (m_runtime == null)
@@ -82,7 +48,7 @@ namespace UniVRM10
private void Update()
{
if (Controller.UpdateType == VRM10ControllerImpl.UpdateTypes.Update)
if (UpdateType == UpdateTypes.Update)
{
GetOrCreate().Process();
}
@@ -90,7 +56,7 @@ namespace UniVRM10
private void LateUpdate()
{
if (Controller.UpdateType == VRM10ControllerImpl.UpdateTypes.LateUpdate)
if (UpdateType == UpdateTypes.LateUpdate)
{
GetOrCreate().Process();
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 49cc95eade43a804fa7a5b8bfd6875d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 3139d59f7bb86b24c933ece483addae3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,12 +0,0 @@
using System;
using UnityEngine;
namespace UniVRM10
{
[Serializable]
public sealed class VRM10ControllerMeta
{
[SerializeField]
public VRM10MetaObject Meta;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 77efcd2e8b041404fafc8909d38daaef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -21,8 +21,8 @@ namespace UniVRM10
throw new Exception();
}
m_head = animator.GetBoneTransform(HumanBodyBones.Head);
target.LookAt.Setup(animator, m_head);
target.Expression.Setup(target, target.LookAt, target.LookAt.EyeDirectionApplicable);
target.Vrm.LookAt.Setup(animator, m_head);
target.Vrm.Expression.Setup(target, target.Vrm.LookAt, target.Vrm.LookAt.EyeDirectionApplicable);
if (m_constraints == null)
{
@@ -52,17 +52,17 @@ namespace UniVRM10
//
// spring
//
m_target.SpringBone.Process(m_target.Controller.SpringBoneCenter);
m_target.Vrm.SpringBone.Process(m_target.SpringBoneCenter);
//
// gaze control
//
m_target.LookAt.Process();
m_target.Vrm.LookAt.Process();
//
// expression
//
m_target.Expression.Process();
m_target.Vrm.Expression.Process();
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9134e2692fe37db46b99691e26390bd9
guid: 8c3df50f202d51e43a56b80a698a3870
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cec6491afc9329e418272980aed747f0
guid: 9ad6ed008a4d416468f3eb04b83b1bb0
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 99c0f25b461a78e4099b81021d029663
guid: c7800be16a75f1542aa302a471b19524
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using VRMShaders;
namespace UniVRM10
{
/// <summary>
/// VRM関連の情報を集約したオブジェクト。
///
/// ScriptedImporter から Extract して Edit 可能な項目なるべく増やすべく導入。
///
/// * Meta(VRM必須)
/// * Humanoid(VRM必須)
/// * Expressions(enum + custom list)
/// * LookAt
/// * FirstPerson
/// * SpringBone の MonoBehaviour でない部分
/// * ColliderGroup
/// * Springs
///
/// Serialize 可能な形で保持し、Editor経由で Edit可能にするのが目的。
///
/// </summary>
public class VRM10Object : ScriptableObject
{
public static SubAssetKey SubAssetKey => new SubAssetKey(typeof(VRM10Object), "_vrm1_");
[SerializeField]
public VRM10ObjectMeta Meta = new VRM10ObjectMeta();
[SerializeField]
public VRM10ObjectExpression Expression = new VRM10ObjectExpression();
[SerializeField]
public VRM10ControllerLookAt LookAt = new VRM10ControllerLookAt();
[SerializeField]
public VRM10ObjectFirstPerson FirstPerson = new VRM10ObjectFirstPerson();
[SerializeField]
public VRM10ControllerSpringBone SpringBone = new VRM10ControllerSpringBone();
void OnValidate()
{
Debug.Log($"VRM10Object.OnValidate");
if (LookAt != null)
{
LookAt.HorizontalInner.OnValidate();
LookAt.HorizontalOuter.OnValidate();
LookAt.VerticalUp.OnValidate();
LookAt.VerticalDown.OnValidate();
}
}
public void CopyTo(VRM10Object dst)
{
throw new NotImplementedException();
}
public IEnumerable<Validation> Validate(GameObject ExportRoot)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 821786654431c304187c2c85ebea264f
guid: 88684271e27adb843b6570957c9e7637
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -7,23 +7,81 @@ using VrmLib;
namespace UniVRM10
{
[Serializable]
public sealed class VRM10ControllerExpression
public sealed class VRM10ObjectExpression
{
public static IExpressionValidatorFactory ExpressionValidatorFactory = new DefaultExpressionValidator.Factory();
VRM10ExpressionAvatar m_expressionAvatar;
public IEnumerable<VRM10Expression> Clips
[SerializeField]
public List<VRM10Expression> Clips = new List<VRM10Expression>();
/// <summary>
/// NullのClipを削除して詰める
/// </summary>
public void RemoveNullClip()
{
get
if (Clips == null)
{
if (m_expressionAvatar == null || m_expressionAvatar.Clips == null)
return;
}
for (int i = Clips.Count - 1; i >= 0; --i)
{
if (Clips[i] == null)
{
return Enumerable.Empty<VRM10Expression>();
Clips.RemoveAt(i);
}
return m_expressionAvatar.Clips;
}
}
/// <summary>
/// Unknown以外で存在しないものを全て作る
/// </summary>
public void CreateDefaultPreset()
{
foreach (var preset in ((UniGLTF.Extensions.VRMC_vrm.ExpressionPreset[])Enum.GetValues(typeof(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset)))
.Where(x => x != UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
)
{
CreateDefaultPreset(preset);
}
}
void CreateDefaultPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset preset)
{
var clip = GetClip(new ExpressionKey(preset));
if (clip != null) return;
clip = ScriptableObject.CreateInstance<VRM10Expression>();
clip.name = preset.ToString();
clip.ExpressionName = preset.ToString();
clip.Preset = preset;
Clips.Add(clip);
}
public void SetClip(ExpressionKey key, VRM10Expression clip)
{
int index = -1;
try
{
index = Clips.FindIndex(x => key.Match(x));
}
catch (Exception)
{
}
if (index == -1)
{
Clips.Add(clip);
}
else
{
Clips[index] = clip;
}
}
public VRM10Expression GetClip(ExpressionKey key)
{
if (Clips == null) return null;
return Clips.FirstOrDefault(x => key.Match(x));
}
public static IExpressionValidatorFactory ExpressionValidatorFactory = new DefaultExpressionValidator.Factory();
private List<ExpressionKey> _keys = new List<ExpressionKey>();
private Dictionary<ExpressionKey, float> _inputWeights = new Dictionary<ExpressionKey, float>();
private Dictionary<ExpressionKey, float> _actualWeights = new Dictionary<ExpressionKey, float>();
@@ -45,16 +103,10 @@ namespace UniVRM10
internal void Setup(VRM10Controller target, ILookAtEyeDirectionProvider eyeDirectionProvider, ILookAtEyeDirectionApplicable eyeDirectionApplicable)
{
m_expressionAvatar = target.GetComponent<VRM10ExpressionAvatar>();
if (m_expressionAvatar == null)
{
throw new ArgumentNullException();
}
Restore();
_merger = new ExpressionMerger(m_expressionAvatar.Clips, target.transform);
_keys = m_expressionAvatar.Clips.Select(ExpressionKey.CreateFromClip).ToList();
_merger = new ExpressionMerger(Clips, target.transform);
_keys = Clips.Select(ExpressionKey.CreateFromClip).ToList();
var oldInputWeights = _inputWeights;
_inputWeights = _keys.ToDictionary(x => x, x => 0f);
foreach (var key in _keys)
@@ -63,7 +115,7 @@ namespace UniVRM10
if (oldInputWeights.ContainsKey(key)) _inputWeights[key] = oldInputWeights[key];
}
_actualWeights = _keys.ToDictionary(x => x, x => 0f);
_validator = ExpressionValidatorFactory.Create(m_expressionAvatar);
_validator = ExpressionValidatorFactory.Create(this);
_eyeDirectionProvider = eyeDirectionProvider;
_eyeDirectionApplicable = eyeDirectionApplicable;
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 848b62e18138b724dbaec592fbf31a1c
guid: dcf99f5cc866e6b42b05c6f6a7ea630c
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -7,7 +7,7 @@ using UnityEngine;
namespace UniVRM10
{
[Serializable]
public class VRM10ControllerFirstPerson
public class VRM10ObjectFirstPerson
{
[SerializeField]
public List<RendererFirstPersonFlags> Renderers = new List<RendererFirstPersonFlags>();
@@ -15,7 +15,7 @@ namespace UniVRM10
public void CopyTo(GameObject _dst, Dictionary<Transform, Transform> map)
{
var dst = _dst.GetOrAddComponent<VRM10Controller>();
dst.FirstPerson.Renderers = Renderers.Select(x =>
dst.Vrm.FirstPerson.Renderers = Renderers.Select(x =>
{
var renderer = map[x.Renderer.transform].GetComponent<Renderer>();
return new RendererFirstPersonFlags

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1aa2c8486d14a1f4cbe81ff2fb5d0438
guid: a54f419e664839f43a56ffffcbdf72db
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,17 +1,15 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using UniGLTF;
using UnityEngine;
using VRMShaders;
namespace UniVRM10
{
[CreateAssetMenu(menuName = "VRM10/MetaObject")]
public class VRM10MetaObject : ScriptableObject
[Serializable]
public class VRM10ObjectMeta
{
public static SubAssetKey SubAssetKey => new SubAssetKey(typeof(VRM10MetaObject), "Meta");
[SerializeField]
public string ExporterVersion;
@@ -93,7 +91,7 @@ namespace UniVRM10
}
}
public void CopyTo(VRM10MetaObject dst)
public void CopyTo(VRM10ObjectMeta dst)
{
dst.ExporterVersion = ExporterVersion;
dst.Name = Name;

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1327f6acc7d07744ab3908816a800a6e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -134,7 +134,7 @@ namespace UniVRM10
return new float[] { -v.x, v.y, v.z };
}
public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, VRM10MetaObject metaObject = null)
public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, VRM10Object vrmObject = null)
{
ExportAsset(model);
@@ -182,7 +182,7 @@ namespace UniVRM10
// node
ExportNodes(model.Root, model.Nodes, model.MeshGroups, option);
var (vrm, vrmSpringBone, thumbnailTextureIndex) = ExportVrm(root, model, converter, metaObject);
var (vrm, vrmSpringBone, thumbnailTextureIndex) = ExportVrm(root, model, converter, vrmObject);
// Extension で Texture が増える場合があるので最後に呼ぶ
for (int i = 0; i < m_textureExporter.Exported.Count; ++i)
@@ -213,21 +213,21 @@ namespace UniVRM10
/// <param name="root"></param>
/// <param name="model"></param>
/// <param name="converter"></param>
/// <param name="meta"></param>
/// <param name="vrmObject"></param>
/// <returns></returns>
(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm,
UniGLTF.Extensions.VRMC_springBone.VRMC_springBone springBone,
int? thumbnailIndex) ExportVrm(GameObject root, Model model, ModelExporter converter, VRM10MetaObject meta)
int? thumbnailIndex) ExportVrm(GameObject root, Model model, ModelExporter converter, VRM10Object vrmObject)
{
var vrmController = root?.GetComponent<VRM10Controller>();
if (meta == null)
if (vrmObject == null)
{
if (vrmController == null || vrmController.Meta == null)
if (vrmController?.Vrm?.Meta == null)
{
throw new NullReferenceException("metaObject is null");
}
meta = vrmController.Meta.Meta;
vrmObject = vrmController.Vrm;
}
var vrm = new UniGLTF.Extensions.VRMC_vrm.VRMC_vrm
@@ -251,7 +251,7 @@ namespace UniVRM10
// required
//
ExportHumanoid(vrm, model);
var thumbnailTextureIndex = ExportMeta(vrm, meta);
var thumbnailTextureIndex = ExportMeta(vrm, vrmObject.Meta);
//
// optional
@@ -340,7 +340,7 @@ namespace UniVRM10
}
// colliderGroups
foreach (var x in controller.SpringBone.ColliderGroups)
foreach (var x in controller.Vrm.SpringBone.ColliderGroups)
{
springBone.ColliderGroups.Add(new UniGLTF.Extensions.VRMC_springBone.ColliderGroup
{
@@ -349,13 +349,13 @@ namespace UniVRM10
}
// springs
foreach (var x in controller.SpringBone.Springs)
foreach (var x in controller.Vrm.SpringBone.Springs)
{
var spring = new UniGLTF.Extensions.VRMC_springBone.Spring
{
Name = x.Name,
Joints = x.Joints.Select(y => ExportJoint(y, getNodeIndexFromTransform)).ToList(),
ColliderGroups = x.ColliderGroups.Select(y => controller.SpringBone.ColliderGroups.IndexOf(y)).ToArray(),
ColliderGroups = x.ColliderGroups.Select(y => controller.Vrm.SpringBone.ColliderGroups.IndexOf(y)).ToArray(),
};
springBone.Springs.Add(spring);
}
@@ -469,7 +469,7 @@ namespace UniVRM10
void ExportFirstPerson(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10Controller vrmController, Model model, ModelExporter converter)
{
if (vrmController?.FirstPerson == null)
if (!(vrmController?.Vrm?.FirstPerson is VRM10ObjectFirstPerson firstPerson))
{
return;
}
@@ -483,7 +483,7 @@ namespace UniVRM10
var node = converter.Nodes[r.gameObject];
return model.Nodes.IndexOf(node);
};
foreach (var f in vrmController.FirstPerson.Renderers)
foreach (var f in firstPerson.Renderers)
{
vrm.FirstPerson.MeshAnnotations.Add(ExportMeshAnnotation(f, getIndex));
}
@@ -500,23 +500,23 @@ namespace UniVRM10
void ExportLookAt(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10Controller vrmController)
{
if (vrmController?.LookAt == null)
if (!(vrmController?.Vrm?.LookAt is VRM10ControllerLookAt lookAt))
{
return;
}
vrm.LookAt = new UniGLTF.Extensions.VRMC_vrm.LookAt
{
Type = vrmController.LookAt.LookAtType,
Type = lookAt.LookAtType,
OffsetFromHeadBone = new float[]{
vrmController.LookAt.OffsetFromHead.x ,
vrmController.LookAt.OffsetFromHead.y ,
vrmController.LookAt.OffsetFromHead.z ,
lookAt.OffsetFromHead.x ,
lookAt.OffsetFromHead.y ,
lookAt.OffsetFromHead.z ,
},
RangeMapHorizontalInner = ExportLookAtRangeMap(vrmController.LookAt.HorizontalInner),
RangeMapHorizontalOuter = ExportLookAtRangeMap(vrmController.LookAt.HorizontalOuter),
RangeMapVerticalDown = ExportLookAtRangeMap(vrmController.LookAt.VerticalDown),
RangeMapVerticalUp = ExportLookAtRangeMap(vrmController.LookAt.VerticalUp),
RangeMapHorizontalInner = ExportLookAtRangeMap(lookAt.HorizontalInner),
RangeMapHorizontalOuter = ExportLookAtRangeMap(lookAt.HorizontalOuter),
RangeMapVerticalDown = ExportLookAtRangeMap(lookAt.VerticalDown),
RangeMapVerticalUp = ExportLookAtRangeMap(lookAt.VerticalUp),
};
}
@@ -552,8 +552,7 @@ namespace UniVRM10
void ExportExpression(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10Controller vrmController, Model model, ModelExporter converter)
{
var expressionAvatar = vrmController.GetComponent<VRM10ExpressionAvatar>();
if (expressionAvatar?.Clips == null)
if (vrmController?.Vrm?.Expression?.Clips == null)
{
return;
}
@@ -578,7 +577,7 @@ namespace UniVRM10
};
vrm.Expressions = new List<UniGLTF.Extensions.VRMC_vrm.Expression>();
foreach (var e in expressionAvatar.Clips)
foreach (var e in vrmController.Vrm.Expression.Clips)
{
var vrmExpression = new UniGLTF.Extensions.VRMC_vrm.Expression
{
@@ -629,7 +628,7 @@ namespace UniVRM10
}
}
int? ExportMeta(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10MetaObject meta)
int? ExportMeta(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10ObjectMeta meta)
{
vrm.Meta.Name = meta.Name;
vrm.Meta.Version = meta.Version;

View File

@@ -214,7 +214,7 @@ namespace UniVRM10
}
UnityEngine.Avatar m_humanoid;
VRM10MetaObject m_meta;
VRM10Object m_vrmObject;
List<VRM10Expression> m_expressions = new List<VRM10Expression>();
protected override async Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
@@ -233,7 +233,8 @@ namespace UniVRM10
var controller = Root.AddComponent<VRM10Controller>();
// vrm
await LoadVrmAsync(awaitCaller, controller, m_vrm);
m_vrmObject = controller.Vrm = await LoadVrmAsync(awaitCaller, m_vrm);
// springBone
if (UniGLTF.Extensions.VRMC_springBone.GltfDeserializer.TryGet(Parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_springBone.VRMC_springBone springBone))
{
@@ -255,58 +256,61 @@ namespace UniVRM10
}
}
async Task LoadVrmAsync(IAwaitCaller awaitCaller, VRM10Controller controller, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)
async Task<VRM10Object> LoadVrmAsync(IAwaitCaller awaitCaller, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrmExtension)
{
// meta
if (m_externalMap.TryGetValue(VRM10MetaObject.SubAssetKey, out UnityEngine.Object meta))
if (m_externalMap.TryGetValue(VRM10Object.SubAssetKey, out UnityEngine.Object obj) && obj is VRM10Object vrm)
{
controller.Meta.Meta = meta as VRM10MetaObject;
// use external object map
return vrm;
}
else if (vrm.Meta != null)
// create new object
vrm = ScriptableObject.CreateInstance<VRM10Object>();
vrm.name = VRM10Object.SubAssetKey.Name;
// meta
if (vrmExtension.Meta != null)
{
var src = vrm.Meta;
m_meta = ScriptableObject.CreateInstance<VRM10MetaObject>();
m_meta.name = VRM10MetaObject.SubAssetKey.Name;
controller.Meta.Meta = m_meta;
m_meta.Name = src.Name;
m_meta.Version = src.Version;
m_meta.ContactInformation = src.ContactInformation;
var src = vrmExtension.Meta;
var meta = new VRM10ObjectMeta();
vrm.Meta = meta;
meta.Name = src.Name;
meta.Version = src.Version;
meta.ContactInformation = src.ContactInformation;
// avatar
m_meta.AllowedUser = src.AvatarPermission;
m_meta.ViolentUsage = src.AllowExcessivelyViolentUsage.Value;
m_meta.SexualUsage = src.AllowExcessivelySexualUsage.Value;
m_meta.CommercialUsage = src.CommercialUsage;
m_meta.PoliticalOrReligiousUsage = src.AllowPoliticalOrReligiousUsage.Value;
meta.AllowedUser = src.AvatarPermission;
meta.ViolentUsage = src.AllowExcessivelyViolentUsage.Value;
meta.SexualUsage = src.AllowExcessivelySexualUsage.Value;
meta.CommercialUsage = src.CommercialUsage;
meta.PoliticalOrReligiousUsage = src.AllowPoliticalOrReligiousUsage.Value;
// redistribution
m_meta.CreditNotation = src.CreditNotation;
m_meta.Redistribution = src.AllowRedistribution.Value;
m_meta.ModificationLicense = src.Modification;
m_meta.OtherLicenseUrl = src.OtherLicenseUrl;
meta.CreditNotation = src.CreditNotation;
meta.Redistribution = src.AllowRedistribution.Value;
meta.ModificationLicense = src.Modification;
meta.OtherLicenseUrl = src.OtherLicenseUrl;
//
if (src.References != null)
{
m_meta.References.AddRange(src.References);
meta.References.AddRange(src.References);
}
if (src.Authors != null)
{
m_meta.Authors.AddRange(src.Authors);
meta.Authors.AddRange(src.Authors);
}
if (Vrm10TextureDescriptorGenerator.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureDescriptor Param) kv))
if (Vrm10TextureDescriptorGenerator.TryGetMetaThumbnailTextureImportParam(Parser, vrmExtension, out (SubAssetKey, VRMShaders.TextureDescriptor Param) kv))
{
var texture = await TextureFactory.GetTextureAsync(kv.Param);
if (texture is Texture2D tex2D)
{
m_meta.Thumbnail = tex2D;
meta.Thumbnail = tex2D;
}
}
}
// expression
if (vrm.Expressions != null)
if (vrmExtension.Expressions != null)
{
var expressionAvatar = Root.AddComponent<VRM10ExpressionAvatar>();
foreach (var expression in vrm.Expressions)
foreach (var expression in vrmExtension.Expressions)
{
VRM10Expression clip = default;
if (m_externalMap.TryGetValue(Key(expression).SubAssetKey, out UnityEngine.Object expressionObj))
@@ -337,48 +341,50 @@ namespace UniVRM10
m_expressions.Add(clip);
}
expressionAvatar.Clips.Add(clip);
vrm.Expression.Clips.Add(clip);
}
}
// lookat
if (vrm.LookAt != null)
if (vrmExtension.LookAt != null)
{
var src = vrm.LookAt;
controller.LookAt.LookAtType = src.Type;
controller.LookAt.OffsetFromHead = new Vector3(src.OffsetFromHeadBone[0], src.OffsetFromHeadBone[1], src.OffsetFromHeadBone[2]);
var src = vrmExtension.LookAt;
vrm.LookAt.LookAtType = src.Type;
vrm.LookAt.OffsetFromHead = new Vector3(src.OffsetFromHeadBone[0], src.OffsetFromHeadBone[1], src.OffsetFromHeadBone[2]);
if (src.RangeMapHorizontalInner != null)
{
controller.LookAt.HorizontalInner = new CurveMapper(src.RangeMapHorizontalInner.InputMaxValue.Value, src.RangeMapHorizontalInner.OutputScale.Value);
vrm.LookAt.HorizontalInner = new CurveMapper(src.RangeMapHorizontalInner.InputMaxValue.Value, src.RangeMapHorizontalInner.OutputScale.Value);
}
if (src.RangeMapHorizontalOuter != null)
{
controller.LookAt.HorizontalOuter = new CurveMapper(src.RangeMapHorizontalOuter.InputMaxValue.Value, src.RangeMapHorizontalOuter.OutputScale.Value);
vrm.LookAt.HorizontalOuter = new CurveMapper(src.RangeMapHorizontalOuter.InputMaxValue.Value, src.RangeMapHorizontalOuter.OutputScale.Value);
}
if (src.RangeMapVerticalUp != null)
{
controller.LookAt.VerticalUp = new CurveMapper(src.RangeMapVerticalUp.InputMaxValue.Value, src.RangeMapVerticalUp.OutputScale.Value);
vrm.LookAt.VerticalUp = new CurveMapper(src.RangeMapVerticalUp.InputMaxValue.Value, src.RangeMapVerticalUp.OutputScale.Value);
}
if (src.RangeMapVerticalDown != null)
{
controller.LookAt.VerticalDown = new CurveMapper(src.RangeMapVerticalDown.InputMaxValue.Value, src.RangeMapVerticalDown.OutputScale.Value);
vrm.LookAt.VerticalDown = new CurveMapper(src.RangeMapVerticalDown.InputMaxValue.Value, src.RangeMapVerticalDown.OutputScale.Value);
}
}
// firstPerson
if (vrm.FirstPerson != null && vrm.FirstPerson.MeshAnnotations != null)
if (vrmExtension.FirstPerson != null && vrmExtension.FirstPerson.MeshAnnotations != null)
{
var fp = vrm.FirstPerson;
var fp = vrmExtension.FirstPerson;
foreach (var x in fp.MeshAnnotations)
{
var node = Nodes[x.Node.Value];
controller.FirstPerson.Renderers.Add(new RendererFirstPersonFlags
vrm.FirstPerson.Renderers.Add(new RendererFirstPersonFlags
{
FirstPersonFlag = x.Type,
Renderer = node.GetComponent<Renderer>()
});
}
}
return vrm;
}
async Task LoadSpringBoneAsync(IAwaitCaller awaitCaller, VRM10Controller controller, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone gltfVrmSpringBone)
@@ -425,7 +431,7 @@ namespace UniVRM10
foreach (var g in gltfVrmSpringBone.ColliderGroups)
{
var colliderGroup = secondary.gameObject.AddComponent<VRM10SpringBoneColliderGroup>();
controller.SpringBone.ColliderGroups.Add(colliderGroup);
controller.Vrm.SpringBone.ColliderGroups.Add(colliderGroup);
foreach (var c in g.Colliders)
{
@@ -447,11 +453,11 @@ namespace UniVRM10
continue;
}
var spring = new VRM10ControllerSpringBone.Spring(gltfSpring.Name);
controller.SpringBone.Springs.Add(spring);
controller.Vrm.SpringBone.Springs.Add(spring);
if (gltfSpring.ColliderGroups != null)
{
spring.ColliderGroups = gltfSpring.ColliderGroups.Select(x => controller.SpringBone.ColliderGroups[x]).ToList();
spring.ColliderGroups = gltfSpring.ColliderGroups.Select(x => controller.Vrm.SpringBone.ColliderGroups[x]).ToList();
}
// joint
foreach (var gltfJoint in gltfSpring.Joints)
@@ -630,10 +636,10 @@ namespace UniVRM10
take(SubAssetKey.Create(m_humanoid), m_humanoid);
m_humanoid = null;
if (m_meta != null)
if (m_vrmObject != null)
{
take(VRM10MetaObject.SubAssetKey, m_meta);
m_meta = null;
take(VRM10Object.SubAssetKey, m_vrmObject);
m_vrmObject = null;
}
foreach (var x in m_expressions)
@@ -653,16 +659,20 @@ namespace UniVRM10
if (m_humanoid != null)
{
UnityObjectDestoyer.DestroyRuntimeOrEditor(m_humanoid);
m_humanoid = null;
}
if (m_meta != null)
if (m_vrmObject != null)
{
UnityObjectDestoyer.DestroyRuntimeOrEditor(m_meta);
UnityObjectDestoyer.DestroyRuntimeOrEditor(m_vrmObject);
m_vrmObject = null;
}
foreach (var clip in m_expressions)
{
UnityObjectDestoyer.DestroyRuntimeOrEditor(clip);
}
m_expressions.Clear();
base.Dispose();
}