diff --git a/Assets/UniGLTF/Runtime/UniGLTF/UniGLTFVersion.cs b/Assets/UniGLTF/Runtime/UniGLTF/UniGLTFVersion.cs index 0ad1c1da7..d90a79ab7 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/UniGLTFVersion.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/UniGLTFVersion.cs @@ -4,8 +4,8 @@ namespace UniGLTF public static partial class UniGLTFVersion { public const int MAJOR = 2; - public const int MINOR = 46; + public const int MINOR = 47; public const int PATCH = 0; - public const string VERSION = "2.46.0"; + public const string VERSION = "2.47.0"; } } diff --git a/Assets/UniGLTF/package.json b/Assets/UniGLTF/package.json index 8359efa35..5d8ef9510 100644 --- a/Assets/UniGLTF/package.json +++ b/Assets/UniGLTF/package.json @@ -1,6 +1,6 @@ { "name": "com.vrmc.gltf", - "version": "0.110.0", + "version": "0.111.0", "displayName": "UniGLTF", "description": "GLTF importer and exporter", "unity": "2019.4", @@ -11,7 +11,7 @@ "name": "VRM Consortium" }, "dependencies": { - "com.vrmc.vrmshaders": "0.110.0", + "com.vrmc.vrmshaders": "0.111.0", "com.unity.modules.animation": "1.0.0" }, "samples": [ diff --git a/Assets/VRM/Runtime/Format/VRMVersion.cs b/Assets/VRM/Runtime/Format/VRMVersion.cs index 41892314d..660ba2150 100644 --- a/Assets/VRM/Runtime/Format/VRMVersion.cs +++ b/Assets/VRM/Runtime/Format/VRMVersion.cs @@ -4,8 +4,8 @@ namespace VRM public static partial class VRMVersion { public const int MAJOR = 0; - public const int MINOR = 110; + public const int MINOR = 111; public const int PATCH = 0; - public const string VERSION = "0.110.0"; + public const string VERSION = "0.111.0"; } } diff --git a/Assets/VRM/package.json b/Assets/VRM/package.json index e3c8db533..9f69e52a4 100644 --- a/Assets/VRM/package.json +++ b/Assets/VRM/package.json @@ -1,6 +1,6 @@ { "name": "com.vrmc.univrm", - "version": "0.110.0", + "version": "0.111.0", "displayName": "VRM", "description": "VRM importer", "unity": "2019.4", @@ -14,8 +14,8 @@ "name": "VRM Consortium" }, "dependencies": { - "com.vrmc.vrmshaders": "0.110.0", - "com.vrmc.gltf": "0.110.0", + "com.vrmc.vrmshaders": "0.111.0", + "com.vrmc.gltf": "0.111.0", "com.unity.ugui": "1.0.0" }, "samples": [ diff --git a/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset.asset b/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset.asset index 7d9e94149..a9311a774 100644 --- a/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset.asset +++ b/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset.asset @@ -32,7 +32,7 @@ MonoBehaviour: m_MainLightShadowmapResolution: 2048 m_AdditionalLightsRenderingMode: 1 m_AdditionalLightsPerObjectLimit: 4 - m_AdditionalLightShadowsSupported: 0 + m_AdditionalLightShadowsSupported: 1 m_AdditionalLightsShadowmapResolution: 512 m_ShadowDistance: 50 m_ShadowCascadeCount: 4 diff --git a/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset_Renderer.asset b/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset_Renderer.asset index cd7074b5f..9c8da0435 100644 --- a/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset_Renderer.asset +++ b/Assets/VRM10/Samples~/URPSample/Settings/UniversalRenderPipelineAsset_Renderer.asset @@ -12,8 +12,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: de640fe3d0db1804a85f9fc8f5cadab6, type: 3} m_Name: UniversalRenderPipelineAsset_Renderer m_EditorClassIdentifier: - m_RendererFeatures: [] - m_RendererFeatureMap: + m_RendererFeatures: + - {fileID: 6807519784255233043} + m_RendererFeatureMap: 131cfa0d2d2b795e postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2} xrSystemData: {fileID: 11400000, guid: 60e1133243b97e347b653163a8c01b64, type: 2} shaders: @@ -43,3 +44,16 @@ MonoBehaviour: m_ShadowTransparentReceive: 1 m_RenderingMode: 0 m_AccurateGbufferNormals: 0 +--- !u!114 &6807519784255233043 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5b6d00cd3f0249a2b4ee7dc86f9a8d63, type: 3} + m_Name: MToonOutlineRenderFeature + m_EditorClassIdentifier: + m_Active: 1 diff --git a/Assets/VRM10/Samples~/VRM10Viewer/VRM10Loaded.cs b/Assets/VRM10/Samples~/VRM10Viewer/VRM10Loaded.cs index c2e2198dc..e5d5882b5 100644 --- a/Assets/VRM10/Samples~/VRM10Viewer/VRM10Loaded.cs +++ b/Assets/VRM10/Samples~/VRM10Viewer/VRM10Loaded.cs @@ -10,6 +10,7 @@ namespace UniVRM10.VRM10Viewer RuntimeGltfInstance m_instance; Vrm10Instance m_controller; public Vrm10RuntimeControlRig ControlRig => m_controller.Runtime.ControlRig; + public Vrm10Runtime Runtime => m_controller.Runtime; VRM10AIUEO m_lipSync; bool m_enableLipSyncValue; diff --git a/Assets/VRM10/Samples~/VRM10Viewer/VRM10Motion.cs b/Assets/VRM10/Samples~/VRM10Viewer/VRM10Motion.cs index fc49d1ab1..62b293e1a 100644 --- a/Assets/VRM10/Samples~/VRM10Viewer/VRM10Motion.cs +++ b/Assets/VRM10/Samples~/VRM10Viewer/VRM10Motion.cs @@ -14,6 +14,8 @@ namespace UniVRM10.VRM10Viewer public interface IMotion : IDisposable { (INormalizedPoseProvider, ITPoseProvider) ControlRig { get; } + IDictionary ExpressionMap { get; } + void ShowBoxMan(bool enable); } @@ -25,6 +27,7 @@ namespace UniVRM10.VRM10Viewer public SkinnedMeshRenderer BoxMan => m_boxMan; (INormalizedPoseProvider, ITPoseProvider) m_controlRig; (INormalizedPoseProvider, ITPoseProvider) IMotion.ControlRig => m_controlRig; + public IDictionary ExpressionMap { get; } = new Dictionary(); public BvhMotion(UniHumanoid.BvhImporterContext context) { m_context = context; @@ -70,6 +73,8 @@ namespace UniVRM10.VRM10Viewer public SkinnedMeshRenderer BoxMan => m_boxMan; (INormalizedPoseProvider, ITPoseProvider) m_controlRig; (INormalizedPoseProvider, ITPoseProvider) IMotion.ControlRig => m_controlRig; + public IDictionary ExpressionMap { get; } = new Dictionary(); + public VrmAnimation(UniGLTF.RuntimeGltfInstance instance) { m_instance = instance; @@ -79,28 +84,35 @@ namespace UniVRM10.VRM10Viewer } var humanoid = instance.gameObject.AddComponent(); - humanoid.AssignBonesFromAnimator(); + if (humanoid.AssignBonesFromAnimator()) + { + var provider = new InitRotationPoseProvider(instance.transform, humanoid); + m_controlRig = (provider, provider); - var provider = new InitRotationPoseProvider(instance.transform, humanoid); - m_controlRig = (provider, provider); - - // create SkinnedMesh for bone visualize - var animator = instance.GetComponent(); - m_boxMan = SkeletonMeshUtility.CreateRenderer(animator); - var material = new Material(Shader.Find("Standard")); - BoxMan.sharedMaterial = material; - var mesh = BoxMan.sharedMesh; - mesh.name = "box-man"; + // create SkinnedMesh for bone visualize + var animator = instance.GetComponent(); + m_boxMan = SkeletonMeshUtility.CreateRenderer(animator); + var material = new Material(Shader.Find("Standard")); + BoxMan.sharedMaterial = material; + var mesh = BoxMan.sharedMesh; + mesh.name = "box-man"; + } } public void ShowBoxMan(bool enable) { - m_boxMan.enabled = enable; + if (m_boxMan != null) + { + m_boxMan.enabled = enable; + } } public void Dispose() { - GameObject.Destroy(m_boxMan.gameObject); + if (m_boxMan != null) + { + GameObject.Destroy(m_boxMan.gameObject); + } } static int? GetNodeIndex(UniGLTF.Extensions.VRMC_vrm_animation.Humanoid humanoid, HumanBodyBones bone) @@ -169,8 +181,6 @@ namespace UniVRM10.VRM10Viewer static Dictionary GetHumanMap(GltfData data, IReadOnlyList nodes) { var humanMap = new Dictionary(); - - if (data.GLTF.extensions is UniGLTF.glTFExtensionImport extensions) { foreach (var kv in extensions.ObjectItems()) @@ -178,13 +188,16 @@ namespace UniVRM10.VRM10Viewer if (kv.Key.GetString() == "VRMC_vrm_animation") { var animation = UniGLTF.Extensions.VRMC_vrm_animation.GltfDeserializer.Deserialize(kv.Value); - foreach (HumanBodyBones bone in UniGLTF.Utils.CachedEnum.GetValues()) + if (animation.Humanoid != null) { - // Debug.Log($"{bone} => {index}"); - var node = GetNodeIndex(animation.Humanoid, bone); - if (node.HasValue) + foreach (HumanBodyBones bone in UniGLTF.Utils.CachedEnum.GetValues()) { - humanMap.Add(bone, nodes[node.Value]); + // Debug.Log($"{bone} => {index}"); + var node = GetNodeIndex(animation.Humanoid, bone); + if (node.HasValue) + { + humanMap.Add(bone, nodes[node.Value]); + } } } } @@ -193,6 +206,59 @@ namespace UniVRM10.VRM10Viewer return humanMap; } + static List<(ExpressionKey, Transform)> GetExpressions(GltfData data, IReadOnlyList nodes) + { + var expressions = new List<(ExpressionKey, Transform)>(); + if (data.GLTF.extensions is UniGLTF.glTFExtensionImport extensions) + { + foreach (var kv in extensions.ObjectItems()) + { + if (kv.Key.GetString() == "VRMC_vrm_animation") + { + var animation = UniGLTF.Extensions.VRMC_vrm_animation.GltfDeserializer.Deserialize(kv.Value); + if (animation.Expressions != null) + { + foreach (ExpressionPreset preset in UniGLTF.Utils.CachedEnum.GetValues()) + { + var node = GetNodeIndex(animation.Expressions, preset); + if (node.HasValue) + { + expressions.Add((ExpressionKey.CreateFromPreset(preset), nodes[node.Value])); + } + } + } + } + } + } + return expressions; + } + + static int? GetNodeIndex(UniGLTF.Extensions.VRMC_vrm_animation.Expressions expressions, ExpressionPreset preset) + { + switch (preset) + { + case ExpressionPreset.happy: return expressions.Preset?.Happy?.Node; + case ExpressionPreset.angry: return expressions.Preset?.Angry?.Node; + case ExpressionPreset.sad: return expressions.Preset?.Sad?.Node; + case ExpressionPreset.relaxed: return expressions.Preset?.Relaxed?.Node; + case ExpressionPreset.surprised: return expressions.Preset?.Surprised?.Node; + case ExpressionPreset.aa: return expressions.Preset?.Aa?.Node; + case ExpressionPreset.ih: return expressions.Preset?.Ih?.Node; + case ExpressionPreset.ou: return expressions.Preset?.Ou?.Node; + case ExpressionPreset.ee: return expressions.Preset?.Ee?.Node; + case ExpressionPreset.oh: return expressions.Preset?.Oh?.Node; + case ExpressionPreset.blink: return expressions.Preset?.Blink?.Node; + case ExpressionPreset.blinkLeft: return expressions.Preset?.BlinkLeft?.Node; + case ExpressionPreset.blinkRight: return expressions.Preset?.BlinkRight?.Node; + case ExpressionPreset.lookUp: return expressions.Preset?.LookUp?.Node; + case ExpressionPreset.lookDown: return expressions.Preset?.LookDown?.Node; + case ExpressionPreset.lookLeft: return expressions.Preset?.LookLeft?.Node; + case ExpressionPreset.lookRight: return expressions.Preset?.LookRight?.Node; + case ExpressionPreset.neutral: return expressions.Preset?.Neutral?.Node; + } + return default; + } + public static async Task LoadVrmAnimationFromPathAsync(string path) { // @@ -202,25 +268,30 @@ namespace UniVRM10.VRM10Viewer using (var loader = new UniGLTF.ImporterContext(data)) { loader.InvertAxis = Axes.X; - // loader.PositionScaling = 0.01f; var instance = await loader.LoadAsync(new ImmediateCaller()); + + // VRMA-humanoid var humanMap = GetHumanMap(data, loader.Nodes); - if (humanMap.Count == 0) + if (humanMap.Count > 0) { - throw new ArgumentException("fail to load VRMC_vrm_animation"); + var description = AvatarDescription.Create(humanMap); + // + // avatar + // + var avatar = description.CreateAvatar(instance.Root.transform); + avatar.name = "Avatar"; + // AvatarDescription = description; + var animator = instance.gameObject.AddComponent(); + animator.avatar = avatar; } - var description = AvatarDescription.Create(humanMap); - // - // avatar - // - var avatar = description.CreateAvatar(instance.Root.transform); - avatar.name = "Avatar"; - // AvatarDescription = description; - var animator = instance.gameObject.AddComponent(); - animator.avatar = avatar; - - return new VrmAnimation(instance); + // VRMA-expression + var animation = new VrmAnimation(instance); + foreach (var (preset, transform) in GetExpressions(data, loader.Nodes)) + { + animation.ExpressionMap.Add(preset, transform); + } + return animation; } } } diff --git a/Assets/VRM10/Samples~/VRM10Viewer/VRM10ViewerUI.cs b/Assets/VRM10/Samples~/VRM10Viewer/VRM10ViewerUI.cs index 187d636e7..cbd775e12 100644 --- a/Assets/VRM10/Samples~/VRM10Viewer/VRM10ViewerUI.cs +++ b/Assets/VRM10/Samples~/VRM10Viewer/VRM10ViewerUI.cs @@ -304,7 +304,17 @@ namespace UniVRM10.VRM10Viewer if (m_ui.IsBvhEnabled && Motion != null) { - VRM10Retarget.Retarget(Motion.ControlRig, (m_loaded.ControlRig, m_loaded.ControlRig)); + // update humanoid + if (Motion.ControlRig.Item1 != null && Motion.ControlRig.Item2 != null) + { + VRM10Retarget.Retarget(Motion.ControlRig, (m_loaded.ControlRig, m_loaded.ControlRig)); + } + // update expressions + foreach (var (k, v) in Motion.ExpressionMap) + { + // VRMA-expression use localPosition.x as expression weight + m_loaded.Runtime.Expression.SetWeight(k, -v.transform.localPosition.x); + } } else { diff --git a/Assets/VRM10/package.json b/Assets/VRM10/package.json index 0f30c08ea..0d3176f42 100644 --- a/Assets/VRM10/package.json +++ b/Assets/VRM10/package.json @@ -1,6 +1,6 @@ { "name": "com.vrmc.vrm", - "version": "0.110.0", + "version": "0.111.0", "displayName": "VRM-1.0", "description": "VRM-1.0 importer", "unity": "2019.4", @@ -14,8 +14,8 @@ "name": "VRM Consortium" }, "dependencies": { - "com.vrmc.vrmshaders": "0.110.0", - "com.vrmc.gltf": "0.110.0" + "com.vrmc.vrmshaders": "0.111.0", + "com.vrmc.gltf": "0.111.0" }, "samples": [ { diff --git a/Assets/VRMShaders/package.json b/Assets/VRMShaders/package.json index 42bf94ff2..9976e9a5c 100644 --- a/Assets/VRMShaders/package.json +++ b/Assets/VRMShaders/package.json @@ -1,6 +1,6 @@ { "name": "com.vrmc.vrmshaders", - "version": "0.110.0", + "version": "0.111.0", "displayName": "VRM Shaders", "description": "VRM Shaders", "unity": "2019.4",