mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-20 09:34:42 -05:00
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace UniVRM10.VRM10Viewer
|
||||
public interface IMotion : IDisposable
|
||||
{
|
||||
(INormalizedPoseProvider, ITPoseProvider) ControlRig { get; }
|
||||
IDictionary<ExpressionKey, Transform> 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<ExpressionKey, Transform> ExpressionMap { get; } = new Dictionary<ExpressionKey, Transform>();
|
||||
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<ExpressionKey, Transform> ExpressionMap { get; } = new Dictionary<ExpressionKey, Transform>();
|
||||
|
||||
public VrmAnimation(UniGLTF.RuntimeGltfInstance instance)
|
||||
{
|
||||
m_instance = instance;
|
||||
@@ -79,28 +84,35 @@ namespace UniVRM10.VRM10Viewer
|
||||
}
|
||||
|
||||
var humanoid = instance.gameObject.AddComponent<Humanoid>();
|
||||
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<Animator>();
|
||||
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<Animator>();
|
||||
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<HumanBodyBones, Transform> GetHumanMap(GltfData data, IReadOnlyList<Transform> nodes)
|
||||
{
|
||||
var humanMap = new Dictionary<HumanBodyBones, Transform>();
|
||||
|
||||
|
||||
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<HumanBodyBones>())
|
||||
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<HumanBodyBones>())
|
||||
{
|
||||
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<Transform> 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<ExpressionPreset>())
|
||||
{
|
||||
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<VrmAnimation> 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>();
|
||||
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>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user