mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-08 03:48:19 -05:00
VRM10SpringBoneManager.cs
This commit is contained in:
@@ -39,15 +39,15 @@ namespace UniVRM10
|
||||
EditorUtility.SetDirty(m_target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/X Mirror")]
|
||||
private static void InvertOffsetX(MenuCommand command)
|
||||
{
|
||||
var target = command.context as VRM10SpringBoneColliderGroup;
|
||||
if (target == null) return;
|
||||
|
||||
|
||||
Undo.RecordObject(target, "X Mirror");
|
||||
|
||||
|
||||
foreach (var sphereCollider in target.Colliders)
|
||||
{
|
||||
var offset = sphereCollider.Offset;
|
||||
@@ -55,27 +55,27 @@ namespace UniVRM10
|
||||
sphereCollider.Offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Radius")]
|
||||
private static void SortByRadius(MenuCommand command)
|
||||
{
|
||||
var target = command.context as VRM10SpringBoneColliderGroup;
|
||||
if (target == null) return;
|
||||
|
||||
|
||||
Undo.RecordObject(target, "Sort Colliders by Radius");
|
||||
|
||||
target.Colliders = target.Colliders.OrderBy(x => -x.Radius).ToArray();
|
||||
target.Colliders = target.Colliders.OrderBy(x => -x.Radius).ToList();
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Offset Y")]
|
||||
private static void SortByOffsetY(MenuCommand command)
|
||||
{
|
||||
var target = command.context as VRM10SpringBoneColliderGroup;
|
||||
if (target == null) return;
|
||||
|
||||
|
||||
Undo.RecordObject(target, "Sort Colliders by Offset Y");
|
||||
|
||||
target.Colliders = target.Colliders.OrderBy(x => -x.Offset.y).ToArray();
|
||||
target.Colliders = target.Colliders.OrderBy(x => -x.Offset.y).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
class VRM10SpringBoneTreeView : TreeView
|
||||
|
||||
{
|
||||
VRM10Controller m_root;
|
||||
|
||||
Dictionary<int, VRM10SpringBone> m_boneMap = new Dictionary<int, VRM10SpringBone>();
|
||||
|
||||
public bool TryGetSpringBone(int id, out VRM10SpringBone bone)
|
||||
{
|
||||
return m_boneMap.TryGetValue(id, out bone);
|
||||
}
|
||||
|
||||
public VRM10SpringBoneTreeView(TreeViewState treeViewState, VRM10Controller root)
|
||||
: base(treeViewState)
|
||||
{
|
||||
m_root = root;
|
||||
Reload();
|
||||
}
|
||||
|
||||
protected override bool CanMultiSelect(TreeViewItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
m_boneMap.Clear();
|
||||
var root = new TreeViewItem { id = 0, depth = -1, displayName = m_root.name };
|
||||
var allItems = new List<TreeViewItem>();
|
||||
var bones = m_root.GetComponentsInChildren<VRM10SpringBone>();
|
||||
var id = 1;
|
||||
for (int i = 0; i < bones.Length; ++i, ++id)
|
||||
{
|
||||
var bone = bones[i];
|
||||
|
||||
m_boneMap.Add(id, bone);
|
||||
|
||||
allItems.Add(new TreeViewItem
|
||||
{
|
||||
id = id,
|
||||
displayName = bone.name,
|
||||
});
|
||||
}
|
||||
// Utility method that initializes the TreeViewItem.children and -parent for all items.
|
||||
SetupParentsAndChildrenFromDepths(root, allItems);
|
||||
|
||||
// Return root of the tree
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public class VRM10SpringBoneWindow : EditorWindow
|
||||
{
|
||||
[MenuItem(VRMVersion.MENU + "/VRMSpringBoneWindow")]
|
||||
public static void ShowEditorWindow()
|
||||
{
|
||||
var wnd = GetWindow<VRM10SpringBoneWindow>();
|
||||
wnd.titleContent = new GUIContent("VRMSpringBoneWindow");
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
minSize = new Vector2(100, 100);
|
||||
maxSize = new Vector2(4000, 4000);
|
||||
Selection.selectionChanged += OnSelectionChanged;
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
Selection.selectionChanged -= OnSelectionChanged;
|
||||
}
|
||||
|
||||
VRM10Controller m_currentRoot;
|
||||
|
||||
[SerializeField]
|
||||
TreeViewState m_treeViewState;
|
||||
VRM10SpringBoneTreeView m_treeView;
|
||||
|
||||
Rect m_treeRect;
|
||||
Rect m_inspectorRect;
|
||||
Vector2 m_inspectorScrollPos;
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (m_treeView is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// bone selector
|
||||
Rect fullRect = GUILayoutUtility.GetRect(0, 100000, 0, 10000);
|
||||
var treeRect = new Rect(fullRect.x, fullRect.y, fullRect.width, EditorGUIUtility.singleLineHeight * 3);
|
||||
var inspectorRect = new Rect(fullRect.x, treeRect.y + treeRect.height, fullRect.width, fullRect.height - treeRect.height);
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
m_treeRect = treeRect;
|
||||
m_inspectorRect = inspectorRect;
|
||||
// Debug.Log($"{m_treeRect}, {m_inspectorRect}");
|
||||
}
|
||||
|
||||
m_treeView.OnGUI(m_treeRect);
|
||||
|
||||
GUILayout.BeginArea(m_inspectorRect);
|
||||
m_inspectorScrollPos = GUILayout.BeginScrollView(m_inspectorScrollPos, GUI.skin.box);
|
||||
if (m_treeViewState.selectedIDs.Any())
|
||||
{
|
||||
// selected な SpringBone の Inspector を描画する
|
||||
if (m_treeView.TryGetSpringBone(m_treeViewState.selectedIDs[0], out VRM10SpringBone bone))
|
||||
{
|
||||
// Debug.Log(bone);
|
||||
using (var inspector = new CustomInspector(new SerializedObject(bone)))
|
||||
{
|
||||
inspector.OnInspectorGUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
void OnSelectionChanged()
|
||||
{
|
||||
var go = Selection.activeObject as GameObject;
|
||||
if (go is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var meta = go.GetComponentInParent<VRM10Controller>();
|
||||
if (meta == m_currentRoot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentRoot = meta;
|
||||
if (m_currentRoot is null)
|
||||
{
|
||||
m_treeViewState = null;
|
||||
m_treeView = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// update treeview
|
||||
Debug.Log(m_currentRoot);
|
||||
m_treeViewState = new TreeViewState();
|
||||
m_treeView = new VRM10SpringBoneTreeView(m_treeViewState, m_currentRoot);
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b4a0f82403ba742b3ae1d7ee14bf05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -53,11 +53,12 @@ namespace UniVRM10
|
||||
{
|
||||
m_metaEditor = Editor.CreateEditor(m_target.Meta);
|
||||
}
|
||||
m_controller = serializedObject.FindProperty(nameof(m_target.Controller));
|
||||
m_expression = serializedObject.FindProperty(nameof(m_target.Expression));
|
||||
m_lookAt = serializedObject.FindProperty(nameof(m_target.LookAt));
|
||||
m_firstPerson = serializedObject.FindProperty(nameof(m_target.FirstPerson));
|
||||
m_asset = serializedObject.FindProperty(nameof(m_target.ModelAsset));
|
||||
m_controller = PropGui.FromObject(serializedObject, nameof(m_target.Controller));
|
||||
m_expression = PropGui.FromObject(serializedObject, nameof(m_target.Expression));
|
||||
m_lookAt = PropGui.FromObject(serializedObject, nameof(m_target.LookAt));
|
||||
m_firstPerson = PropGui.FromObject(serializedObject, nameof(m_target.FirstPerson));
|
||||
m_springBone = PropGui.FromObject(serializedObject, nameof(m_target.SpringBone));
|
||||
m_asset = PropGui.FromObject(serializedObject, nameof(m_target.ModelAsset));
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
@@ -76,16 +77,51 @@ namespace UniVRM10
|
||||
Expression,
|
||||
LookAt,
|
||||
FirstPerson,
|
||||
SpringBone,
|
||||
Assets,
|
||||
}
|
||||
Tabs _tab;
|
||||
|
||||
Editor m_metaEditor;
|
||||
SerializedProperty m_controller;
|
||||
SerializedProperty m_expression;
|
||||
SerializedProperty m_lookAt;
|
||||
SerializedProperty m_firstPerson;
|
||||
SerializedProperty m_asset;
|
||||
|
||||
class PropGui
|
||||
{
|
||||
SerializedProperty m_prop;
|
||||
|
||||
PropGui(SerializedProperty property)
|
||||
{
|
||||
m_prop = property;
|
||||
}
|
||||
|
||||
public static PropGui FromObject(SerializedObject serializedObject, string name)
|
||||
{
|
||||
var prop = serializedObject.FindProperty(name);
|
||||
return new PropGui(prop);
|
||||
}
|
||||
|
||||
public void RecursiveProperty()
|
||||
{
|
||||
var depth = m_prop.depth;
|
||||
var iterator = m_prop.Copy();
|
||||
for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false)
|
||||
{
|
||||
if (iterator.depth < depth)
|
||||
return;
|
||||
|
||||
depth = iterator.depth;
|
||||
|
||||
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropGui m_controller;
|
||||
PropGui m_expression;
|
||||
PropGui m_lookAt;
|
||||
PropGui m_firstPerson;
|
||||
PropGui m_springBone;
|
||||
PropGui m_asset;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
@@ -109,24 +145,28 @@ namespace UniVRM10
|
||||
break;
|
||||
|
||||
case Tabs.Controller:
|
||||
RecursiveProperty(m_controller);
|
||||
m_controller.RecursiveProperty();
|
||||
break;
|
||||
|
||||
case Tabs.Expression:
|
||||
ExpressionGUI();
|
||||
RecursiveProperty(m_expression);
|
||||
m_expression.RecursiveProperty();
|
||||
break;
|
||||
|
||||
case Tabs.LookAt:
|
||||
RecursiveProperty(m_lookAt);
|
||||
m_lookAt.RecursiveProperty();
|
||||
break;
|
||||
|
||||
case Tabs.FirstPerson:
|
||||
RecursiveProperty(m_firstPerson);
|
||||
m_firstPerson.RecursiveProperty();
|
||||
break;
|
||||
|
||||
case Tabs.SpringBone:
|
||||
m_springBone.RecursiveProperty();
|
||||
break;
|
||||
|
||||
case Tabs.Assets:
|
||||
RecursiveProperty(m_asset);
|
||||
m_asset.RecursiveProperty();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -164,22 +204,6 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
static void RecursiveProperty(SerializedProperty property)
|
||||
{
|
||||
var depth = property.depth;
|
||||
var iterator = property.Copy();
|
||||
for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false)
|
||||
{
|
||||
if (iterator.depth < depth)
|
||||
return;
|
||||
|
||||
depth = iterator.depth;
|
||||
|
||||
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnSceneGUI()
|
||||
{
|
||||
OnSceneGUIOffset();
|
||||
|
||||
@@ -8,11 +8,8 @@ namespace UniVRM10
|
||||
/// The base algorithm is http://rocketjump.skr.jp/unity3d/109/ of @ricopin416
|
||||
/// DefaultExecutionOrder(11000) means calculate springbone after FinalIK( VRIK )
|
||||
/// </summary>
|
||||
[AddComponentMenu("VRM10/VRM10SpringBone")]
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
[DefaultExecutionOrder(11000)]
|
||||
#endif
|
||||
public class VRM10SpringBone : MonoBehaviour
|
||||
[Serializable]
|
||||
public class VRM10SpringBone
|
||||
{
|
||||
[SerializeField]
|
||||
public string m_comment;
|
||||
@@ -49,7 +46,7 @@ namespace UniVRM10
|
||||
public List<VRM10SpringJoint> Joints = new List<VRM10SpringJoint>();
|
||||
|
||||
[SerializeField]
|
||||
public VRM10SpringBoneColliderGroup[] ColliderGroups;
|
||||
public List<VRM10SpringBoneColliderGroup> ColliderGroups = new List<VRM10SpringBoneColliderGroup>();
|
||||
|
||||
SpringBoneProcessor m_processor = new SpringBoneProcessor();
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
@@ -10,14 +11,18 @@ namespace UniVRM10
|
||||
[AddComponentMenu("VRM10/VRM10SpringBoneColliderGroup")]
|
||||
public class VRM10SpringBoneColliderGroup : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public VRM10SpringBoneCollider[] Colliders = new VRM10SpringBoneCollider[]{
|
||||
new VRM10SpringBoneCollider
|
||||
void Reset()
|
||||
{
|
||||
// default shape
|
||||
Colliders.Add(new VRM10SpringBoneCollider
|
||||
{
|
||||
ColliderType = VRM10SpringBoneColliderTypes.Capsule,
|
||||
Radius=0.1f
|
||||
}
|
||||
};
|
||||
Radius = 0.1f
|
||||
});
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
public List<VRM10SpringBoneCollider> Colliders = new List<VRM10SpringBoneCollider>();
|
||||
|
||||
public static void DrawWireCapsule(Vector3 headPos, Vector3 tailPos, float radius)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
/// <summary>
|
||||
/// すべての SpringBone を管理する。
|
||||
/// Humanoid 一体につきひとつだけ存在する。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class VRM10SpringBoneManager
|
||||
{
|
||||
[SerializeField]
|
||||
public List<VRM10SpringBone> Springs = new List<VRM10SpringBone>();
|
||||
|
||||
/// <summary>
|
||||
/// 1フレームに一回呼び出す(VRM10Controllerの仕事)
|
||||
/// </summary>
|
||||
public void Process()
|
||||
{
|
||||
foreach (var spring in Springs)
|
||||
{
|
||||
spring.Process();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c012308d77f262b4789f2fee6cdb7105
|
||||
guid: d09e28f7198c42d42bb31fd40e164b2d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -15,16 +15,16 @@ namespace UniVRM10
|
||||
[DisallowMultipleComponent]
|
||||
public class VRM10Controller : MonoBehaviour
|
||||
{
|
||||
public enum UpdateTypes
|
||||
{
|
||||
None,
|
||||
Update,
|
||||
LateUpdate,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class VRM10ControllerImpl
|
||||
{
|
||||
public enum UpdateTypes
|
||||
{
|
||||
None,
|
||||
Update,
|
||||
LateUpdate,
|
||||
}
|
||||
|
||||
[SerializeField, Header("UpdateSetting")]
|
||||
public UpdateTypes UpdateType = UpdateTypes.LateUpdate;
|
||||
}
|
||||
@@ -44,6 +44,9 @@ namespace UniVRM10
|
||||
[SerializeField]
|
||||
public VRM10ControllerFirstPerson FirstPerson = new VRM10ControllerFirstPerson();
|
||||
|
||||
[SerializeField]
|
||||
public VRM10SpringBoneManager SpringBone = new VRM10SpringBoneManager();
|
||||
|
||||
[SerializeField]
|
||||
public ModelAsset ModelAsset;
|
||||
|
||||
@@ -62,7 +65,6 @@ namespace UniVRM10
|
||||
}
|
||||
|
||||
VRMConstraint[] m_constraints;
|
||||
VRM10SpringBone[] m_springs;
|
||||
|
||||
Transform m_head;
|
||||
public Transform Head
|
||||
@@ -133,14 +135,7 @@ namespace UniVRM10
|
||||
//
|
||||
// spring
|
||||
//
|
||||
if (m_springs == null)
|
||||
{
|
||||
m_springs = GetComponentsInChildren<VRM10SpringBone>();
|
||||
}
|
||||
foreach (var spring in m_springs)
|
||||
{
|
||||
spring.Process();
|
||||
}
|
||||
SpringBone.Process();
|
||||
|
||||
//
|
||||
// expression
|
||||
@@ -160,7 +155,7 @@ namespace UniVRM10
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Controller.UpdateType == UpdateTypes.Update)
|
||||
if (Controller.UpdateType == VRM10ControllerImpl.UpdateTypes.Update)
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
@@ -168,7 +163,7 @@ namespace UniVRM10
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (Controller.UpdateType == UpdateTypes.LateUpdate)
|
||||
if (Controller.UpdateType == VRM10ControllerImpl.UpdateTypes.LateUpdate)
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
|
||||
@@ -232,67 +232,67 @@ namespace UniVRM10
|
||||
|
||||
// springBone
|
||||
{
|
||||
var colliders = new Dictionary<VrmLib.SpringBoneColliderGroup, UniVRM10.VRM10SpringBoneColliderGroup>();
|
||||
if (model.Vrm.SpringBone != null)
|
||||
{
|
||||
foreach (var colliderGroup in model.Vrm.SpringBone.Springs.SelectMany(x => x.Colliders))
|
||||
{
|
||||
var go = asset.Map.Nodes[colliderGroup.Node];
|
||||
var springBoneColliderGroup = go.AddComponent<UniVRM10.VRM10SpringBoneColliderGroup>();
|
||||
|
||||
springBoneColliderGroup.Colliders = colliderGroup.Colliders.Select(x =>
|
||||
{
|
||||
switch (x.ColliderType)
|
||||
{
|
||||
case VrmLib.VrmSpringBoneColliderTypes.Sphere:
|
||||
return new UniVRM10.VRM10SpringBoneCollider()
|
||||
{
|
||||
ColliderType = VRM10SpringBoneColliderTypes.Sphere,
|
||||
Offset = x.Offset.ToUnityVector3(),
|
||||
Radius = x.Radius
|
||||
};
|
||||
|
||||
case VrmLib.VrmSpringBoneColliderTypes.Capsule:
|
||||
return new UniVRM10.VRM10SpringBoneCollider()
|
||||
{
|
||||
ColliderType = VRM10SpringBoneColliderTypes.Capsule,
|
||||
Offset = x.Offset.ToUnityVector3(),
|
||||
Radius = x.Radius,
|
||||
Tail = x.CapsuleTail.ToUnityVector3(),
|
||||
};
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}).ToArray(); ;
|
||||
|
||||
colliders.Add(colliderGroup, springBoneColliderGroup);
|
||||
}
|
||||
}
|
||||
|
||||
GameObject springBoneObject = null;
|
||||
var springBoneTransform = asset.Root.transform.GetChildren().FirstOrDefault(x => x.name == "SpringBone");
|
||||
if (springBoneTransform == null)
|
||||
{
|
||||
springBoneObject = new GameObject("SpringBone");
|
||||
}
|
||||
else
|
||||
{
|
||||
springBoneObject = springBoneTransform.gameObject;
|
||||
}
|
||||
|
||||
springBoneObject.transform.SetParent(asset.Root.transform);
|
||||
if (model.Vrm.SpringBone != null)
|
||||
{
|
||||
foreach (var vrmSpring in model.Vrm.SpringBone.Springs)
|
||||
{
|
||||
var springBone = springBoneObject.AddComponent<UniVRM10.VRM10SpringBone>();
|
||||
// create a spring
|
||||
var springBone = new UniVRM10.VRM10SpringBone();
|
||||
springBone.m_comment = vrmSpring.Comment;
|
||||
if (vrmSpring.Origin != null && asset.Map.Nodes.TryGetValue(vrmSpring.Origin, out GameObject origin))
|
||||
{
|
||||
springBone.m_center = origin.transform;
|
||||
}
|
||||
controller.SpringBone.Springs.Add(springBone);
|
||||
|
||||
// create colliders for the spring
|
||||
foreach (var vrmSpringBoneCollider in vrmSpring.Colliders)
|
||||
{
|
||||
var go = asset.Map.Nodes[vrmSpringBoneCollider.Node];
|
||||
var springBoneColliderGroup = go.GetComponent<UniVRM10.VRM10SpringBoneColliderGroup>();
|
||||
if (springBoneColliderGroup != null)
|
||||
{
|
||||
// already setup
|
||||
}
|
||||
else
|
||||
{
|
||||
// new collider
|
||||
springBoneColliderGroup = go.AddComponent<UniVRM10.VRM10SpringBoneColliderGroup>();
|
||||
|
||||
// add collider shapes
|
||||
springBoneColliderGroup.Colliders.Clear();
|
||||
foreach (var x in vrmSpringBoneCollider.Colliders)
|
||||
{
|
||||
switch (x.ColliderType)
|
||||
{
|
||||
case VrmLib.VrmSpringBoneColliderTypes.Sphere:
|
||||
springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider()
|
||||
{
|
||||
ColliderType = VRM10SpringBoneColliderTypes.Sphere,
|
||||
Offset = x.Offset.ToUnityVector3(),
|
||||
Radius = x.Radius
|
||||
});
|
||||
break;
|
||||
|
||||
case VrmLib.VrmSpringBoneColliderTypes.Capsule:
|
||||
springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider()
|
||||
{
|
||||
ColliderType = VRM10SpringBoneColliderTypes.Capsule,
|
||||
Offset = x.Offset.ToUnityVector3(),
|
||||
Radius = x.Radius,
|
||||
Tail = x.CapsuleTail.ToUnityVector3(),
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
springBone.ColliderGroups.Add(springBoneColliderGroup);
|
||||
}
|
||||
|
||||
// create joint for the spring
|
||||
foreach (var vrmJoint in vrmSpring.Joints)
|
||||
{
|
||||
var joint = new VRM10SpringBone.VRM10SpringJoint();
|
||||
@@ -305,8 +305,6 @@ namespace UniVRM10
|
||||
|
||||
springBone.Joints.Add(joint);
|
||||
}
|
||||
|
||||
springBone.ColliderGroups = vrmSpring.Colliders.Select(x => colliders[x]).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,133 +258,136 @@ namespace UniVRM10
|
||||
|
||||
// blendShape
|
||||
var controller = root.GetComponent<UniVRM10.VRM10Controller>();
|
||||
if (controller != null)
|
||||
{
|
||||
Model.Vrm.ExpressionManager = new VrmLib.ExpressionManager();
|
||||
if (controller != null)
|
||||
{
|
||||
foreach (var clip in controller.Expression.ExpressionAvatar.Clips)
|
||||
Model.Vrm.ExpressionManager = new VrmLib.ExpressionManager();
|
||||
if (controller != null)
|
||||
{
|
||||
var expression = ToVrmLib(clip, root);
|
||||
if (expression != null)
|
||||
foreach (var clip in controller.Expression.ExpressionAvatar.Clips)
|
||||
{
|
||||
Model.Vrm.ExpressionManager.ExpressionList.Add(expression);
|
||||
var expression = ToVrmLib(clip, root);
|
||||
if (expression != null)
|
||||
{
|
||||
Model.Vrm.ExpressionManager.ExpressionList.Add(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// firstPerson
|
||||
{
|
||||
var firstPerson = new VrmLib.FirstPerson();
|
||||
if (controller != null)
|
||||
// firstPerson
|
||||
{
|
||||
foreach (var annotation in controller.FirstPerson.Renderers)
|
||||
var firstPerson = new VrmLib.FirstPerson();
|
||||
if (controller != null)
|
||||
{
|
||||
firstPerson.Annotations.Add(
|
||||
new VrmLib.FirstPersonMeshAnnotation(Nodes[annotation.Renderer.gameObject],
|
||||
annotation.FirstPersonFlag)
|
||||
);
|
||||
foreach (var annotation in controller.FirstPerson.Renderers)
|
||||
{
|
||||
firstPerson.Annotations.Add(
|
||||
new VrmLib.FirstPersonMeshAnnotation(Nodes[annotation.Renderer.gameObject],
|
||||
annotation.FirstPersonFlag)
|
||||
);
|
||||
}
|
||||
Model.Vrm.FirstPerson = firstPerson;
|
||||
}
|
||||
Model.Vrm.FirstPerson = firstPerson;
|
||||
}
|
||||
}
|
||||
|
||||
// lookAt
|
||||
{
|
||||
var lookAt = new VrmLib.LookAt();
|
||||
if (controller != null)
|
||||
// lookAt
|
||||
{
|
||||
if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Expression)
|
||||
var lookAt = new VrmLib.LookAt();
|
||||
if (controller != null)
|
||||
{
|
||||
lookAt.HorizontalInner = new VrmLib.LookAtRangeMap();
|
||||
lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap()
|
||||
if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Expression)
|
||||
{
|
||||
InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree
|
||||
};
|
||||
lookAt.VerticalUp = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree,
|
||||
};
|
||||
lookAt.VerticalDown = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree,
|
||||
};
|
||||
}
|
||||
else if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Bone)
|
||||
{
|
||||
lookAt.HorizontalInner = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.HorizontalInner.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.HorizontalInner.CurveYRangeDegree
|
||||
};
|
||||
lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree
|
||||
};
|
||||
lookAt.VerticalUp = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree,
|
||||
};
|
||||
lookAt.VerticalDown = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree,
|
||||
};
|
||||
}
|
||||
lookAt.OffsetFromHeadBone = controller.LookAt.OffsetFromHead.ToNumericsVector3();
|
||||
}
|
||||
Model.Vrm.LookAt = lookAt;
|
||||
}
|
||||
|
||||
// springBone
|
||||
{
|
||||
var springBones = root.GetComponentsInChildren<UniVRM10.VRM10SpringBone>();
|
||||
foreach (var springBone in springBones)
|
||||
{
|
||||
var vrmSpringBone = new VrmLib.SpringBone()
|
||||
{
|
||||
Comment = springBone.m_comment,
|
||||
Origin = (springBone.m_center != null) ? Nodes[springBone.m_center.gameObject] : null,
|
||||
};
|
||||
|
||||
foreach (var joint in springBone.Joints)
|
||||
{
|
||||
vrmSpringBone.Joints.Add(new VrmLib.SpringJoint
|
||||
{
|
||||
Stiffness = joint.m_stiffnessForce,
|
||||
GravityPower = joint.m_gravityPower,
|
||||
GravityDir = joint.m_gravityDir.ToNumericsVector3(),
|
||||
DragForce = joint.m_dragForce,
|
||||
HitRadius = joint.m_hitRadius,
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var colliderGroup in springBone.ColliderGroups)
|
||||
{
|
||||
var colliderGroups = colliderGroup.Colliders.Select(x =>
|
||||
{
|
||||
switch (x.ColliderType)
|
||||
lookAt.HorizontalInner = new VrmLib.LookAtRangeMap();
|
||||
lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
case VRM10SpringBoneColliderTypes.Sphere:
|
||||
return VrmLib.VrmSpringBoneCollider.CreateSphere(x.Offset.ToNumericsVector3(), x.Radius);
|
||||
|
||||
case VRM10SpringBoneColliderTypes.Capsule:
|
||||
return VrmLib.VrmSpringBoneCollider.CreateCapsule(x.Offset.ToNumericsVector3(), x.Radius, x.Tail.ToNumericsVector3());
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
});
|
||||
var vrmColliderGroup = new VrmLib.SpringBoneColliderGroup(Nodes[colliderGroup.gameObject], colliderGroups);
|
||||
vrmSpringBone.Colliders.Add(vrmColliderGroup);
|
||||
InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree
|
||||
};
|
||||
lookAt.VerticalUp = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree,
|
||||
};
|
||||
lookAt.VerticalDown = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree,
|
||||
};
|
||||
}
|
||||
else if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Bone)
|
||||
{
|
||||
lookAt.HorizontalInner = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.HorizontalInner.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.HorizontalInner.CurveYRangeDegree
|
||||
};
|
||||
lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree
|
||||
};
|
||||
lookAt.VerticalUp = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree,
|
||||
};
|
||||
lookAt.VerticalDown = new VrmLib.LookAtRangeMap()
|
||||
{
|
||||
InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree,
|
||||
OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree,
|
||||
};
|
||||
}
|
||||
lookAt.OffsetFromHeadBone = controller.LookAt.OffsetFromHead.ToNumericsVector3();
|
||||
}
|
||||
Model.Vrm.LookAt = lookAt;
|
||||
}
|
||||
|
||||
Model.Vrm.SpringBone.Springs.Add(vrmSpringBone);
|
||||
// springBone
|
||||
{
|
||||
var springBoneManager = controller.SpringBone;
|
||||
foreach (var springBone in springBoneManager.Springs)
|
||||
{
|
||||
var vrmSpringBone = new VrmLib.SpringBone()
|
||||
{
|
||||
Comment = springBone.m_comment,
|
||||
Origin = (springBone.m_center != null) ? Nodes[springBone.m_center.gameObject] : null,
|
||||
};
|
||||
|
||||
foreach (var joint in springBone.Joints)
|
||||
{
|
||||
vrmSpringBone.Joints.Add(new VrmLib.SpringJoint
|
||||
{
|
||||
Stiffness = joint.m_stiffnessForce,
|
||||
GravityPower = joint.m_gravityPower,
|
||||
GravityDir = joint.m_gravityDir.ToNumericsVector3(),
|
||||
DragForce = joint.m_dragForce,
|
||||
HitRadius = joint.m_hitRadius,
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var colliderGroup in springBone.ColliderGroups)
|
||||
{
|
||||
var colliderGroups = colliderGroup.Colliders.Select(x =>
|
||||
{
|
||||
switch (x.ColliderType)
|
||||
{
|
||||
case VRM10SpringBoneColliderTypes.Sphere:
|
||||
return VrmLib.VrmSpringBoneCollider.CreateSphere(x.Offset.ToNumericsVector3(), x.Radius);
|
||||
|
||||
case VRM10SpringBoneColliderTypes.Capsule:
|
||||
return VrmLib.VrmSpringBoneCollider.CreateCapsule(x.Offset.ToNumericsVector3(), x.Radius, x.Tail.ToNumericsVector3());
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
});
|
||||
var vrmColliderGroup = new VrmLib.SpringBoneColliderGroup(Nodes[colliderGroup.gameObject], colliderGroups);
|
||||
vrmSpringBone.Colliders.Add(vrmColliderGroup);
|
||||
}
|
||||
|
||||
Model.Vrm.SpringBone.Springs.Add(vrmSpringBone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,9 @@ namespace VrmLib
|
||||
return false;
|
||||
}
|
||||
|
||||
var Vrm = new Vrm(storage.CreateVrmMeta(model.Textures), storage.VrmExporterVersion, storage.VrmSpecVersion);
|
||||
var meta = storage.CreateVrmMeta(model.Textures);
|
||||
|
||||
var Vrm = new Vrm(meta, storage.VrmExporterVersion, storage.VrmSpecVersion);
|
||||
model.Vrm = Vrm;
|
||||
|
||||
storage.LoadVrmHumanoid(model.Nodes);
|
||||
|
||||
Reference in New Issue
Block a user