diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs index 5b8aba36f..b5cb6e1c9 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs @@ -42,6 +42,35 @@ namespace UniGLTF.SpringBoneJobs // System Level public float DeltaTime; + static float MaxValue(Vector3 s) + { + var x = Mathf.Abs(s.x); + var y = Mathf.Abs(s.y); + var z = Mathf.Abs(s.z); + if (x < y) + { + if (y < z) + { + return z; + } + else + { + return y; + } + } + else + { + if (x < z) + { + return z; + } + else + { + return x; + } + } + } + /// 房のindex public void Execute(int index) { @@ -81,13 +110,16 @@ namespace UniGLTF.SpringBoneJobs var parentRotation = parentTransform?.rotation ?? Quaternion.identity; + // scaling 対応 + var scalingFactor = model.SupportsScalingAtRuntime ? MaxValue(headTransform.localToWorldMatrix.lossyScale) : 1.0f; + // verlet積分で次の位置を計算 var external = (joint.gravityDir * joint.gravityPower + model.ExternalForce) * DeltaTime; var nextTail = currentTail + (currentTail - prevTail) * (1.0f - joint.dragForce) // 前フレームの移動を継続する(減衰もあるよ) + parentRotation * logic.localRotation * logic.boneAxis * - joint.stiffnessForce * DeltaTime // 親の回転による子ボーンの移動目標 - + external; // 外力による移動量 + joint.stiffnessForce * DeltaTime * scalingFactor // 親の回転による子ボーンの移動目標 + + external * scalingFactor; // 外力による移動量 // 長さをboneLengthに強制 nextTail = headTransform.position + (nextTail - headTransform.position).normalized * logic.length; diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity b/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity index c14346314..731b58285 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity @@ -357,6 +357,88 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 74180717} m_CullTransparentMesh: 1 +--- !u!1 &87189655 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 87189656} + - component: {fileID: 87189658} + - component: {fileID: 87189657} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &87189656 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87189655} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 434383452} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &87189657 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87189655} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 'ReconstructSpring + +' +--- !u!222 &87189658 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87189655} + m_CullTransparentMesh: 0 --- !u!1 &103723703 GameObject: m_ObjectHideFlags: 0 @@ -388,7 +470,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 339774397} - m_RootOrder: 22 + m_RootOrder: 23 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1532,6 +1614,7 @@ RectTransform: - {fileID: 310817054} - {fileID: 1828459436} - {fileID: 704896193} + - {fileID: 434383452} - {fileID: 597950322} - {fileID: 935566651} - {fileID: 634488421} @@ -1690,6 +1773,128 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 427963460} m_CullTransparentMesh: 0 +--- !u!1 &434383451 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 434383452} + - component: {fileID: 434383455} + - component: {fileID: 434383454} + - component: {fileID: 434383453} + m_Layer: 5 + m_Name: ReconstructSpringBone\ + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &434383452 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 434383451} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 87189656} + m_Father: {fileID: 339774397} + m_RootOrder: 18 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 162, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &434383453 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 434383451} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 434383454} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &434383454 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 434383451} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &434383455 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 434383451} + m_CullTransparentMesh: 0 --- !u!1 &450042403 GameObject: m_ObjectHideFlags: 0 @@ -2120,7 +2325,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 339774397} - m_RootOrder: 18 + m_RootOrder: 19 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -2201,7 +2406,7 @@ RectTransform: - {fileID: 154330168} - {fileID: 1954133885} m_Father: {fileID: 339774397} - m_RootOrder: 23 + m_RootOrder: 24 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -2368,7 +2573,7 @@ RectTransform: - {fileID: 2010083454} - {fileID: 1081455630} m_Father: {fileID: 339774397} - m_RootOrder: 20 + m_RootOrder: 21 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -3882,7 +4087,7 @@ RectTransform: - {fileID: 175751363} - {fileID: 1904789319} m_Father: {fileID: 339774397} - m_RootOrder: 19 + m_RootOrder: 20 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -7541,7 +7746,7 @@ RectTransform: - {fileID: 62367395} - {fileID: 1037763549} m_Father: {fileID: 339774397} - m_RootOrder: 21 + m_RootOrder: 22 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -7728,6 +7933,7 @@ MonoBehaviour: m_springboneExternalY: {fileID: 310817055} m_springboneExternalZ: {fileID: 1828459437} m_resetSpringBone: {fileID: 704896194} + m_reconstructSpringBone: {fileID: 434383453} m_texts: m_textModelTitle: {fileID: 1111491925} m_textModelVersion: {fileID: 1045380263} diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs index c780d5c73..f7b442561 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs @@ -64,6 +64,8 @@ namespace UniVRM10.VRM10Viewer [SerializeField] Button m_resetSpringBone = default; + [SerializeField] + Button m_reconstructSpringBone = default; GameObject Root = default; @@ -369,6 +371,7 @@ namespace UniVRM10.VRM10Viewer m_openMotion.onClick.AddListener(OnOpenMotionClicked); m_pastePose.onClick.AddListener(OnPastePoseClicked); m_resetSpringBone.onClick.AddListener(OnResetSpringBoneClicked); + m_reconstructSpringBone.onClick.AddListener(OnReconstructSpringBoneClicked); // load initial bvh if (m_motion != null) @@ -524,6 +527,17 @@ namespace UniVRM10.VRM10Viewer } } + void OnReconstructSpringBoneClicked() + { + if (m_loaded != null) + { + if (m_loaded.Runtime != null) + { + m_loaded.Runtime.SpringBone.ReconstructSpringBone(); + } + } + } + static IMaterialDescriptorGenerator GetVrmMaterialDescriptorGenerator(bool useUrp) { if (useUrp)