diff --git a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs
index 809ea6736..16199a6ec 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs
@@ -50,7 +50,9 @@ namespace UniVRM10
[SerializeField]
public VRM10ObjectLookAt.LookAtTargetTypes LookAtTargetType;
- UniHumanoid.Humanoid m_humanoid;
+ private UniHumanoid.Humanoid m_humanoid;
+ private Vrm10Runtime m_runtime;
+ private bool m_generateControlRig = false;
public UniHumanoid.Humanoid Humanoid
{
@@ -64,8 +66,6 @@ namespace UniVRM10
}
}
- Vrm10Runtime m_runtime;
-
///
/// ランタイム情報
///
@@ -75,12 +75,17 @@ namespace UniVRM10
{
if (m_runtime == null)
{
- m_runtime = new Vrm10Runtime(this);
+ m_runtime = new Vrm10Runtime(this, m_generateControlRig);
}
return m_runtime;
}
}
+ internal void InitializeAtRuntime(bool generateControlRig)
+ {
+ m_generateControlRig = generateControlRig;
+ }
+
void Start()
{
// cause new Vrm10Runtime.
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
index 1138f08ee..18872aa83 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
@@ -33,7 +33,7 @@ namespace UniVRM10
public Vrm10RuntimeExpression Expression { get; }
public Vrm10RuntimeLookAt LookAt { get; }
- public Vrm10Runtime(Vrm10Instance target)
+ public Vrm10Runtime(Vrm10Instance target, bool generateControlRig)
{
m_target = target;
@@ -42,7 +42,10 @@ namespace UniVRM10
throw new Exception();
}
- ControlRig = new Vrm10RuntimeControlRig(target.Humanoid);
+ if (generateControlRig)
+ {
+ ControlRig = new Vrm10RuntimeControlRig(target.Humanoid, m_target.transform);
+ }
Constraints = target.GetComponentsInChildren();
LookAt = new Vrm10RuntimeLookAt(target.Vrm.LookAt, target.Humanoid, m_head, target.LookAtTargetType, target.Gaze);
Expression = new Vrm10RuntimeExpression(target, LookAt, LookAt.EyeDirectionApplicable);
@@ -69,6 +72,13 @@ namespace UniVRM10
}
}
+ public void Dispose()
+ {
+ ControlRig?.Dispose();
+ m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer);
+ m_fastSpringBoneBuffer.Dispose();
+ }
+
///
/// このVRMに紐づくSpringBone関連のバッファを再構築する
/// ランタイム実行時にSpringBoneに対して変更を行いたいときは、このメソッドを明示的に呼ぶ必要がある
@@ -169,11 +179,5 @@ namespace UniVRM10
// 4. Expression
Expression.Process();
}
-
- public void Dispose()
- {
- m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer);
- m_fastSpringBoneBuffer.Dispose();
- }
}
}
\ No newline at end of file
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs
index 9adbeb807..fb4acf273 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs
@@ -1,4 +1,7 @@
+using System;
using System.Collections.Generic;
+using System.Linq;
+using UniHumanoid;
using UnityEngine;
namespace UniVRM10
@@ -10,27 +13,48 @@ namespace UniVRM10
/// Create a control rig for the VRM 1.0 model instance.
/// This provides the normalized operation of bones, like VRM 0.x.
///
- public sealed class Vrm10RuntimeControlRig
+ public sealed class Vrm10RuntimeControlRig : IDisposable
{
- private readonly Vrm10ControlBone _rootBone;
+ private readonly Transform _controlRigRoot;
+ private readonly Vrm10ControlBone _hipBone;
private readonly Dictionary _bones;
+ private readonly Avatar _controlRigAvatar;
+ public IReadOnlyDictionary Bones => _bones;
+ public Animator ControlRigAnimator { get; }
public float InitialHipsHeight { get; }
///
/// コンストラクタ。
/// humanoid は VRM T-Pose でなければならない。
///
- public Vrm10RuntimeControlRig(UniHumanoid.Humanoid humanoid)
+ public Vrm10RuntimeControlRig(UniHumanoid.Humanoid humanoid, Transform vrmRoot)
{
- _rootBone = Vrm10ControlBone.Build(humanoid, out _bones);
- InitialHipsHeight = _rootBone.ControlTarget.position.y;
+ _controlRigRoot = new GameObject("Runtime Control Rig").transform;
+ _controlRigRoot.SetParent(vrmRoot);
+
+ _hipBone = Vrm10ControlBone.Build(humanoid, out _bones);
+ _hipBone.ControlBone.SetParent(_controlRigRoot);
+
+ InitialHipsHeight = _hipBone.ControlTarget.position.y;
+
+ var transformBonePairs = _bones.Select(kv => (kv.Value.ControlBone, kv.Key));
+ _controlRigAvatar = HumanoidLoader.LoadHumanoidAvatar(_controlRigRoot, transformBonePairs);
+ _controlRigAvatar.name = "Runtime Control Rig";
+ ControlRigAnimator = _controlRigRoot.gameObject.AddComponent();
+ ControlRigAnimator.avatar = _controlRigAvatar;
+ }
+
+ public void Dispose()
+ {
+ UnityEngine.Object.Destroy(_controlRigAvatar);
+ UnityEngine.Object.Destroy(_controlRigRoot);
}
internal void Process()
{
- _rootBone.ControlTarget.position = _rootBone.ControlBone.position;
- _rootBone.ProcessRecursively();
+ _hipBone.ControlTarget.position = _hipBone.ControlBone.position;
+ _hipBone.ProcessRecursively();
}
public Transform GetBoneTransform(HumanBodyBones bone)
diff --git a/Assets/VRM10/Runtime/IO/Vrm10.cs b/Assets/VRM10/Runtime/IO/Vrm10.cs
index 78453a442..55e51eecc 100644
--- a/Assets/VRM10/Runtime/IO/Vrm10.cs
+++ b/Assets/VRM10/Runtime/IO/Vrm10.cs
@@ -27,6 +27,7 @@ namespace UniVRM10
///
/// vrm file path
/// if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.
+ /// if true, generating the control rig provides bone manipulation like vrm-0.x
/// if true, show meshes when loaded.
/// this loader use specified await strategy.
/// this loader use specified material generation strategy.
@@ -36,6 +37,7 @@ namespace UniVRM10
public static async Task LoadPathAsync(
string path,
bool canLoadVrm0X = true,
+ bool generateControlRig = true,
bool showMeshes = true,
IAwaitCaller awaitCaller = null,
IMaterialDescriptorGenerator materialGenerator = null,
@@ -53,6 +55,7 @@ namespace UniVRM10
path,
System.IO.File.ReadAllBytes(path),
canLoadVrm0X,
+ generateControlRig,
showMeshes,
awaitCaller,
materialGenerator,
@@ -68,6 +71,7 @@ namespace UniVRM10
///
/// vrm file data
/// if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.
+ /// if true, generating the control rig provides bone manipulation like vrm-0.x
/// if true, show meshes when loaded.
/// this loader use specified await strategy.
/// this loader use specified material generation strategy.
@@ -77,6 +81,7 @@ namespace UniVRM10
public static async Task LoadBytesAsync(
byte[] bytes,
bool canLoadVrm0X = true,
+ bool generateControlRig = true,
bool showMeshes = true,
IAwaitCaller awaitCaller = null,
IMaterialDescriptorGenerator materialGenerator = null,
@@ -94,6 +99,7 @@ namespace UniVRM10
string.Empty,
bytes,
canLoadVrm0X,
+ generateControlRig,
showMeshes,
awaitCaller,
materialGenerator,
@@ -105,6 +111,7 @@ namespace UniVRM10
string name,
byte[] bytes,
bool canLoadVrm0X,
+ bool generateControlRig,
bool showMeshes,
IAwaitCaller awaitCaller,
IMaterialDescriptorGenerator materialGenerator,
@@ -122,6 +129,7 @@ namespace UniVRM10
// 1. Try loading as vrm-1.0
var instance = await TryLoadingAsVrm10Async(
gltfData,
+ generateControlRig,
showMeshes,
awaitCaller,
materialGenerator,
@@ -146,6 +154,7 @@ namespace UniVRM10
// 3. Try migration from vrm-0.x into vrm-1.0
var migratedInstance = await TryMigratingFromVrm0XAsync(
gltfData,
+ generateControlRig,
showMeshes,
awaitCaller,
materialGenerator,
@@ -168,6 +177,7 @@ namespace UniVRM10
private static async Task TryLoadingAsVrm10Async(
GltfData gltfData,
+ bool generateControlRig,
bool showMeshes,
IAwaitCaller awaitCaller,
IMaterialDescriptorGenerator materialGenerator,
@@ -192,6 +202,7 @@ namespace UniVRM10
return await LoadVrm10DataAsync(
vrm10Data,
null,
+ generateControlRig,
showMeshes,
awaitCaller,
materialGenerator,
@@ -201,6 +212,7 @@ namespace UniVRM10
private static async Task TryMigratingFromVrm0XAsync(
GltfData gltfData,
+ bool generateControlRig,
bool showMeshes,
IAwaitCaller awaitCaller,
IMaterialDescriptorGenerator materialGenerator,
@@ -227,6 +239,7 @@ namespace UniVRM10
var migratedVrm10Instance = await LoadVrm10DataAsync(
migratedVrm10Data,
migrationData,
+ generateControlRig,
showMeshes,
awaitCaller,
materialGenerator,
@@ -243,6 +256,7 @@ namespace UniVRM10
private static async Task LoadVrm10DataAsync(
Vrm10Data vrm10Data,
MigrationData migrationData,
+ bool generateControlRig,
bool showMeshes,
IAwaitCaller awaitCaller,
IMaterialDescriptorGenerator materialGenerator,
@@ -260,7 +274,7 @@ namespace UniVRM10
throw new ArgumentNullException(nameof(vrm10Data));
}
- using (var loader = new Vrm10Importer(vrm10Data, materialGenerator: materialGenerator))
+ using (var loader = new Vrm10Importer(vrm10Data, generateControlRig: generateControlRig, materialGenerator: materialGenerator))
{
// 1. Load meta information if callback was available.
if (vrmMetaInformationCallback != null)
diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
index 0d6a2b495..b6261f30a 100644
--- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
+++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs
@@ -15,17 +15,23 @@ namespace UniVRM10
///
public class Vrm10Importer : UniGLTF.ImporterContext
{
- VrmLib.Model m_model;
+ private readonly Vrm10Data m_vrm;
+ /// VrmLib.Model の オブジェクトと UnityEngine.Object のマッピングを記録する
+ private readonly ModelMap m_map = new ModelMap();
+ private readonly bool m_generateControlRig;
- readonly Vrm10Data m_vrm;
-
- IReadOnlyDictionary m_externalMap;
+ private VrmLib.Model m_model;
+ private IReadOnlyDictionary m_externalMap;
+ private Avatar m_humanoid;
+ private VRM10Object m_vrmObject;
+ private List<(ExpressionPreset Preset, VRM10Expression Clip)> m_expressions = new List<(ExpressionPreset, VRM10Expression)>();
public Vrm10Importer(
Vrm10Data vrm,
IReadOnlyDictionary externalObjectMap = null,
ITextureDeserializer textureDeserializer = null,
- IMaterialDescriptorGenerator materialGenerator = null)
+ IMaterialDescriptorGenerator materialGenerator = null,
+ bool generateControlRig = false)
: base(vrm.Data, externalObjectMap, textureDeserializer)
{
if (vrm == null)
@@ -33,6 +39,7 @@ namespace UniVRM10
throw new ArgumentNullException("vrm");
}
m_vrm = vrm;
+ m_generateControlRig = generateControlRig;
TextureDescriptorGenerator = new Vrm10TextureDescriptorGenerator(Data);
MaterialDescriptorGenerator = materialGenerator ?? new Vrm10MaterialDescriptorGenerator();
@@ -44,18 +51,6 @@ namespace UniVRM10
}
}
- public class ModelMap
- {
- public readonly Dictionary Nodes = new Dictionary();
- public readonly Dictionary Meshes = new Dictionary();
- }
-
- ///
- /// VrmLib.Model の オブジェクトと UnityEngine.Object のマッピングを記録する
- ///
- ///
- readonly ModelMap m_map = new ModelMap();
-
static void AssignHumanoid(List nodes, UniGLTF.Extensions.VRMC_vrm.HumanBone humanBone, VrmLib.HumanoidBones key)
{
if (nodes == null)
@@ -237,10 +232,6 @@ namespace UniVRM10
}
}
- UnityEngine.Avatar m_humanoid;
- VRM10Object m_vrmObject;
- List<(ExpressionPreset Preset, VRM10Expression Clip)> m_expressions = new List<(ExpressionPreset, VRM10Expression)>();
-
protected override async Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func MeasureTime)
{
Root.name = "VRM1";
@@ -255,6 +246,7 @@ namespace UniVRM10
// VrmController
var controller = Root.AddComponent();
+ controller.InitializeAtRuntime(m_generateControlRig);
controller.enabled = false;
// vrm
@@ -847,5 +839,11 @@ namespace UniVRM10
base.Dispose();
}
+
+ public sealed class ModelMap
+ {
+ public readonly Dictionary Nodes = new Dictionary();
+ public readonly Dictionary Meshes = new Dictionary();
+ }
}
}
\ No newline at end of file
diff --git a/Assets/VRM10/Tests/ExpressionTests.cs b/Assets/VRM10/Tests/ExpressionTests.cs
index d176cb3e9..dfd370363 100644
--- a/Assets/VRM10/Tests/ExpressionTests.cs
+++ b/Assets/VRM10/Tests/ExpressionTests.cs
@@ -32,7 +32,7 @@ namespace UniVRM10.Test
controller.Vrm.Expression.Aa.MaterialColorBindings = src.ToArray();
// ok if no exception
- var r = new Vrm10Runtime(controller);
+ var r = new Vrm10Runtime(controller, false);
}
[Test]
@@ -56,7 +56,7 @@ namespace UniVRM10.Test
controller.Vrm.Expression.Aa.MaterialUVBindings = src.ToArray();
// ok if no exception
- var r = new Vrm10Runtime(controller);
+ var r = new Vrm10Runtime(controller, false);
}
}
}
diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs
index b99f1e17e..a400bd797 100644
--- a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs
+++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs
@@ -301,7 +301,7 @@ namespace UniVRM10.VRM10Viewer
if (bone == HumanBodyBones.Hips)
{
- controlRigBone.position = bvhBone.position * controlRig.InitialHipsHeight;
+ controlRigBone.localPosition = bvhBone.localPosition * controlRig.InitialHipsHeight;
}
}
else