mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-21 02:07:58 -05:00
Merge pull request #1779 from Santarh/crOption
Add the `GenerateControlRig` option to VRM 1.0 Importer.
This commit is contained in:
commit
fba82f02a8
|
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// ランタイム情報
|
||||
/// </summary>
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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<IVrm10Constraint>();
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// この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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
/// </summary>
|
||||
public sealed class Vrm10RuntimeControlRig
|
||||
public sealed class Vrm10RuntimeControlRig : IDisposable
|
||||
{
|
||||
private readonly Vrm10ControlBone _rootBone;
|
||||
private readonly Transform _controlRigRoot;
|
||||
private readonly Vrm10ControlBone _hipBone;
|
||||
private readonly Dictionary<HumanBodyBones, Vrm10ControlBone> _bones;
|
||||
private readonly Avatar _controlRigAvatar;
|
||||
|
||||
public IReadOnlyDictionary<HumanBodyBones, Vrm10ControlBone> Bones => _bones;
|
||||
public Animator ControlRigAnimator { get; }
|
||||
public float InitialHipsHeight { get; }
|
||||
|
||||
/// <summary>
|
||||
/// コンストラクタ。
|
||||
/// humanoid は VRM T-Pose でなければならない。
|
||||
/// </summary>
|
||||
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<Animator>();
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ namespace UniVRM10
|
|||
/// </summary>
|
||||
/// <param name="path">vrm file path</param>
|
||||
/// <param name="canLoadVrm0X">if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.</param>
|
||||
/// <param name="generateControlRig">if true, generating the control rig provides bone manipulation like vrm-0.x</param>
|
||||
/// <param name="showMeshes">if true, show meshes when loaded.</param>
|
||||
/// <param name="awaitCaller">this loader use specified await strategy.</param>
|
||||
/// <param name="materialGenerator">this loader use specified material generation strategy.</param>
|
||||
|
|
@ -36,6 +37,7 @@ namespace UniVRM10
|
|||
public static async Task<Vrm10Instance> 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
|
|||
/// </summary>
|
||||
/// <param name="bytes">vrm file data</param>
|
||||
/// <param name="canLoadVrm0X">if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.</param>
|
||||
/// <param name="generateControlRig">if true, generating the control rig provides bone manipulation like vrm-0.x</param>
|
||||
/// <param name="showMeshes">if true, show meshes when loaded.</param>
|
||||
/// <param name="awaitCaller">this loader use specified await strategy.</param>
|
||||
/// <param name="materialGenerator">this loader use specified material generation strategy.</param>
|
||||
|
|
@ -77,6 +81,7 @@ namespace UniVRM10
|
|||
public static async Task<Vrm10Instance> 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<Vrm10Instance> 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<Vrm10Instance> 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<Vrm10Instance> 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)
|
||||
|
|
|
|||
|
|
@ -15,17 +15,23 @@ namespace UniVRM10
|
|||
/// </summary>
|
||||
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<SubAssetKey, UnityEngine.Object> m_externalMap;
|
||||
private VrmLib.Model m_model;
|
||||
private IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> 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<SubAssetKey, UnityEngine.Object> 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<VrmLib.Node, GameObject> Nodes = new Dictionary<VrmLib.Node, GameObject>();
|
||||
public readonly Dictionary<VrmLib.MeshGroup, UnityEngine.Mesh> Meshes = new Dictionary<VrmLib.MeshGroup, UnityEngine.Mesh>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VrmLib.Model の オブジェクトと UnityEngine.Object のマッピングを記録する
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
readonly ModelMap m_map = new ModelMap();
|
||||
|
||||
static void AssignHumanoid(List<VrmLib.Node> 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<string, IDisposable> MeasureTime)
|
||||
{
|
||||
Root.name = "VRM1";
|
||||
|
|
@ -255,6 +246,7 @@ namespace UniVRM10
|
|||
|
||||
// VrmController
|
||||
var controller = Root.AddComponent<Vrm10Instance>();
|
||||
controller.InitializeAtRuntime(m_generateControlRig);
|
||||
controller.enabled = false;
|
||||
|
||||
// vrm
|
||||
|
|
@ -847,5 +839,11 @@ namespace UniVRM10
|
|||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public sealed class ModelMap
|
||||
{
|
||||
public readonly Dictionary<VrmLib.Node, GameObject> Nodes = new Dictionary<VrmLib.Node, GameObject>();
|
||||
public readonly Dictionary<VrmLib.MeshGroup, UnityEngine.Mesh> Meshes = new Dictionary<VrmLib.MeshGroup, UnityEngine.Mesh>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ namespace UniVRM10.VRM10Viewer
|
|||
|
||||
if (bone == HumanBodyBones.Hips)
|
||||
{
|
||||
controlRigBone.position = bvhBone.position * controlRig.InitialHipsHeight;
|
||||
controlRigBone.localPosition = bvhBone.localPosition * controlRig.InitialHipsHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user