diff --git a/README.md b/README.md index fbc3469..4435e48 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ Official releases are tagged and can be found [here](https://github.com/Malcolmn The following branches are in active development: | Branch | Description | Godot version | |-----------|-------------------------------|------------------| -| master | Current development branch | Godot 4.3-dev4+ | +| master | Current development branch | Godot 4.3-dev6+ | + +NOTE: This requires the [XR Trackers](https://github.com/godotengine/godot/pull/90645) PR which is in the Godot master branch, but no release has been made. ## Overview @@ -54,7 +56,11 @@ The character model must be in Godot Humanoid format. This can be achieved in th ### Body Driving -The body is driven using an [XRBodyModifier3D](https://docs.godotengine.org/en/latest/classes/class_xrbodymodifier3d.html) node configured to drive the skeleton of the character: +The body is positioned using an [XRNode3D](https://docs.godotengine.org/en/latest/classes/class_xrnode3d.html) node configured to track the character body: + +![XRNode3D](/docs/xrnode3d.png) + +The body is posed using an [XRBodyModifier3D](https://docs.godotengine.org/en/latest/classes/class_xrbodymodifier3d.html) node skeleton modifier: ![XRBodyModifier3D](/docs/xrbodymodifier3d.png) diff --git a/VERSIONS.md b/VERSIONS.md index 0d3e406..ae8f69a 100644 --- a/VERSIONS.md +++ b/VERSIONS.md @@ -1,3 +1,6 @@ +# 1.2.0 +- Updated for changes to XR Tracker names and hierarchy + # 1.1.0 - Set tracker "Root" under hips - Move avatars under body modifier diff --git a/addons/godot_vmc_tracker/plugin.cfg b/addons/godot_vmc_tracker/plugin.cfg index 60937b6..5e57c03 100644 --- a/addons/godot_vmc_tracker/plugin.cfg +++ b/addons/godot_vmc_tracker/plugin.cfg @@ -3,5 +3,5 @@ name="Godot VMC Tracker" description="Godot VMC Tracker plugin" author="Malcolm Nixon and Contributors" -version="1.0.0" +version="1.2.0" script="plugin.gd" diff --git a/addons/godot_vmc_tracker/plugin.gd b/addons/godot_vmc_tracker/plugin.gd index dbcd924..58c5afe 100644 --- a/addons/godot_vmc_tracker/plugin.gd +++ b/addons/godot_vmc_tracker/plugin.gd @@ -34,7 +34,7 @@ func _enter_tree(): TYPE_STRING, PROPERTY_HINT_NONE, "", - "/vmc/head") + "/vmc/face_tracker") # Add body tracker name _define_project_setting( @@ -42,7 +42,7 @@ func _enter_tree(): TYPE_STRING, PROPERTY_HINT_NONE, "", - "/vmc/body") + "/vmc/body_tracker") # Add position mode _define_project_setting( diff --git a/addons/godot_vmc_tracker/vmc_plugin.gd b/addons/godot_vmc_tracker/vmc_plugin.gd index 2b1fd5e..6934dc6 100644 --- a/addons/godot_vmc_tracker/vmc_plugin.gd +++ b/addons/godot_vmc_tracker/vmc_plugin.gd @@ -16,12 +16,12 @@ func _enter_tree() -> void: # Get the face tracker name var face_tracker_name : String = ProjectSettings.get_setting( "godot_vmc_tracker/tracking/face_tracker_name", - "/vmc/head") + "/vmc/face_tracker") # Get the body tracker name var body_tracker_name : String = ProjectSettings.get_setting( "godot_vmc_tracker/tracking/body_tracker_name", - "/vmc/body") + "/vmc/body_tracker") # Get the position mode var position_mode = ProjectSettings.get_setting( diff --git a/addons/godot_vmc_tracker/vmc_source.gd b/addons/godot_vmc_tracker/vmc_source.gd index 4fde3e9..de29e22 100644 --- a/addons/godot_vmc_tracker/vmc_source.gd +++ b/addons/godot_vmc_tracker/vmc_source.gd @@ -93,10 +93,12 @@ func _init( _face_blends.fill(0.0) # Register the face tracker - XRServer.add_face_tracker(face_tracker_name, _face_tracker) + _face_tracker.name = face_tracker_name + XRServer.add_tracker(_face_tracker) # Register the body tracker - XRServer.add_body_tracker(body_tracker_name, _body_tracker) + _body_tracker.name = body_tracker_name + XRServer.add_tracker(_body_tracker) # Save the position mode _position_mode = position_mode @@ -225,6 +227,12 @@ func _process_joints() -> void: var root := Transform3D(root_x, root_y, root_z, root_o).orthonormalized() _body_tracker.set_joint_transform(XRBodyTracker.JOINT_ROOT, root) _body_tracker.set_joint_flags(XRBodyTracker.JOINT_ROOT, JOINT_TRACKING) + _body_tracker.set_pose( + "default", + root, + Vector3.ZERO, + Vector3.ZERO, + XRPose.XR_TRACKING_CONFIDENCE_HIGH); # Indicate we are tracking the body _body_tracker.body_flags = BODY_TRACKING diff --git a/addons/godot_vmc_tracker/vmc_tracker.gd b/addons/godot_vmc_tracker/vmc_tracker.gd index 0266f90..87aeba5 100644 --- a/addons/godot_vmc_tracker/vmc_tracker.gd +++ b/addons/godot_vmc_tracker/vmc_tracker.gd @@ -10,10 +10,10 @@ extends Node ## Face tracker name -@export var face_tracker_name : String = "/vmc/head" +@export var face_tracker_name : String = "/vmc/face_tracker" ## Body tracker name -@export var body_tracker_name : String = "/vmc/body" +@export var body_tracker_name : String = "/vmc/body_tracker" ## Position mode @export_enum("Free", "Calibrate", "Locked") var position_mode : int = 0 diff --git a/addons/godot_vmc_tracker/vmc_tracker.tscn b/addons/godot_vmc_tracker/vmc_tracker.tscn index a1b1460..0e75068 100644 --- a/addons/godot_vmc_tracker/vmc_tracker.tscn +++ b/addons/godot_vmc_tracker/vmc_tracker.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=2 format=3 uid="uid://dvnmxtkucajqw"] +[gd_scene load_steps=2 format=4 uid="uid://dvnmxtkucajqw"] [ext_resource type="Script" path="res://addons/godot_vmc_tracker/vmc_tracker.gd" id="1_w1cjd"] diff --git a/demo.gd b/demo.gd index d9f7684..72a6383 100644 --- a/demo.gd +++ b/demo.gd @@ -47,8 +47,8 @@ func _input(event : InputEvent) -> void: func _on_skeleton_spin_box_value_changed(value: float) -> void: - %"Test-Chan/Armature/Skeleton3D".motion_scale = value - %"Test-Kun/Armature/Skeleton3D".motion_scale = value + $"Chan/ChanAvatar/Test-Chan/Armature/Skeleton3D".motion_scale = value + $"Kun/KunAvatar/Test-Kun/Armature/Skeleton3D".motion_scale = value func _on_world_spin_box_value_changed(value: float) -> void: diff --git a/demo.tscn b/demo.tscn index bad00dd..c8a460b 100644 --- a/demo.tscn +++ b/demo.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=14 format=3 uid="uid://dkkew3u3hi7md"] +[gd_scene load_steps=14 format=4 uid="uid://dkkew3u3hi7md"] [ext_resource type="Script" path="res://demo.gd" id="1_7k4ei"] [ext_resource type="PackedScene" uid="uid://bhc6nngwjdvum" path="res://assets/test_chan/Test-Chan.fbx" id="1_lkeve"] @@ -65,18 +65,12 @@ transform = Transform3D(0.939693, 0.0593911, -0.336824, 0, 0.984808, 0.173648, 0 [node name="Chan" type="Node3D" parent="."] transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, -0.6, 0, 0) -[node name="XRFaceModifier3D" type="XRFaceModifier3D" parent="Chan"] -face_tracker = &"/vmc/head" -target = NodePath("../XRBodyModifier3D/Test-Chan/Armature/Skeleton3D/Body") +[node name="ChanAvatar" type="XRNode3D" parent="Chan"] +tracker = &"/vmc/body_tracker" -[node name="XRBodyModifier3D" type="XRBodyModifier3D" parent="Chan"] -body_tracker = &"/vmc/body" -target = NodePath("Test-Chan/Armature/Skeleton3D") +[node name="Test-Chan" parent="Chan/ChanAvatar" instance=ExtResource("1_lkeve")] -[node name="Test-Chan" parent="Chan/XRBodyModifier3D" instance=ExtResource("1_lkeve")] -unique_name_in_owner = true - -[node name="Body" parent="Chan/XRBodyModifier3D/Test-Chan/Armature/Skeleton3D" index="0"] +[node name="Body" parent="Chan/ChanAvatar/Test-Chan/Armature/Skeleton3D" index="0"] blend_shapes/Cheek_Puff_Left = 1.28996e-05 blend_shapes/Cheek_Puff_Right = 1.28996e-05 blend_shapes/Eye_Left_Left = 0.297788 @@ -119,30 +113,31 @@ blend_shapes/mouthPressRight = 0.0310566 blend_shapes/mouthStretchLeft = 0.0145674 blend_shapes/mouthStretchRight = 0.00253638 -[node name="GroundRing" type="MeshInstance3D" parent="Chan/XRBodyModifier3D"] +[node name="XRBodyModifier3D" type="XRBodyModifier3D" parent="Chan/ChanAvatar/Test-Chan/Armature/Skeleton3D" index="2"] +body_tracker = &"/vmc/body_tracker" + +[node name="XRFaceModifier3D" type="XRFaceModifier3D" parent="Chan/ChanAvatar"] +face_tracker = &"/vmc/face_tracker" +target = NodePath("../Test-Chan/Armature/Skeleton3D/Body") + +[node name="GroundRing" type="MeshInstance3D" parent="Chan/ChanAvatar"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0) mesh = SubResource("TorusMesh_rbtmk") skeleton = NodePath("") -[node name="Forward" type="MeshInstance3D" parent="Chan/XRBodyModifier3D/GroundRing"] +[node name="Forward" type="MeshInstance3D" parent="Chan/ChanAvatar/GroundRing"] transform = Transform3D(1, -8.74228e-08, -8.74228e-08, 8.74228e-08, -4.37114e-08, 1, -8.74228e-08, -1, -4.37114e-08, -5.96046e-08, 0, -0.6) mesh = SubResource("SphereMesh_t4i7x") [node name="Kun" type="Node3D" parent="."] transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0.6, 0, 0) -[node name="XRFaceModifier3D" type="XRFaceModifier3D" parent="Kun"] -face_tracker = &"/vmc/head" -target = NodePath("../XRBodyModifier3D/Test-Kun/Armature/Skeleton3D/Body") +[node name="KunAvatar" type="XRNode3D" parent="Kun"] +tracker = &"/vmc/body_tracker" -[node name="XRBodyModifier3D" type="XRBodyModifier3D" parent="Kun"] -body_tracker = &"/vmc/body" -target = NodePath("Test-Kun/Armature/Skeleton3D") +[node name="Test-Kun" parent="Kun/KunAvatar" instance=ExtResource("2_67k0v")] -[node name="Test-Kun" parent="Kun/XRBodyModifier3D" instance=ExtResource("2_67k0v")] -unique_name_in_owner = true - -[node name="Body" parent="Kun/XRBodyModifier3D/Test-Kun/Armature/Skeleton3D" index="0"] +[node name="Body" parent="Kun/KunAvatar/Test-Kun/Armature/Skeleton3D" index="0"] blend_shapes/Cheek_Puff_Left = 1.28996e-05 blend_shapes/Cheek_Puff_Right = 1.28996e-05 blend_shapes/Eye_Left_Left = 0.297788 @@ -185,12 +180,19 @@ blend_shapes/mouthPressRight = 0.0310566 blend_shapes/mouthStretchLeft = 0.0145674 blend_shapes/mouthStretchRight = 0.00253638 -[node name="GroundRing" type="MeshInstance3D" parent="Kun/XRBodyModifier3D"] +[node name="XRBodyModifier3D" type="XRBodyModifier3D" parent="Kun/KunAvatar/Test-Kun/Armature/Skeleton3D" index="2"] +body_tracker = &"/vmc/body_tracker" + +[node name="XRFaceModifier3D" type="XRFaceModifier3D" parent="Kun/KunAvatar"] +face_tracker = &"/vmc/face_tracker" +target = NodePath("../Test-Kun/Armature/Skeleton3D/Body") + +[node name="GroundRing" type="MeshInstance3D" parent="Kun/KunAvatar"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0) mesh = SubResource("TorusMesh_rbtmk") skeleton = NodePath("") -[node name="Forward" type="MeshInstance3D" parent="Kun/XRBodyModifier3D/GroundRing"] +[node name="Forward" type="MeshInstance3D" parent="Kun/KunAvatar/GroundRing"] transform = Transform3D(1, -8.74228e-08, -8.74228e-08, 8.74228e-08, -4.37114e-08, 1, -8.74228e-08, -1, -4.37114e-08, -5.96046e-08, 0, -0.6) mesh = SubResource("SphereMesh_t4i7x") @@ -262,5 +264,5 @@ value = 1.0 [connection signal="value_changed" from="PanelContainer/MarginContainer/HBoxContainer/GridContainer/SkeletonSpinBox" to="." method="_on_skeleton_spin_box_value_changed"] [connection signal="value_changed" from="PanelContainer/MarginContainer/HBoxContainer/GridContainer/WorldSpinBox" to="." method="_on_world_spin_box_value_changed"] -[editable path="Chan/XRBodyModifier3D/Test-Chan"] -[editable path="Kun/XRBodyModifier3D/Test-Kun"] +[editable path="Chan/ChanAvatar/Test-Chan"] +[editable path="Kun/KunAvatar/Test-Kun"] diff --git a/docs/enable_plugin.png b/docs/enable_plugin.png index e7199bc..31dec7c 100644 Binary files a/docs/enable_plugin.png and b/docs/enable_plugin.png differ diff --git a/docs/plugin_settings.png b/docs/plugin_settings.png index 84989ef..ca693fe 100644 Binary files a/docs/plugin_settings.png and b/docs/plugin_settings.png differ diff --git a/docs/xrbodymodifier3d.png b/docs/xrbodymodifier3d.png index 9245d38..2bfec73 100644 Binary files a/docs/xrbodymodifier3d.png and b/docs/xrbodymodifier3d.png differ diff --git a/docs/xrfacemodifier3d.png b/docs/xrfacemodifier3d.png index ec15695..5f1a030 100644 Binary files a/docs/xrfacemodifier3d.png and b/docs/xrfacemodifier3d.png differ diff --git a/docs/xrnode3d.png b/docs/xrnode3d.png new file mode 100644 index 0000000..456b3b0 Binary files /dev/null and b/docs/xrnode3d.png differ