From 232653429669241e4108823994da645600841ede Mon Sep 17 00:00:00 2001 From: Nitwel Date: Thu, 14 Dec 2023 00:03:03 +0100 Subject: [PATCH] update to latest xr tools --- addons/godot-xr-tools/VERSIONS.md | 14 + .../misc/Hold trigger to continue.png.import | 2 +- .../assets/misc/progress_bar.png.import | 2 +- .../godot-xr-tools/audio/surface_audio.tscn | 6 +- .../editor/icons/audio.svg.import | 2 +- .../editor/icons/body.svg.import | 2 +- .../editor/icons/foot.svg.import | 2 +- .../editor/icons/function.svg.import | 2 +- .../editor/icons/hand.svg.import | 2 +- .../editor/icons/movement_provider.svg.import | 2 +- .../editor/icons/node.svg.import | 2 +- addons/godot-xr-tools/effects/vignette.tscn | 3 +- .../functions/function_pickup.gd | 3 +- .../functions/function_pickup.tscn | 1 + .../functions/function_pose_detector.gd | 7 + .../functions/movement_climb.gd | 14 + .../functions/movement_grapple.gd | 32 +- .../godot-xr-tools/functions/movement_jog.gd | 156 ++++++ .../functions/movement_jog.tscn | 6 + .../functions/movement_world_grab.gd | 217 +++++++++ .../functions/movement_world_grab.tscn | 6 + .../animations/left/hand_blend_tree.tres | 2 +- .../animations/right/hand_blend_tree.tres | 2 +- .../animations/animations_hand_l.blend.import | 3 + .../animations/animations_hand_r.blend.import | 3 + .../hands/blend/hand_l.blend.import | 3 + .../hands/blend/hand_r.blend.import | 3 + addons/godot-xr-tools/hands/collision_hand.gd | 5 +- addons/godot-xr-tools/hands/hand.gd | 146 +++++- .../godot-xr-tools/hands/hand_physics_bone.gd | 8 + .../hands/model/Hand_Glove_L.gltf.import | 4 +- .../hands/model/Hand_Glove_R.gltf.import | 4 +- .../hands/model/Hand_Glove_low_L.gltf.import | 4 +- .../hands/model/Hand_Glove_low_R.gltf.import | 4 +- .../hands/model/Hand_Nails_L.gltf.import | 4 +- .../hands/model/Hand_Nails_R.gltf.import | 4 +- .../hands/model/Hand_Nails_low_L.gltf.import | 4 +- .../hands/model/Hand_Nails_low_R.gltf.import | 4 +- .../hands/model/Hand_low_L.gltf.import | 4 +- .../hands/model/Hand_low_R.gltf.import | 4 +- .../hands/model/hand_l.gltf.import | 4 +- .../hands/model/hand_r.gltf.import | 4 +- .../scenes/collision/collision_hand_left.tscn | 5 +- .../collision/collision_hand_right.tscn | 5 +- .../scenes/highpoly/left_fullglove_hand.tscn | 4 +- .../highpoly/left_fullglove_physics_hand.tscn | 4 +- .../hands/scenes/highpoly/left_hand.tscn | 28 +- .../scenes/highpoly/left_physics_hand.tscn | 4 +- .../highpoly/left_physics_tac_glove.tscn | 4 +- .../hands/scenes/highpoly/left_tac_glove.tscn | 4 +- .../scenes/highpoly/right_fullglove_hand.tscn | 4 +- .../right_fullglove_physics_hand.tscn | 4 +- .../hands/scenes/highpoly/right_hand.tscn | 4 +- .../scenes/highpoly/right_physics_hand.tscn | 4 +- .../highpoly/right_physics_tac_glove.tscn | 4 +- .../scenes/highpoly/right_tac_glove.tscn | 4 +- .../scenes/lowpoly/left_fullglove_low.tscn | 4 +- .../hands/scenes/lowpoly/left_hand_low.tscn | 4 +- .../lowpoly/left_physics_fullglove_low.tscn | 4 +- .../scenes/lowpoly/left_physics_hand_low.tscn | 4 +- .../lowpoly/left_physics_tac_glove_low.tscn | 4 +- .../scenes/lowpoly/left_tac_glove_low.tscn | 4 +- .../scenes/lowpoly/right_fullglove_low.tscn | 4 +- .../hands/scenes/lowpoly/right_hand_low.tscn | 4 +- .../lowpoly/right_physics_fullglove_low.tscn | 4 +- .../lowpoly/right_physics_hand_low.tscn | 4 +- .../lowpoly/right_physics_tac_glove_low.tscn | 4 +- .../scenes/lowpoly/right_tac_glove_low.tscn | 4 +- .../textures/african_baseColor.png.import | 2 +- .../african_realistic_baseColor.png.import | 2 +- .../textures/caucasian_baseColor.png.import | 2 +- .../caucasian_realistic_baseColor.png.import | 2 +- .../cleaning_glove_baseColor.png.import | 2 +- .../glove_african_dark_camo.png.import | 2 +- .../glove_african_green_camo.png.import | 16 +- .../glove_caucasian_dark_camo.png.import | 2 +- .../glove_caucasian_green_camo.png.import | 2 +- .../glove_fingerless_normal.png.import | 2 +- ...less_occlusionRoughnessMetallic.png.import | 2 +- .../hands/textures/glove_normal.png.import | 2 +- ...love_occlusionRoughnessMetallic.png.import | 2 +- .../hands/textures/hands_normal.png.import | 2 +- ...ands_occlusionRoughnessMetallic.png.import | 2 +- .../textures/labglove_baseColor.png.import | 2 +- addons/godot-xr-tools/images/icon.png.import | 2 +- addons/godot-xr-tools/images/ring.png.import | 2 +- .../images/teleport_arrow.png.import | 2 +- .../images/teleport_target.png.import | 2 +- .../interactables/interactable_handle.gd | 12 +- .../interactables/interactable_hinge.tscn | 6 +- .../interactables/interactable_joystick.tscn | 6 +- addons/godot-xr-tools/misc/hold_button.tscn | 2 +- .../misc/vr_common_shader_cache.tscn | 4 +- addons/godot-xr-tools/objects/climbable.gd | 81 +++- .../objects/force_body/force_body.gd | 7 +- .../objects/grab_points/grab.gd | 171 +++++++ .../objects/grab_points/grab_driver.gd | 216 +++++++++ .../objects/grab_points/grab_point.gd | 16 +- .../objects/grab_points/grab_point_hand.gd | 103 +++- .../grab_points/grab_point_redirect.gd | 17 + .../grab_points/grab_point_redirect.tscn | 6 + .../objects/grab_points/grab_point_snap.gd | 30 +- .../objects/grab_points/grabber.gd | 32 ++ .../godot-xr-tools/objects/hand_pose_area.gd | 12 + addons/godot-xr-tools/objects/pickable.gd | 446 ++++++++---------- addons/godot-xr-tools/objects/snap_zone.gd | 10 +- .../objects/viewport_2d_in_3d.gd | 39 +- .../godot-xr-tools/objects/world_grab_area.gd | 64 +++ .../objects/world_grab_area.tscn | 6 + addons/godot-xr-tools/player/player_body.gd | 132 +++++- addons/godot-xr-tools/player/poke/poke.tscn | 7 +- addons/godot-xr-tools/plugin.cfg | 2 +- .../staging/loading_screen.tscn | 4 +- addons/godot-xr-tools/staging/staging.gd | 15 +- addons/godot-xr-tools/staging/staging.tscn | 2 +- .../user_settings/user_settings.gd | 6 +- 116 files changed, 1797 insertions(+), 547 deletions(-) create mode 100644 addons/godot-xr-tools/functions/movement_jog.gd create mode 100644 addons/godot-xr-tools/functions/movement_jog.tscn create mode 100644 addons/godot-xr-tools/functions/movement_world_grab.gd create mode 100644 addons/godot-xr-tools/functions/movement_world_grab.tscn create mode 100644 addons/godot-xr-tools/hands/blend/animations/animations_hand_l.blend.import create mode 100644 addons/godot-xr-tools/hands/blend/animations/animations_hand_r.blend.import create mode 100644 addons/godot-xr-tools/hands/blend/hand_l.blend.import create mode 100644 addons/godot-xr-tools/hands/blend/hand_r.blend.import create mode 100644 addons/godot-xr-tools/objects/grab_points/grab.gd create mode 100644 addons/godot-xr-tools/objects/grab_points/grab_driver.gd create mode 100644 addons/godot-xr-tools/objects/grab_points/grab_point_redirect.gd create mode 100644 addons/godot-xr-tools/objects/grab_points/grab_point_redirect.tscn create mode 100644 addons/godot-xr-tools/objects/grab_points/grabber.gd create mode 100644 addons/godot-xr-tools/objects/world_grab_area.gd create mode 100644 addons/godot-xr-tools/objects/world_grab_area.tscn diff --git a/addons/godot-xr-tools/VERSIONS.md b/addons/godot-xr-tools/VERSIONS.md index 79640a6..6cf6d6f 100644 --- a/addons/godot-xr-tools/VERSIONS.md +++ b/addons/godot-xr-tools/VERSIONS.md @@ -1,3 +1,17 @@ +# 4.3.0 +- Upgraded project to Godot 4.1 as the new minimum version. +- Added reporting of stage load errors. +- Blend player height changes and prevent the player from standing up under a low ceiling. +- **minor-breakage** Added support for swapping held items between hands. +- Added jog-in-place movement provider. +- Added support for grappling on GridMap instances +- **breakage** Added support for two-handed grabbing. +- Added support for snapping hands to grab-points. +- Added support for world-grab movement. +- Fixed editor errors when using hand physics bones. +- Added support for climbable grab-points. +- Added control of keyboard or gamepad inputs to Viewport2Din3D instances. + # 4.2.1 - Fixed snap-zones showing highlight when disabled. - Fixed pickup leaving target highlighted after picking up. diff --git a/addons/godot-xr-tools/assets/misc/Hold trigger to continue.png.import b/addons/godot-xr-tools/assets/misc/Hold trigger to continue.png.import index a7a574d..172212e 100644 --- a/addons/godot-xr-tools/assets/misc/Hold trigger to continue.png.import +++ b/addons/godot-xr-tools/assets/misc/Hold trigger to continue.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dbbxlk5acoxfg" +uid="uid://ocyj01x5mtt7" path.s3tc="res://.godot/imported/Hold trigger to continue.png-ce0a3a4de13c262f7015326bad2cb09d.s3tc.ctex" path.etc2="res://.godot/imported/Hold trigger to continue.png-ce0a3a4de13c262f7015326bad2cb09d.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/assets/misc/progress_bar.png.import b/addons/godot-xr-tools/assets/misc/progress_bar.png.import index 97d88ca..45517bb 100644 --- a/addons/godot-xr-tools/assets/misc/progress_bar.png.import +++ b/addons/godot-xr-tools/assets/misc/progress_bar.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://b77u06jwo4l5y" +uid="uid://clbtsf0ahb3fm" path.s3tc="res://.godot/imported/progress_bar.png-2ef3cbffca173889900be004fdeb1700.s3tc.ctex" path.etc2="res://.godot/imported/progress_bar.png-2ef3cbffca173889900be004fdeb1700.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/audio/surface_audio.tscn b/addons/godot-xr-tools/audio/surface_audio.tscn index ef59c58..81fdcb9 100644 --- a/addons/godot-xr-tools/audio/surface_audio.tscn +++ b/addons/godot-xr-tools/audio/surface_audio.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=2 format=3 uid="uid://cggrrnkgc7ufo"] +[gd_scene load_steps=2 format=2] -[ext_resource type="Script" path="res://addons/godot-xr-tools/audio/surface_audio.gd" id="1"] +[ext_resource path="res://addons/godot-xr-tools/audio/surface_audio.gd" type="Script" id=1] [node name="SurfaceAudio" type="Node"] -script = ExtResource("1") +script = ExtResource( 1 ) diff --git a/addons/godot-xr-tools/editor/icons/audio.svg.import b/addons/godot-xr-tools/editor/icons/audio.svg.import index 8b393e0..6b68a74 100644 --- a/addons/godot-xr-tools/editor/icons/audio.svg.import +++ b/addons/godot-xr-tools/editor/icons/audio.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dd81tkixfsdrw" +uid="uid://dhnfbf4p0s74" path="res://.godot/imported/audio.svg-20d7f0b624a1b2ef54f1b4d12970c8d0.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/editor/icons/body.svg.import b/addons/godot-xr-tools/editor/icons/body.svg.import index 4ac6b16..787be50 100644 --- a/addons/godot-xr-tools/editor/icons/body.svg.import +++ b/addons/godot-xr-tools/editor/icons/body.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://8krthn43snhi" +uid="uid://cyg33jxco0rh6" path="res://.godot/imported/body.svg-324e141d452c32f3136ca97c338025b4.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/editor/icons/foot.svg.import b/addons/godot-xr-tools/editor/icons/foot.svg.import index ce738ec..15c8f09 100644 --- a/addons/godot-xr-tools/editor/icons/foot.svg.import +++ b/addons/godot-xr-tools/editor/icons/foot.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://cqjrs44rcon7m" +uid="uid://bfkcd3fkyahqu" path="res://.godot/imported/foot.svg-9e361563e010aa07be49bfb25fdb6639.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/editor/icons/function.svg.import b/addons/godot-xr-tools/editor/icons/function.svg.import index 4c22e49..2e4ed63 100644 --- a/addons/godot-xr-tools/editor/icons/function.svg.import +++ b/addons/godot-xr-tools/editor/icons/function.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://b3tktceuqduij" +uid="uid://b5vxil50s0ofi" path="res://.godot/imported/function.svg-52c5f936037e0f38a4da2b1e16ae67fe.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/editor/icons/hand.svg.import b/addons/godot-xr-tools/editor/icons/hand.svg.import index 6fce11a..c59f938 100644 --- a/addons/godot-xr-tools/editor/icons/hand.svg.import +++ b/addons/godot-xr-tools/editor/icons/hand.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://duxf7oimwxodc" +uid="uid://beko1qhyybx7e" path="res://.godot/imported/hand.svg-a05486d804ef16320d6cf54e06292b8f.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/editor/icons/movement_provider.svg.import b/addons/godot-xr-tools/editor/icons/movement_provider.svg.import index b594b35..65c9b74 100644 --- a/addons/godot-xr-tools/editor/icons/movement_provider.svg.import +++ b/addons/godot-xr-tools/editor/icons/movement_provider.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bj0d07w1a7blg" +uid="uid://04fn15h4x333" path="res://.godot/imported/movement_provider.svg-3c994cf0a3775c20f333be563d69fbf8.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/editor/icons/node.svg.import b/addons/godot-xr-tools/editor/icons/node.svg.import index 234a356..87553f5 100644 --- a/addons/godot-xr-tools/editor/icons/node.svg.import +++ b/addons/godot-xr-tools/editor/icons/node.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://xtrkapd7af3l" +uid="uid://b6gwa6o27pbry" path="res://.godot/imported/node.svg-37d53571b4a4459efefcc791c5402b4f.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/effects/vignette.tscn b/addons/godot-xr-tools/effects/vignette.tscn index 304a637..3ac97d3 100644 --- a/addons/godot-xr-tools/effects/vignette.tscn +++ b/addons/godot-xr-tools/effects/vignette.tscn @@ -6,11 +6,10 @@ [sub_resource type="ArrayMesh" id="ArrayMesh_yyajy"] _surfaces = [{ "aabb": AABB(-2, -2, 0, 4, 4, 1e-05), -"format": 34359742465, +"format": 4097, "index_count": 192, "index_data": PackedByteArray(32, 0, 33, 0, 1, 0, 32, 0, 1, 0, 0, 0, 33, 0, 34, 0, 2, 0, 33, 0, 2, 0, 1, 0, 34, 0, 35, 0, 3, 0, 34, 0, 3, 0, 2, 0, 35, 0, 36, 0, 4, 0, 35, 0, 4, 0, 3, 0, 36, 0, 37, 0, 5, 0, 36, 0, 5, 0, 4, 0, 37, 0, 38, 0, 6, 0, 37, 0, 6, 0, 5, 0, 38, 0, 39, 0, 7, 0, 38, 0, 7, 0, 6, 0, 39, 0, 40, 0, 8, 0, 39, 0, 8, 0, 7, 0, 40, 0, 41, 0, 9, 0, 40, 0, 9, 0, 8, 0, 41, 0, 42, 0, 10, 0, 41, 0, 10, 0, 9, 0, 42, 0, 43, 0, 11, 0, 42, 0, 11, 0, 10, 0, 43, 0, 44, 0, 12, 0, 43, 0, 12, 0, 11, 0, 44, 0, 45, 0, 13, 0, 44, 0, 13, 0, 12, 0, 45, 0, 46, 0, 14, 0, 45, 0, 14, 0, 13, 0, 46, 0, 47, 0, 15, 0, 46, 0, 15, 0, 14, 0, 47, 0, 48, 0, 16, 0, 47, 0, 16, 0, 15, 0, 48, 0, 49, 0, 17, 0, 48, 0, 17, 0, 16, 0, 49, 0, 50, 0, 18, 0, 49, 0, 18, 0, 17, 0, 50, 0, 51, 0, 19, 0, 50, 0, 19, 0, 18, 0, 51, 0, 52, 0, 20, 0, 51, 0, 20, 0, 19, 0, 52, 0, 53, 0, 21, 0, 52, 0, 21, 0, 20, 0, 53, 0, 54, 0, 22, 0, 53, 0, 22, 0, 21, 0, 54, 0, 55, 0, 23, 0, 54, 0, 23, 0, 22, 0, 55, 0, 56, 0, 24, 0, 55, 0, 24, 0, 23, 0, 56, 0, 57, 0, 25, 0, 56, 0, 25, 0, 24, 0, 57, 0, 58, 0, 26, 0, 57, 0, 26, 0, 25, 0, 58, 0, 59, 0, 27, 0, 58, 0, 27, 0, 26, 0, 59, 0, 60, 0, 28, 0, 59, 0, 28, 0, 27, 0, 60, 0, 61, 0, 29, 0, 60, 0, 29, 0, 28, 0, 61, 0, 62, 0, 30, 0, 61, 0, 30, 0, 29, 0, 62, 0, 63, 0, 31, 0, 62, 0, 31, 0, 30, 0, 63, 0, 32, 0, 0, 0, 63, 0, 0, 0, 31, 0), "primitive": 3, -"uv_scale": Vector4(0, 0, 0, 0), "vertex_count": 64, "vertex_data": PackedByteArray(0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 190, 20, 123, 63, 194, 197, 71, 190, 0, 0, 0, 0, 94, 131, 108, 63, 22, 239, 195, 190, 0, 0, 0, 0, 49, 219, 84, 63, 218, 57, 14, 191, 0, 0, 0, 0, 243, 4, 53, 63, 243, 4, 53, 191, 0, 0, 0, 0, 218, 57, 14, 63, 49, 219, 84, 191, 0, 0, 0, 0, 21, 239, 195, 62, 94, 131, 108, 191, 0, 0, 0, 0, 196, 197, 71, 62, 190, 20, 123, 191, 0, 0, 0, 0, 46, 189, 59, 179, 0, 0, 128, 191, 0, 0, 0, 0, 194, 197, 71, 190, 190, 20, 123, 191, 0, 0, 0, 0, 20, 239, 195, 190, 95, 131, 108, 191, 0, 0, 0, 0, 217, 57, 14, 191, 50, 219, 84, 191, 0, 0, 0, 0, 243, 4, 53, 191, 243, 4, 53, 191, 0, 0, 0, 0, 50, 219, 84, 191, 217, 57, 14, 191, 0, 0, 0, 0, 94, 131, 108, 191, 23, 239, 195, 190, 0, 0, 0, 0, 191, 20, 123, 191, 193, 197, 71, 190, 0, 0, 0, 0, 0, 0, 128, 191, 46, 189, 187, 51, 0, 0, 0, 0, 191, 20, 123, 191, 189, 197, 71, 62, 0, 0, 0, 0, 94, 131, 108, 191, 21, 239, 195, 62, 0, 0, 0, 0, 48, 219, 84, 191, 219, 57, 14, 63, 0, 0, 0, 0, 244, 4, 53, 191, 242, 4, 53, 63, 0, 0, 0, 0, 221, 57, 14, 191, 47, 219, 84, 63, 0, 0, 0, 0, 26, 239, 195, 190, 94, 131, 108, 63, 0, 0, 0, 0, 198, 197, 71, 190, 190, 20, 123, 63, 0, 0, 0, 0, 46, 222, 76, 50, 0, 0, 128, 63, 0, 0, 0, 0, 200, 197, 71, 62, 190, 20, 123, 63, 0, 0, 0, 0, 27, 239, 195, 62, 93, 131, 108, 63, 0, 0, 0, 0, 215, 57, 14, 63, 51, 219, 84, 63, 0, 0, 0, 0, 242, 4, 53, 63, 245, 4, 53, 63, 0, 0, 0, 0, 49, 219, 84, 63, 219, 57, 14, 63, 0, 0, 0, 0, 95, 131, 108, 63, 21, 239, 195, 62, 0, 0, 0, 0, 191, 20, 123, 63, 188, 197, 71, 62, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 190, 20, 251, 63, 194, 197, 199, 190, 0, 0, 0, 0, 94, 131, 236, 63, 22, 239, 67, 191, 0, 0, 0, 0, 49, 219, 212, 63, 218, 57, 142, 191, 0, 0, 0, 0, 243, 4, 181, 63, 243, 4, 181, 191, 0, 0, 0, 0, 218, 57, 142, 63, 49, 219, 212, 191, 0, 0, 0, 0, 21, 239, 67, 63, 94, 131, 236, 191, 0, 0, 0, 0, 196, 197, 199, 62, 190, 20, 251, 191, 0, 0, 0, 0, 46, 189, 187, 179, 0, 0, 0, 192, 0, 0, 0, 0, 194, 197, 199, 190, 190, 20, 251, 191, 0, 0, 0, 0, 20, 239, 67, 191, 95, 131, 236, 191, 0, 0, 0, 0, 217, 57, 142, 191, 50, 219, 212, 191, 0, 0, 0, 0, 243, 4, 181, 191, 243, 4, 181, 191, 0, 0, 0, 0, 50, 219, 212, 191, 217, 57, 142, 191, 0, 0, 0, 0, 94, 131, 236, 191, 23, 239, 67, 191, 0, 0, 0, 0, 191, 20, 251, 191, 193, 197, 199, 190, 0, 0, 0, 0, 0, 0, 0, 192, 46, 189, 59, 52, 0, 0, 0, 0, 191, 20, 251, 191, 189, 197, 199, 62, 0, 0, 0, 0, 94, 131, 236, 191, 21, 239, 67, 63, 0, 0, 0, 0, 48, 219, 212, 191, 219, 57, 142, 63, 0, 0, 0, 0, 244, 4, 181, 191, 242, 4, 181, 63, 0, 0, 0, 0, 221, 57, 142, 191, 47, 219, 212, 63, 0, 0, 0, 0, 26, 239, 67, 191, 94, 131, 236, 63, 0, 0, 0, 0, 198, 197, 199, 190, 190, 20, 251, 63, 0, 0, 0, 0, 46, 222, 204, 50, 0, 0, 0, 64, 0, 0, 0, 0, 200, 197, 199, 62, 190, 20, 251, 63, 0, 0, 0, 0, 27, 239, 67, 63, 93, 131, 236, 63, 0, 0, 0, 0, 215, 57, 142, 63, 51, 219, 212, 63, 0, 0, 0, 0, 242, 4, 181, 63, 245, 4, 181, 63, 0, 0, 0, 0, 49, 219, 212, 63, 219, 57, 142, 63, 0, 0, 0, 0, 95, 131, 236, 63, 21, 239, 67, 63, 0, 0, 0, 0, 191, 20, 251, 63, 188, 197, 199, 62, 0, 0, 0, 0) }] diff --git a/addons/godot-xr-tools/functions/function_pickup.gd b/addons/godot-xr-tools/functions/function_pickup.gd index 93c4c3d..c042e29 100644 --- a/addons/godot-xr-tools/functions/function_pickup.gd +++ b/addons/godot-xr-tools/functions/function_pickup.gd @@ -373,6 +373,7 @@ func drop_object() -> void: # let go of this object picked_up_object.let_go( + self, _velocity_averager.linear_velocity() * impulse_factor, _velocity_averager.angular_velocity()) picked_up_object = null @@ -401,7 +402,7 @@ func _pick_up_object(target: Node3D) -> void: # Pick up our target. Note, target may do instant drop_and_free picked_up_ranged = not _object_in_grab_area.has(target) picked_up_object = target - target.pick_up(self, _controller) + target.pick_up(self) # If object picked up then emit signal if is_instance_valid(picked_up_object): diff --git a/addons/godot-xr-tools/functions/function_pickup.tscn b/addons/godot-xr-tools/functions/function_pickup.tscn index 9414a6d..dad436d 100644 --- a/addons/godot-xr-tools/functions/function_pickup.tscn +++ b/addons/godot-xr-tools/functions/function_pickup.tscn @@ -4,3 +4,4 @@ [node name="FunctionPickup" type="Node3D"] script = ExtResource("1") +grab_collision_mask = 327684 diff --git a/addons/godot-xr-tools/functions/function_pose_detector.gd b/addons/godot-xr-tools/functions/function_pose_detector.gd index e399c8d..5a914d5 100644 --- a/addons/godot-xr-tools/functions/function_pose_detector.gd +++ b/addons/godot-xr-tools/functions/function_pose_detector.gd @@ -81,11 +81,15 @@ func _on_area_entered(area : Area3D) -> void: pose_area, pose_area.pose_priority, pose_area.left_pose) + # Disable grabpoints in this pose_area + pose_area.disable_grab_points() elif _controller.tracker == "right_hand" and pose_area.right_pose: _hand.add_pose_override( pose_area, pose_area.pose_priority, pose_area.right_pose) + # Disable grabpoints in this pose_area + pose_area.disable_grab_points() ## Signal handler called when this XRToolsFunctionPoseArea leaves an area @@ -97,3 +101,6 @@ func _on_area_exited(area : Area3D) -> void: # Remove any overrides set from this hand-pose area _hand.remove_pose_override(pose_area) + + # Enable previously disabled grabpoints + pose_area.enable_grab_points() diff --git a/addons/godot-xr-tools/functions/movement_climb.gd b/addons/godot-xr-tools/functions/movement_climb.gd index 2916c25..c4bc91f 100644 --- a/addons/godot-xr-tools/functions/movement_climb.gd +++ b/addons/godot-xr-tools/functions/movement_climb.gd @@ -68,6 +68,12 @@ var _dominant : Node3D # Right controller @onready var _right_controller := XRHelpers.get_right_controller(self) +# Left collision hand +@onready var _left_hand := XRToolsHand.find_left(self) + +# Right collision hand +@onready var _right_hand := XRToolsHand.find_right(self) + # Left collision hand @onready var _left_collision_hand := XRToolsCollisionHand.find_left(self) @@ -205,6 +211,8 @@ func _on_left_picked_up(what : Node3D) -> void: # If collision hands present then target the handle if _left_collision_hand: _left_collision_hand.add_target_override(_left_handle, 0) + elif _left_hand: + _left_hand.add_target_override(_left_handle, 0) ## Handler for right controller picked up @@ -225,6 +233,8 @@ func _on_right_picked_up(what : Node3D) -> void: # If collision hands present then target the handle if _right_collision_hand: _right_collision_hand.add_target_override(_right_handle, 0) + elif _right_hand: + _right_hand.add_target_override(_right_handle, 0) ## Handler for left controller dropped @@ -232,6 +242,8 @@ func _on_left_dropped() -> void: # If collision hands present then clear handle target if _left_collision_hand: _left_collision_hand.remove_target_override(_left_handle) + if _left_hand: + _left_hand.remove_target_override(_left_handle) # Release handle and transfer dominance _left_handle = null @@ -243,6 +255,8 @@ func _on_right_dropped() -> void: # If collision hands present then clear handle target if _right_collision_hand: _right_collision_hand.remove_target_override(_right_handle) + if _right_hand: + _right_hand.remove_target_override(_right_handle) # Release handle and transfer dominance _right_handle = null diff --git a/addons/godot-xr-tools/functions/movement_grapple.gd b/addons/godot-xr-tools/functions/movement_grapple.gd index 3982e47..bc90490 100644 --- a/addons/godot-xr-tools/functions/movement_grapple.gd +++ b/addons/godot-xr-tools/functions/movement_grapple.gd @@ -117,13 +117,21 @@ func _ready(): _line.hide() -# Update grapple display objects -func _process(_delta: float): +# Update the grappling line and target +func _physics_process(_delta : float): # Skip if running in the editor if Engine.is_editor_hint(): return - # Update grapple line + # If pointing grappler at target then show the target + if enabled and not is_active and _is_raycast_valid(): + _grapple_target.global_transform.origin = _grapple_raycast.get_collision_point() + _grapple_target.global_transform = _grapple_target.global_transform.orthonormalized() + _grapple_target.visible = true + else: + _grapple_target.visible = false + + # If actively grappling then update and show the grappling line if is_active: var line_length := (hook_point - _controller.global_transform.origin).length() _line_helper.look_at(hook_point, Vector3.UP) @@ -133,14 +141,6 @@ func _process(_delta: float): else: _line.visible = false - # Update grapple target - if enabled and !is_active and _is_raycast_valid(): - _grapple_target.global_transform.origin = _grapple_raycast.get_collision_point() - _grapple_target.global_transform = _grapple_target.global_transform.orthonormalized() - _grapple_target.visible = true - else: - _grapple_target.visible = false - # Perform grapple movement func physics_movement(delta: float, player_body: XRToolsPlayerBody, disabled: bool): @@ -220,14 +220,12 @@ func _set_grappling(active: bool) -> void: # Test if the raycast is striking a valid target func _is_raycast_valid() -> bool: - # Fail if raycast not colliding - if not _grapple_raycast.is_colliding(): + # Test if the raycast hit a collider + var target = _grapple_raycast.get_collider() + if not is_instance_valid(target): return false - # Get the target of the raycast - var target : CollisionObject3D = _grapple_raycast.get_collider() - - # Check tartget layer + # Check collider layer return true if target.collision_layer & grapple_enable_mask else false diff --git a/addons/godot-xr-tools/functions/movement_jog.gd b/addons/godot-xr-tools/functions/movement_jog.gd new file mode 100644 index 0000000..58699d2 --- /dev/null +++ b/addons/godot-xr-tools/functions/movement_jog.gd @@ -0,0 +1,156 @@ +@tool +class_name XRToolsMovementJog +extends XRToolsMovementProvider + + +## XR Tools Movement Provider for Jog Movement +## +## This script provides jog-in-place movement for the player. This script +## works with the [XRToolsPlayerBody] attached to the players [XROrigin3D]. +## +## The implementation uses filtering of the controller Y velocities to measure +## the approximate frequency of jog arm-swings; and uses that to +## switch between stopped, slow, and fast movement speeds. + + +## Speed mode enumeration +enum SpeedMode { + STOPPED, ## Not jogging + SLOW, ## Jogging slowly + FAST ## Jogging fast +} + + +## Jog arm-swing frequency in Hz to trigger slow movement +const JOG_SLOW_FREQ := 3.5 + +## Jog arm-swing frequency in Hz to trigger fast movement +const JOG_FAST_FREQ := 5.5 + + +## Movement provider order +@export var order : int = 10 + +## Slow jogging speed in meters-per-second +@export var slow_speed : float = 1.0 + +## Fast jogging speed in meters-per-second +@export var fast_speed : float = 3.0 + + +# Jog arm-swing "stroke" detector "confidence-hat" signal +var _conf_hat := 0.0 + +# Current jog arm-swing "stroke" duration +var _current_stroke := 0.0 + +# Last jog arm-swing "stroke" total duration +var _last_stroke := 0.0 + +# Current jog-speed mode +var _speed_mode := SpeedMode.STOPPED + + +# Left controller +@onready var _left_controller := XRHelpers.get_left_controller(self) + +# Right controller +@onready var _right_controller := XRHelpers.get_right_controller(self) + + +# Add support for is_xr_class on XRTools classes +func is_xr_class(name : String) -> bool: + return name == "XRToolsMovementJog" or super(name) + + +# Perform jump movement +func physics_movement(delta: float, player_body: XRToolsPlayerBody, _disabled: bool): + # Skip if the either controller is inactive + if !_left_controller.get_is_active() or !_right_controller.get_is_active(): + _speed_mode = SpeedMode.STOPPED + return + + # Get the arm-swing stroke frequency in Hz + var freq := _get_stroke_frequency(delta) + + # Transition between stopped/slow/fast speed-modes based on thresholds. + # This thresholding has some hysteresis to make speed changes smoother. + if freq == 0: + _speed_mode = SpeedMode.STOPPED + elif freq < JOG_SLOW_FREQ: + _speed_mode = min(_speed_mode, SpeedMode.SLOW) + elif freq < JOG_FAST_FREQ: + _speed_mode = max(_speed_mode, SpeedMode.SLOW) + else: + _speed_mode = SpeedMode.FAST + + # Pick the speed in meters-per-second based on the current speed-mode. + var speed := 0.0 + if _speed_mode == SpeedMode.SLOW: + speed = slow_speed + elif _speed_mode == SpeedMode.FAST: + speed = fast_speed + + # Contribute to the player body speed - with clamping to the maximum speed + player_body.ground_control_velocity.y += speed + var length := player_body.ground_control_velocity.length() + if length > fast_speed: + player_body.ground_control_velocity *= fast_speed / length + + +# Get the frequency of the last arm-swing "stroke" in Hz. +func _get_stroke_frequency(delta : float) -> float: + # Get the controller velocities + var vl := _left_controller.get_pose().linear_velocity.y + var vr := _right_controller.get_pose().linear_velocity.y + + # Calculate the arm-swing "stroke" confidence. This is done by multiplying + # the left and right controller vertical velocities. As these velocities + # are highly anti-correlated while "jogging" the result is a confidence + # signal with a high "peak" on every jog "stroke". + var conf := vl * -vr + + # Test for the confidence valley between strokes. This is used to signal + # when to measure the duration between strokes. + var valley := conf < _conf_hat + + # Update confidence-hat. The confidence-hat signal has a fast-rise and + # slow-decay. Rising with each jog arm-swing "stroke" and then taking time + # to decay. The magnitude of the "confidence-hat" can be used as a good + # indicator of when the user is jogging; and the difference between the + # "confidence" and "confidence-hat" signals can be used to identify the + # duration of a jog arm-swing "stroke". + if valley: + # Gently decay when in the confidence valley. + _conf_hat = lerpf(_conf_hat, 0.0, delta * 2) + else: + # Quickly ramp confidence-hat to confidence + _conf_hat = lerpf(_conf_hat, conf, delta * 20) + + # If the "confidence-hat" signal is too low then the user is not jogging. + # The stroke date-data is cleared and a stroke frequency of 0Hz is returned. + if _conf_hat < 0.5: + _current_stroke = 0.0 + _last_stroke = 0.0 + return 0.0 + + # Track the jog arm-swing "stroke" duration. + if valley: + # In the valley between jog arm-swing "strokes" + _current_stroke += delta + elif _current_stroke > 0.1: + # Save the measured jog arm-swing "stroke" duration. + _last_stroke = _current_stroke + _current_stroke = 0.0 + + # If no previous jog arm-swing "stroke" duration to report, so return 0Hz. + if _last_stroke < 0.1: + return 0.0 + + # If the current jog arm-swing "stroke" is taking longer (slower) than 2Hz + # then truncate to 0Hz. + if _current_stroke > 0.75: + return 0.0 + + # Return the last jog arm-swing "stroke" in Hz. + return 1.0 / _last_stroke diff --git a/addons/godot-xr-tools/functions/movement_jog.tscn b/addons/godot-xr-tools/functions/movement_jog.tscn new file mode 100644 index 0000000..aebadf6 --- /dev/null +++ b/addons/godot-xr-tools/functions/movement_jog.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://chcuj3jysipk8"] + +[ext_resource type="Script" path="res://addons/godot-xr-tools/functions/movement_jog.gd" id="1_k4cao"] + +[node name="MovementJog" type="Node" groups=["movement_providers"]] +script = ExtResource("1_k4cao") diff --git a/addons/godot-xr-tools/functions/movement_world_grab.gd b/addons/godot-xr-tools/functions/movement_world_grab.gd new file mode 100644 index 0000000..4597649 --- /dev/null +++ b/addons/godot-xr-tools/functions/movement_world_grab.gd @@ -0,0 +1,217 @@ +@tool +class_name XRToolsMovementWorldGrab +extends XRToolsMovementProvider + + +## XR Tools Movement Provider for World-Grab +## +## This script provides world-grab movement for the player. To add world-grab +## support, the player must also have [XRToolsFunctionPickup] nodes attached +## to the left and right controllers, and an [XRToolsPlayerBody] under the +## [XROrigin3D]. +## +## World-Grab areas inherit from the world_grab_area scene, or be [Area3D] +## nodes with the [XRToolsWorldGrabArea] script attached to them. + + +## Signal invoked when the player starts world-grab movement +signal player_world_grab_start + +## Signal invoked when the player ends world-grab movement +signal player_world_grab_end + + +## Movement provider order +@export var order : int = 15 + +## Smallest world scale +@export var world_scale_min := 0.5 + +## Largest world scale +@export var world_scale_max := 2.0 + + +# Left world-grab handle +var _left_handle : Node3D + +# Right world-grab handle +var _right_handle : Node3D + + +# Left pickup node +@onready var _left_pickup_node := XRToolsFunctionPickup.find_left(self) + +# Right pickup node +@onready var _right_pickup_node := XRToolsFunctionPickup.find_right(self) + +# Left controller +@onready var _left_controller := XRHelpers.get_left_controller(self) + +# Right controller +@onready var _right_controller := XRHelpers.get_right_controller(self) + + +# Add support for is_xr_class on XRTools classes +func is_xr_class(name : String) -> bool: + return name == "XRToolsMovementGrabWorld" or super(name) + + +# Called when the node enters the scene tree for the first time. +func _ready(): + # In Godot 4 we must now manually call our super class ready function + super() + + # Do not initialise if in the editor + if Engine.is_editor_hint(): + return + + # Connect pickup funcitons + if _left_pickup_node.connect("has_picked_up", _on_left_picked_up): + push_error("Unable to connect left picked up signal") + if _right_pickup_node.connect("has_picked_up", _on_right_picked_up): + push_error("Unable to connect right picked up signal") + if _left_pickup_node.connect("has_dropped", _on_left_dropped): + push_error("Unable to connect left dropped signal") + if _right_pickup_node.connect("has_dropped", _on_right_dropped): + push_error("Unable to connect right dropped signal") + + +## Perform player physics movement +func physics_movement(delta: float, player_body: XRToolsPlayerBody, disabled: bool): + # Disable world-grab movement if requested + if disabled or !enabled: + _set_world_grab_moving(false) + return + + # Always set velocity to zero if enabled + player_body.velocity = Vector3.ZERO + + # Check for world-grab handles being deleted while held + if not is_instance_valid(_left_handle): + _left_handle = null + if not is_instance_valid(_right_handle): + _right_handle = null + + # Disable world-grab movement if not holding the world + if not _left_handle and not _right_handle: + _set_world_grab_moving(false) + return + + # World grabbed + _set_world_grab_moving(true) + + # Handle world-grab movement + var offset := Vector3.ZERO + if _left_handle and not _right_handle: + # Left-hand movement only + var left_pickup_pos := _left_controller.global_position + var left_grab_pos := _left_handle.global_position + offset = left_pickup_pos - left_grab_pos + elif _right_handle and not _left_handle: + # Right-hand movement only + var right_pickup_pos := _right_controller.global_position + var right_grab_pos := _right_handle.global_position + offset = right_pickup_pos - right_grab_pos + else: + # Get the world-grab handle positions + var left_grab_pos := _left_handle.global_position + var right_grab_pos := _right_handle.global_position + var grab_l2r := (right_grab_pos - left_grab_pos).slide(player_body.up_player) + var grab_mid := (left_grab_pos + right_grab_pos) * 0.5 + + # Get the pickup positions + var left_pickup_pos := _left_controller.global_position + var right_pickup_pos := _right_controller.global_position + var pickup_l2r := (right_pickup_pos - left_pickup_pos).slide(player_body.up_player) + var pickup_mid := (left_pickup_pos + right_pickup_pos) * 0.5 + + # Apply rotation + var angle := grab_l2r.signed_angle_to(pickup_l2r, player_body.up_player) + player_body.rotate_player(angle) + + # Apply scale + var new_world_scale := XRServer.world_scale * grab_l2r.length() / pickup_l2r.length() + new_world_scale = clamp(new_world_scale, world_scale_min, world_scale_max) + XRServer.world_scale = new_world_scale + + # Apply offset + offset = pickup_mid - grab_mid + + # Move the player by the offset + var old_position := player_body.global_position + player_body.move_body(-offset / delta) + player_body.velocity = Vector3.ZERO + #player_body.move_and_collide(-offset) + + # Report exclusive motion performed (to bypass gravity) + return true + + +## Start or stop world-grab movement +func _set_world_grab_moving(active: bool) -> void: + # Skip if no change + if active == is_active: + return + + # Update state + is_active = active + + # Handle state change + if is_active: + emit_signal("player_world_grab_start") + else: + emit_signal("player_world_grab_end") + + +## Handler for left controller picked up +func _on_left_picked_up(what : Node3D) -> void: + # Get the world-grab area + var world_grab_area = what as XRToolsWorldGrabArea + if not world_grab_area: + return + + # Get the handle + _left_handle = world_grab_area.get_grab_handle(_left_pickup_node) + if not _left_handle: + return + + +## Handler for right controller picked up +func _on_right_picked_up(what : Node3D) -> void: + # Get the world-grab area + var world_grab_area = what as XRToolsWorldGrabArea + if not world_grab_area: + return + + # Get the handle + _right_handle = world_grab_area.get_grab_handle(_right_pickup_node) + if not _right_handle: + return + + +## Handler for left controller dropped +func _on_left_dropped() -> void: + # Release handle and transfer dominance + _left_handle = null + + +## Handler for righ controller dropped +func _on_right_dropped() -> void: + # Release handle and transfer dominance + _right_handle = null + + +# This method verifies the movement provider has a valid configuration. +func _get_configuration_warnings() -> PackedStringArray: + var warnings := super() + + # Verify the left controller pickup + if !XRToolsFunctionPickup.find_left(self): + warnings.append("Unable to find left XRToolsFunctionPickup node") + + # Verify the right controller pickup + if !XRToolsFunctionPickup.find_right(self): + warnings.append("Unable to find right XRToolsFunctionPickup node") + + # Return warnings + return warnings diff --git a/addons/godot-xr-tools/functions/movement_world_grab.tscn b/addons/godot-xr-tools/functions/movement_world_grab.tscn new file mode 100644 index 0000000..987cc7e --- /dev/null +++ b/addons/godot-xr-tools/functions/movement_world_grab.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://dg3gr6ofd8yx4"] + +[ext_resource type="Script" path="res://addons/godot-xr-tools/functions/movement_world_grab.gd" id="1_0qp8q"] + +[node name="MovementWorldGrab" type="Node" groups=["movement_providers"]] +script = ExtResource("1_0qp8q") diff --git a/addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres b/addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres index a97fbf0..6e05f8b 100644 --- a/addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres +++ b/addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b55738edba8fcdaab47c5e40cf4b900b10c86ea67f9d40dc041f84f4e76ec484 +oid sha256:ec74b5b5948e76d01115d7ff959610515e97aca1c42870f36b4a747f2dc4cb70 size 2416 diff --git a/addons/godot-xr-tools/hands/animations/right/hand_blend_tree.tres b/addons/godot-xr-tools/hands/animations/right/hand_blend_tree.tres index 5bfabca..71ad03f 100644 --- a/addons/godot-xr-tools/hands/animations/right/hand_blend_tree.tres +++ b/addons/godot-xr-tools/hands/animations/right/hand_blend_tree.tres @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3a3e64d9a45c8ab58180b00eae7ed8e306c22686656fca4ed854b87283ed4c09 +oid sha256:46cdd3222390fdf4b7e6f591958bbf30944df088a71cab919ba54a49ace2baf8 size 2424 diff --git a/addons/godot-xr-tools/hands/blend/animations/animations_hand_l.blend.import b/addons/godot-xr-tools/hands/blend/animations/animations_hand_l.blend.import new file mode 100644 index 0000000..8dd0c09 --- /dev/null +++ b/addons/godot-xr-tools/hands/blend/animations/animations_hand_l.blend.import @@ -0,0 +1,3 @@ +[remap] + +importer="keep" diff --git a/addons/godot-xr-tools/hands/blend/animations/animations_hand_r.blend.import b/addons/godot-xr-tools/hands/blend/animations/animations_hand_r.blend.import new file mode 100644 index 0000000..8dd0c09 --- /dev/null +++ b/addons/godot-xr-tools/hands/blend/animations/animations_hand_r.blend.import @@ -0,0 +1,3 @@ +[remap] + +importer="keep" diff --git a/addons/godot-xr-tools/hands/blend/hand_l.blend.import b/addons/godot-xr-tools/hands/blend/hand_l.blend.import new file mode 100644 index 0000000..8dd0c09 --- /dev/null +++ b/addons/godot-xr-tools/hands/blend/hand_l.blend.import @@ -0,0 +1,3 @@ +[remap] + +importer="keep" diff --git a/addons/godot-xr-tools/hands/blend/hand_r.blend.import b/addons/godot-xr-tools/hands/blend/hand_r.blend.import new file mode 100644 index 0000000..8dd0c09 --- /dev/null +++ b/addons/godot-xr-tools/hands/blend/hand_r.blend.import @@ -0,0 +1,3 @@ +[remap] + +importer="keep" diff --git a/addons/godot-xr-tools/hands/collision_hand.gd b/addons/godot-xr-tools/hands/collision_hand.gd index 7adc474..594b276 100644 --- a/addons/godot-xr-tools/hands/collision_hand.gd +++ b/addons/godot-xr-tools/hands/collision_hand.gd @@ -79,8 +79,10 @@ func _ready(): if Engine.is_editor_hint(): return - # Disconnect from parent transform, as we move to it in the physics step + # Disconnect from parent transform as we move to it in the physics step, + # and boost the physics priority above any grab-drivers or hands. top_level = true + process_physics_priority = -90 # Populate nodes _controller = XRTools.find_xr_ancestor(self, "*", "XRController3D") @@ -171,6 +173,7 @@ func _move_to_target(): # Orient the hand then move global_transform.basis = _target.global_transform.basis move_and_slide(_target.global_position - global_position) + force_update_transform() # This function inserts a target override into the overrides list by priority diff --git a/addons/godot-xr-tools/hands/hand.gd b/addons/godot-xr-tools/hands/hand.gd index dafb922..a7b3442 100644 --- a/addons/godot-xr-tools/hands/hand.gd +++ b/addons/godot-xr-tools/hands/hand.gd @@ -41,6 +41,9 @@ var _last_world_scale : float = 1.0 var _controller : XRController3D ## Initial hand transform (from controller) - used for scaling hands +var _initial_transform : Transform3D + +## Current hand transform (from controller) - after scale var _transform : Transform3D ## Hand mesh @@ -64,6 +67,12 @@ var _force_grip := -1.0 ## Force trigger value (< 0 for no force) var _force_trigger := -1.0 +# Sorted stack of TargetOverride +var _target_overrides := [] + +# Current target (controller or override) +var _target : Node3D + ## Pose-override class class PoseOverride: @@ -83,6 +92,20 @@ class PoseOverride: settings = s +## Target-override class +class TargetOverride: + ## Target of the override + var target : Node3D + + ## Target priority + var priority : int + + ## Target-override constructor + func _init(t : Node3D, p : int): + target = t + priority = p + + # Add support for is_xr_class on XRTools classes func is_xr_class(name : String) -> bool: return name == "XRToolsHand" @@ -91,7 +114,15 @@ func is_xr_class(name : String) -> bool: ## Called when the node enters the scene tree for the first time. func _ready() -> void: # Save the initial hand transform - _transform = transform + _initial_transform = transform + _transform = _initial_transform + + # Disconnect from parent transform as we move to it in the physics step, + # and boost the physics priority after any grab-drivers but before other + # processing. + if not Engine.is_editor_hint(): + top_level = true + process_physics_priority = -70 # Find our controller _controller = XRTools.find_xr_ancestor(self, "*", "XRController3D") @@ -105,12 +136,13 @@ func _ready() -> void: _update_hand_blend_tree() _update_hand_material_override() _update_pose() + _update_target() -## This method is called on every frame. It checks for world-scale changes and -## scales itself causing the hand mesh and skeleton to scale appropriately. -## It then reads the grip and trigger action values to animate the hand. -func _process(_delta: float) -> void: +## This method checks for world-scale changes and scales itself causing the +## hand mesh and skeleton to scale appropriately. It then reads the grip and +## trigger action values to animate the hand. +func _physics_process(_delta: float) -> void: # Do not run physics if in the editor if Engine.is_editor_hint(): return @@ -118,7 +150,7 @@ func _process(_delta: float) -> void: # Scale the hand mesh with the world scale. if XRServer.world_scale != _last_world_scale: _last_world_scale = XRServer.world_scale - transform = _transform.scaled(Vector3.ONE * _last_world_scale) + _transform = _initial_transform.scaled(Vector3.ONE * _last_world_scale) emit_signal("hand_scale_changed", _last_world_scale) # Animate the hand mesh with the controller inputs @@ -133,6 +165,9 @@ func _process(_delta: float) -> void: $AnimationTree.set("parameters/Grip/blend_amount", grip) $AnimationTree.set("parameters/Trigger/blend_amount", trigger) + # Move to target + global_transform = _target.global_transform * _transform + force_update_transform() # This method verifies the hand has a valid configuration. @@ -161,7 +196,7 @@ func _get_configuration_warnings() -> PackedStringArray: ## Find an [XRToolsHand] node. ## ## This function searches from the specified node for an [XRToolsHand] assuming -## the node is a sibling of the hand under an [ARVRController]. +## the node is a sibling of the hand under an [XROrigin3D]. static func find_instance(node : Node) -> XRToolsHand: return XRTools.find_xr_child( XRHelpers.get_xr_controller(node), @@ -169,6 +204,24 @@ static func find_instance(node : Node) -> XRToolsHand: "XRToolsHand") as XRToolsHand +## This function searches from the specified node for the left controller +## [XRToolsHand] assuming the node is a sibling of the [XROrigin3D]. +static func find_left(node : Node) -> XRToolsHand: + return XRTools.find_xr_child( + XRHelpers.get_left_controller(node), + "*", + "XRToolsHand") as XRToolsHand + + +## This function searches from the specified node for the right controller +## [XRToolsHand] assuming the node is a sibling of the [XROrigin3D]. +static func find_right(node : Node) -> XRToolsHand: + return XRTools.find_xr_child( + XRHelpers.get_right_controller(node), + "*", + "XRToolsHand") as XRToolsHand + + ## Set the blend tree func set_hand_blend_tree(blend_tree : AnimationNodeBlendTree) -> void: hand_blend_tree = blend_tree @@ -227,6 +280,32 @@ func force_grip_trigger(grip : float = -1.0, trigger : float = -1.0) -> void: if trigger >= 0.0: $AnimationTree.set("parameters/Trigger/blend_amount", trigger) +## This function adds a target override. The collision hand will attempt to +## move to the highest priority target, or the [XRController3D] if no override +## is specified. +func add_target_override(target : Node3D, priority : int) -> void: + # Remove any existing target override from this source + var modified := _remove_target_override(target) + + # Insert the target override + _insert_target_override(target, priority) + modified = true + + # Update the target + if modified: + _update_target() + + +## This function remove a target override. +func remove_target_override(target : Node3D) -> void: + # Remove the target override + var modified := _remove_target_override(target) + + # Update the pose + if modified: + _update_target() + + func _update_hand_blend_tree() -> void: # As we're going to make modifications to our animation tree, we need to do # a deep copy, simply setting resource local to scene does not seem to be enough @@ -329,6 +408,59 @@ func _remove_pose_override(who : Node) -> bool: return modified +# This function inserts a target override into the overrides list by priority +# order. +func _insert_target_override(target : Node3D, priority : int) -> void: + # Construct the target override + var override := TargetOverride.new(target, priority) + + # Iterate over all target overrides in the list + for pos in _target_overrides.size(): + # Get the target override + var o : TargetOverride = _target_overrides[pos] + + # Insert as early as possible to not invalidate sorting + if o.priority <= priority: + _target_overrides.insert(pos, override) + return + + # Insert at the end + _target_overrides.push_back(override) + + +# This function removes a target from the overrides list +func _remove_target_override(target : Node) -> bool: + var pos := 0 + var length := _target_overrides.size() + var modified := false + + # Iterate over all pose overrides in the list + while pos < length: + # Get the target override + var o : TargetOverride = _target_overrides[pos] + + # Check for a match + if o.target == target: + # Remove the override + _target_overrides.remove_at(pos) + modified = true + length -= 1 + else: + # Advance down the list + pos += 1 + + # Return the modified indicator + return modified + + +# This function updates the target for hand movement. +func _update_target() -> void: + if _target_overrides.size(): + _target = _target_overrides[0].target + else: + _target = get_parent() + + static func _find_child(node : Node, type : String) -> Node: # Iterate through all children for child in node.get_children(): diff --git a/addons/godot-xr-tools/hands/hand_physics_bone.gd b/addons/godot-xr-tools/hands/hand_physics_bone.gd index 998d35d..36b4f95 100644 --- a/addons/godot-xr-tools/hands/hand_physics_bone.gd +++ b/addons/godot-xr-tools/hands/hand_physics_bone.gd @@ -55,6 +55,10 @@ func is_xr_class(name : String) -> bool: # Called when the node enters the scene tree. This constructs the physics-bone # nodes and performs initial positioning. func _ready(): + # Skip if in the editor + if Engine.is_editor_hint(): + return + # Connect the 'hand_scale_changed' signal var physics_hand := XRToolsHand.find_instance(self) as XRToolsPhysicsHand if physics_hand: @@ -102,6 +106,10 @@ func _ready(): # Called during the physics process and moves the physics-bone to follow the # skeletal-bone. func _physics_process(delta: float) -> void: + # Skip if in the editor + if Engine.is_editor_hint(): + return + _move_bone(delta) diff --git a/addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf.import index f3af00a..1314ffb 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://bd7h22w1o77fp" +uid="uid://bu07alt6vkbaq" path="res://.godot/imported/Hand_Glove_L.gltf-ac6c06fe48ca0d7ce0f9faffd177a897.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf.import index a42434a..8c12245 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://iwqh6hhdhhdk" +uid="uid://w7th3d2hl7b5" path="res://.godot/imported/Hand_Glove_R.gltf-0e99922c663867da8d37af9597ab1ce8.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf.import index 478d8e1..6fb44fe 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://dokq2yjsxpofc" +uid="uid://bnx4hithcij6y" path="res://.godot/imported/Hand_Glove_low_L.gltf-7b94b12c0dff159d494da6cafd52895d.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf.import index 9b4bf74..31c5355 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://cacrvwhji2ibw" +uid="uid://csgsp0wuw8ucy" path="res://.godot/imported/Hand_Glove_low_R.gltf-c32907596b2287c95aff0e704780ef3d.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf.import index 28458e8..fb4f1ce 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://bh786yhm5v4fh" +uid="uid://q1l3fknstir2" path="res://.godot/imported/Hand_Nails_L.gltf-22452b307072e9d363b1f547e2b6a365.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf.import index ad9ae09..d198397 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://duffm8pu8ask7" +uid="uid://c6s5nvekg0isa" path="res://.godot/imported/Hand_Nails_R.gltf-35869d6a39400588d95465aa5e3b528d.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf.import index cfd9a3a..40d4e92 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://w87o4l6qhsmd" +uid="uid://c4nba0qpi0uls" path="res://.godot/imported/Hand_Nails_low_L.gltf-60d8096917582bfe1d760ff1ad173fc8.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf.import b/addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf.import index f9a3680..53fea66 100644 --- a/addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://cgobg2isk3rk1" +uid="uid://dunu03tc5vdbh" path="res://.godot/imported/Hand_Nails_low_R.gltf-7d9fc9507def4b4fd9c10cdae7aa6e11.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_low_L.gltf.import b/addons/godot-xr-tools/hands/model/Hand_low_L.gltf.import index e89ca1e..44b7650 100644 --- a/addons/godot-xr-tools/hands/model/Hand_low_L.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_low_L.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://g510kgsy5u72" +uid="uid://16colgxrw27d" path="res://.godot/imported/Hand_low_L.gltf-a83bdf9115e4fb62c63deabade61cbbb.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/Hand_low_R.gltf.import b/addons/godot-xr-tools/hands/model/Hand_low_R.gltf.import index 334e485..dcf37b5 100644 --- a/addons/godot-xr-tools/hands/model/Hand_low_R.gltf.import +++ b/addons/godot-xr-tools/hands/model/Hand_low_R.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://c6rnlihkm44f0" +uid="uid://cjrac51wst3tu" path="res://.godot/imported/Hand_low_R.gltf-8b164aff014e5c5bfa2eccc8e40e7e97.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/hand_l.gltf.import b/addons/godot-xr-tools/hands/model/hand_l.gltf.import index a62a6b6..326d084 100644 --- a/addons/godot-xr-tools/hands/model/hand_l.gltf.import +++ b/addons/godot-xr-tools/hands/model/hand_l.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://dvkh1gxbhwri4" +uid="uid://dhaqth6q5yw4n" path="res://.godot/imported/hand_l.gltf-6ba1595ac4c28aef3719b7f0b4f2f4f2.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/model/hand_r.gltf.import b/addons/godot-xr-tools/hands/model/hand_r.gltf.import index 7448225..1f91a8d 100644 --- a/addons/godot-xr-tools/hands/model/hand_r.gltf.import +++ b/addons/godot-xr-tools/hands/model/hand_r.gltf.import @@ -3,7 +3,7 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://ytv5cbt6dbeg" +uid="uid://ds1t8vc0kxoeo" path="res://.godot/imported/hand_r.gltf-dd429687cadefbc3e7a21ae26addfb30.scn" [deps] @@ -22,7 +22,6 @@ meshes/generate_lods=true meshes/create_shadow_meshes=true meshes/light_baking=1 meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false skins/use_named_skins=true animation/import=true animation/fps=30 @@ -30,5 +29,4 @@ animation/trimming=false animation/remove_immutable_tracks=true import_script/path="" _subresources={} -gltf/naming_version=0 gltf/embedded_image_handling=1 diff --git a/addons/godot-xr-tools/hands/scenes/collision/collision_hand_left.tscn b/addons/godot-xr-tools/hands/scenes/collision/collision_hand_left.tscn index 0cb1065..869d1b6 100644 --- a/addons/godot-xr-tools/hands/scenes/collision/collision_hand_left.tscn +++ b/addons/godot-xr-tools/hands/scenes/collision/collision_hand_left.tscn @@ -5,11 +5,10 @@ [sub_resource type="BoxShape3D" id="BoxShape3D_bv7in"] size = Vector3(0.045, 0.075, 0.1) -[node name="CollisionHandLeft" type="StaticBody3D"] -process_priority = -90 -process_physics_priority = -90 +[node name="CollisionHandLeft" type="AnimatableBody3D"] collision_layer = 131072 collision_mask = 327711 +sync_to_physics = false script = ExtResource("1_t5acd") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/addons/godot-xr-tools/hands/scenes/collision/collision_hand_right.tscn b/addons/godot-xr-tools/hands/scenes/collision/collision_hand_right.tscn index e6a3b60..e68a9cd 100644 --- a/addons/godot-xr-tools/hands/scenes/collision/collision_hand_right.tscn +++ b/addons/godot-xr-tools/hands/scenes/collision/collision_hand_right.tscn @@ -5,11 +5,10 @@ [sub_resource type="BoxShape3D" id="BoxShape3D_fc2ij"] size = Vector3(0.045, 0.075, 0.1) -[node name="CollisionHandRight" type="StaticBody3D"] -process_priority = -90 -process_physics_priority = -90 +[node name="CollisionHandRight" type="AnimatableBody3D"] collision_layer = 131072 collision_mask = 327711 +sync_to_physics = false script = ExtResource("1_so3hf") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_hand.tscn index db9c6b1..5af1d46 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_hand.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=13 format=3 uid="uid://bpdj5njb8nhot"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://dvkh1gxbhwri4" path="res://addons/godot-xr-tools/hands/model/hand_l.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://dhaqth6q5yw4n" path="res://addons/godot-xr-tools/hands/model/hand_l.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_x4lr3"] [ext_resource type="Material" uid="uid://ba02jnd2dswyn" path="res://addons/godot-xr-tools/hands/materials/cleaning_glove.material" id="4"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_rtx6p") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_y01rx") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_physics_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_physics_hand.tscn index f54a0b5..64dfa96 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_physics_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/left_fullglove_physics_hand.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=14 format=3 uid="uid://nqiyqnx42m61"] -[ext_resource type="PackedScene" uid="uid://dvkh1gxbhwri4" path="res://addons/godot-xr-tools/hands/model/hand_l.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://dhaqth6q5yw4n" path="res://addons/godot-xr-tools/hands/model/hand_l.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_0aa1r"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_g5ps2") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_v8isy") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftPhysicsHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/left_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/left_hand.tscn index f9d32bb..ef1c2d3 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/left_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/left_hand.tscn @@ -1,42 +1,42 @@ [gd_scene load_steps=13 format=3 uid="uid://njx823gyk04n"] -[ext_resource type="PackedScene" uid="uid://bh786yhm5v4fh" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://q1l3fknstir2" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_k56uy"] [ext_resource type="AnimationNodeBlendTree" uid="uid://dl8yf7ipqotd1" path="res://addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres" id="5"] [ext_resource type="Material" uid="uid://dbvge3quu3bju" path="res://addons/godot-xr-tools/hands/materials/caucasian_hand.material" id="6"] -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_e6byy"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_x12eo"] animation = &"Grip" -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_bs8g1"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_kw2gg"] animation = &"Grip" -[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_675c4"] +[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_o8j0s"] filter_enabled = true filters = ["Armature/Skeleton3D:Little_Distal_L", "Armature/Skeleton3D:Little_Intermediate_L", "Armature/Skeleton3D:Little_Metacarpal_L", "Armature/Skeleton3D:Little_Proximal_L", "Armature/Skeleton3D:Middle_Distal_L", "Armature/Skeleton3D:Middle_Intermediate_L", "Armature/Skeleton3D:Middle_Metacarpal_L", "Armature/Skeleton3D:Middle_Proximal_L", "Armature/Skeleton3D:Ring_Distal_L", "Armature/Skeleton3D:Ring_Intermediate_L", "Armature/Skeleton3D:Ring_Metacarpal_L", "Armature/Skeleton3D:Ring_Proximal_L", "Armature/Skeleton3D:Thumb_Distal_L", "Armature/Skeleton3D:Thumb_Metacarpal_L", "Armature/Skeleton3D:Thumb_Proximal_L", "Armature/Skeleton:Little_Distal_L", "Armature/Skeleton:Little_Intermediate_L", "Armature/Skeleton:Little_Proximal_L", "Armature/Skeleton:Middle_Distal_L", "Armature/Skeleton:Middle_Intermediate_L", "Armature/Skeleton:Middle_Proximal_L", "Armature/Skeleton:Ring_Distal_L", "Armature/Skeleton:Ring_Intermediate_L", "Armature/Skeleton:Ring_Proximal_L", "Armature/Skeleton:Thumb_Distal_L", "Armature/Skeleton:Thumb_Proximal_L"] -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_2ssci"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_cxcnq"] animation = &"Grip 5" -[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_narw6"] +[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_yn70n"] filter_enabled = true filters = ["Armature/Skeleton3D:Index_Distal_L", "Armature/Skeleton3D:Index_Intermediate_L", "Armature/Skeleton3D:Index_Metacarpal_L", "Armature/Skeleton3D:Index_Proximal_L", "Armature/Skeleton:Index_Distal_L", "Armature/Skeleton:Index_Intermediate_L", "Armature/Skeleton:Index_Proximal_L"] -[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_wp4n0"] +[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_v8owg"] graph_offset = Vector2(-536, 11) -nodes/ClosedHand1/node = SubResource("AnimationNodeAnimation_e6byy") +nodes/ClosedHand1/node = SubResource("AnimationNodeAnimation_x12eo") nodes/ClosedHand1/position = Vector2(-600, 300) -nodes/ClosedHand2/node = SubResource("AnimationNodeAnimation_bs8g1") +nodes/ClosedHand2/node = SubResource("AnimationNodeAnimation_kw2gg") nodes/ClosedHand2/position = Vector2(-360, 300) -nodes/Grip/node = SubResource("AnimationNodeBlend2_675c4") +nodes/Grip/node = SubResource("AnimationNodeBlend2_o8j0s") nodes/Grip/position = Vector2(0, 20) -nodes/OpenHand/node = SubResource("AnimationNodeAnimation_2ssci") +nodes/OpenHand/node = SubResource("AnimationNodeAnimation_cxcnq") nodes/OpenHand/position = Vector2(-600, 100) -nodes/Trigger/node = SubResource("AnimationNodeBlend2_narw6") +nodes/Trigger/node = SubResource("AnimationNodeBlend2_yn70n") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftHand" type="Node3D"] script = ExtResource("3") @@ -73,7 +73,7 @@ surface_material_override/0 = ExtResource("6") [node name="AnimationPlayer" parent="Hand_Nails_L" instance=ExtResource("2")] [node name="AnimationTree" type="AnimationTree" parent="."] -tree_root = SubResource("AnimationNodeBlendTree_wp4n0") +tree_root = SubResource("AnimationNodeBlendTree_v8owg") anim_player = NodePath("../Hand_Nails_L/AnimationPlayer") active = true parameters/Grip/blend_amount = 0.0 diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_hand.tscn index fdc5aa8..c94c778 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_hand.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://cy03d57iyrci"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://bh786yhm5v4fh" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://q1l3fknstir2" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_L.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_fye1l"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand_physics_bone.gd" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_40ncn") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_fjpy6") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftPhysicsHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_tac_glove.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_tac_glove.tscn index 4ac5560..43f657f 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_tac_glove.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/left_physics_tac_glove.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=14 format=3 uid="uid://ddsj74hpt1kgb"] -[ext_resource type="PackedScene" uid="uid://bd7h22w1o77fp" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://bu07alt6vkbaq" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="2"] [ext_resource type="AnimationNodeBlendTree" uid="uid://dl8yf7ipqotd1" path="res://addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_rnhp7"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_2ih7n") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_02eq5") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftPhysicsHand" type="Node3D"] script = ExtResource("6") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/left_tac_glove.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/left_tac_glove.tscn index 88f9dcb..60a45d6 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/left_tac_glove.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/left_tac_glove.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=13 format=3 uid="uid://hpr0v012ghsb"] -[ext_resource type="PackedScene" uid="uid://bd7h22w1o77fp" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://bu07alt6vkbaq" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_L.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_s33di"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_kjpaa") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_kisbg") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_hand.tscn index 87d59df..84e076b 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_hand.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=13 format=3 uid="uid://d1tl07geqm5xq"] -[ext_resource type="PackedScene" uid="uid://ytv5cbt6dbeg" path="res://addons/godot-xr-tools/hands/model/hand_r.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://ds1t8vc0kxoeo" path="res://addons/godot-xr-tools/hands/model/hand_r.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_xmpie"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_gm5ny") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_3o6s4") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_physics_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_physics_hand.tscn index d703934..c48a0c5 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_physics_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/right_fullglove_physics_hand.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=14 format=3 uid="uid://cigx2gnf4tg4d"] -[ext_resource type="PackedScene" uid="uid://ytv5cbt6dbeg" path="res://addons/godot-xr-tools/hands/model/hand_r.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://ds1t8vc0kxoeo" path="res://addons/godot-xr-tools/hands/model/hand_r.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_23oai"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_4mwbe") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_x7ees") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightPhysicsHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/right_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/right_hand.tscn index 30f53d2..3062ad9 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/right_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/right_hand.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=13 format=3 uid="uid://raeeicvvindd"] -[ext_resource type="PackedScene" uid="uid://duffm8pu8ask7" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://c6s5nvekg0isa" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_lydk3"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_0hd6d") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_okkj6") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_hand.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_hand.tscn index 0be37a2..0ee707a 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_hand.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://kcqomcjq52np"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://duffm8pu8ask7" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://c6s5nvekg0isa" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_R.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_gqplw"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand_physics_bone.gd" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_4bb4h") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_b8ks0") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightPhysicsHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_tac_glove.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_tac_glove.tscn index 2321537..18bf291 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_tac_glove.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/right_physics_tac_glove.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://b6xesntm4qeo5"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://iwqh6hhdhhdk" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://w7th3d2hl7b5" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf" id="2"] [ext_resource type="AnimationNodeBlendTree" uid="uid://m85b1gogdums" path="res://addons/godot-xr-tools/hands/animations/right/hand_blend_tree.tres" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_h0fv3"] [ext_resource type="Material" uid="uid://dy4ya7w0k18ds" path="res://addons/godot-xr-tools/hands/materials/glove_caucasian_dark_camo.material" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_dc0m1") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_guoth") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightPhysicsHand" type="Node3D"] script = ExtResource("6") diff --git a/addons/godot-xr-tools/hands/scenes/highpoly/right_tac_glove.tscn b/addons/godot-xr-tools/hands/scenes/highpoly/right_tac_glove.tscn index b6b6823..3ac11a0 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/right_tac_glove.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/right_tac_glove.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=13 format=3 uid="uid://dup2vp8v5rpi5"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://iwqh6hhdhhdk" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://w7th3d2hl7b5" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_R.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_3ih8a"] [ext_resource type="AnimationNodeBlendTree" uid="uid://m85b1gogdums" path="res://addons/godot-xr-tools/hands/animations/right/hand_blend_tree.tres" id="4"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_4vdom") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_hef27") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/left_fullglove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/left_fullglove_low.tscn index 4d82290..1899c63 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/left_fullglove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/left_fullglove_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=13 format=3 uid="uid://bq86r4yll8po"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://g510kgsy5u72" path="res://addons/godot-xr-tools/hands/model/Hand_low_L.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://16colgxrw27d" path="res://addons/godot-xr-tools/hands/model/Hand_low_L.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_wyae6"] [ext_resource type="AnimationNodeBlendTree" uid="uid://dl8yf7ipqotd1" path="res://addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres" id="5"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_470u2") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_fhgyt") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/left_hand_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/left_hand_low.tscn index b7286db..7455a9d 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/left_hand_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/left_hand_low.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=13 format=3 uid="uid://b4kad2kuba1yn"] -[ext_resource type="PackedScene" uid="uid://w87o4l6qhsmd" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://c4nba0qpi0uls" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_ry7qg"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_c3h37") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_ihxeh") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_fullglove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_fullglove_low.tscn index f84a9d8..94f4a5b 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_fullglove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_fullglove_low.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=14 format=3 uid="uid://b8hc2ex21u8xj"] -[ext_resource type="PackedScene" uid="uid://g510kgsy5u72" path="res://addons/godot-xr-tools/hands/model/Hand_low_L.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://16colgxrw27d" path="res://addons/godot-xr-tools/hands/model/Hand_low_L.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_4017m"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_fvmpw") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_a1c3t") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftPhysicsHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_hand_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_hand_low.tscn index 1d310c7..7c0ccfb 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_hand_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_hand_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://bdwmserhqai5h"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://w87o4l6qhsmd" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://c4nba0qpi0uls" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_L.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_t17lq"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand_physics_bone.gd" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_3l13i") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_ms3kw") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftPhysicsHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_tac_glove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_tac_glove_low.tscn index e8bc058..57263a9 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_tac_glove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/left_physics_tac_glove_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://bj1aas6kty3qx"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://dokq2yjsxpofc" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://bnx4hithcij6y" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf" id="2"] [ext_resource type="AnimationNodeBlendTree" uid="uid://dl8yf7ipqotd1" path="res://addons/godot-xr-tools/hands/animations/left/hand_blend_tree.tres" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_oehre"] [ext_resource type="Material" uid="uid://dy4ya7w0k18ds" path="res://addons/godot-xr-tools/hands/materials/glove_caucasian_dark_camo.material" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_vkt4w") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_1yhw8") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftPhysicsHand" type="Node3D"] script = ExtResource("6") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/left_tac_glove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/left_tac_glove_low.tscn index b53f92d..26176eb 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/left_tac_glove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/left_tac_glove_low.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=13 format=3 uid="uid://bx1xdisoqo1f6"] -[ext_resource type="PackedScene" uid="uid://dokq2yjsxpofc" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://bnx4hithcij6y" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_L.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://the6y7swe6j0" path="res://addons/godot-xr-tools/hands/animations/left/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dertgu7k8alls" path="res://addons/godot-xr-tools/hands/poses/pose_default_left.tres" id="3_iq5xt"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_csu2l") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_akg52") nodes/Trigger/position = Vector2(-360, 20) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="LeftHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/right_fullglove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/right_fullglove_low.tscn index fc6c501..530078b 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/right_fullglove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/right_fullglove_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=13 format=3 uid="uid://xqimcf20s2jp"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://c6rnlihkm44f0" path="res://addons/godot-xr-tools/hands/model/Hand_low_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://cjrac51wst3tu" path="res://addons/godot-xr-tools/hands/model/Hand_low_R.gltf" id="2"] [ext_resource type="Material" uid="uid://ba02jnd2dswyn" path="res://addons/godot-xr-tools/hands/materials/cleaning_glove.material" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_r4xyu"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="4"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_l50hj") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_vrc3g") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightHand" type="Node3D"] script = ExtResource("4") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/right_hand_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/right_hand_low.tscn index cac7bff..e985370 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/right_hand_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/right_hand_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=13 format=3 uid="uid://l2n30mpbkdyw"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://cgobg2isk3rk1" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://dunu03tc5vdbh" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_f67ka"] [ext_resource type="Material" uid="uid://dbvge3quu3bju" path="res://addons/godot-xr-tools/hands/materials/caucasian_hand.material" id="4"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_covtt") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_h5uio") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_fullglove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_fullglove_low.tscn index 13103a9..be22323 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_fullglove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_fullglove_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://bkdeegb8w3oah"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://c6rnlihkm44f0" path="res://addons/godot-xr-tools/hands/model/Hand_low_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://cjrac51wst3tu" path="res://addons/godot-xr-tools/hands/model/Hand_low_R.gltf" id="2"] [ext_resource type="Material" uid="uid://bhiiya7ow6h8v" path="res://addons/godot-xr-tools/hands/materials/labglove.material" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_e8slj"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_1fjc2") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_ai2qv") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightPhysicsHand" type="Node3D"] script = ExtResource("4") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_hand_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_hand_low.tscn index 0c3d319..7b35e6f 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_hand_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_hand_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://btf05hjpw6k05"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://cgobg2isk3rk1" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://dunu03tc5vdbh" path="res://addons/godot-xr-tools/hands/model/Hand_Nails_low_R.gltf" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/physics_hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_b86a5"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand_physics_bone.gd" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_l0mk4") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_it0su") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightPhysicsHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_tac_glove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_tac_glove_low.tscn index 76a8f2b..13804db 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_tac_glove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/right_physics_tac_glove_low.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=14 format=3 uid="uid://c2uvwvdlsfuep"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://cacrvwhji2ibw" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf" id="2"] +[ext_resource type="PackedScene" uid="uid://csgsp0wuw8ucy" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf" id="2"] [ext_resource type="AnimationNodeBlendTree" uid="uid://m85b1gogdums" path="res://addons/godot-xr-tools/hands/animations/right/hand_blend_tree.tres" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_xodao"] [ext_resource type="Material" uid="uid://dy4ya7w0k18ds" path="res://addons/godot-xr-tools/hands/materials/glove_caucasian_dark_camo.material" id="4"] @@ -37,7 +37,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_8kdoe") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_5qnsq") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightPhysicsHand" type="Node3D"] script = ExtResource("6") diff --git a/addons/godot-xr-tools/hands/scenes/lowpoly/right_tac_glove_low.tscn b/addons/godot-xr-tools/hands/scenes/lowpoly/right_tac_glove_low.tscn index 5128804..a258c44 100644 --- a/addons/godot-xr-tools/hands/scenes/lowpoly/right_tac_glove_low.tscn +++ b/addons/godot-xr-tools/hands/scenes/lowpoly/right_tac_glove_low.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=13 format=3 uid="uid://chumpejwiub7f"] -[ext_resource type="PackedScene" uid="uid://cacrvwhji2ibw" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf" id="1"] +[ext_resource type="PackedScene" uid="uid://csgsp0wuw8ucy" path="res://addons/godot-xr-tools/hands/model/Hand_Glove_low_R.gltf" id="1"] [ext_resource type="PackedScene" uid="uid://bxipj7hyjwy6f" path="res://addons/godot-xr-tools/hands/animations/right/AnimationPlayer.tscn" id="2"] [ext_resource type="Script" path="res://addons/godot-xr-tools/hands/hand.gd" id="3"] [ext_resource type="Resource" uid="uid://dmpjtk0l8vh6v" path="res://addons/godot-xr-tools/hands/poses/pose_default_right.tres" id="3_2wryo"] @@ -36,7 +36,7 @@ nodes/OpenHand/node = SubResource("AnimationNodeAnimation_4o3a2") nodes/OpenHand/position = Vector2(-600, 100) nodes/Trigger/node = SubResource("AnimationNodeBlend2_5v4fm") nodes/Trigger/position = Vector2(-360, 40) -node_connections = [&"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1", &"output", 0, &"Grip"] +node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] [node name="RightHand" type="Node3D"] script = ExtResource("3") diff --git a/addons/godot-xr-tools/hands/textures/african_baseColor.png.import b/addons/godot-xr-tools/hands/textures/african_baseColor.png.import index 4b41dac..be52018 100644 --- a/addons/godot-xr-tools/hands/textures/african_baseColor.png.import +++ b/addons/godot-xr-tools/hands/textures/african_baseColor.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bcgvvpllho2e1" +uid="uid://cs7m7m0k2506g" path="res://.godot/imported/african_baseColor.png-c1a63b2c85973a5f7673482d994697e9.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/hands/textures/african_realistic_baseColor.png.import b/addons/godot-xr-tools/hands/textures/african_realistic_baseColor.png.import index ffd4b06..9ab4c6d 100644 --- a/addons/godot-xr-tools/hands/textures/african_realistic_baseColor.png.import +++ b/addons/godot-xr-tools/hands/textures/african_realistic_baseColor.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bbegc1t6sypfe" +uid="uid://dk8o82rjww802" path="res://.godot/imported/african_realistic_baseColor.png-67cf0f3230115c16edbeaf7b76430f7c.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/hands/textures/caucasian_baseColor.png.import b/addons/godot-xr-tools/hands/textures/caucasian_baseColor.png.import index 9931572..6ef2fde 100644 --- a/addons/godot-xr-tools/hands/textures/caucasian_baseColor.png.import +++ b/addons/godot-xr-tools/hands/textures/caucasian_baseColor.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://ura2vjsqegjt" +uid="uid://c506svon268ms" path.s3tc="res://.godot/imported/caucasian_baseColor.png-2ffa4b91e9a1b3bcc11c22eccd941be7.s3tc.ctex" path.etc2="res://.godot/imported/caucasian_baseColor.png-2ffa4b91e9a1b3bcc11c22eccd941be7.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/caucasian_realistic_baseColor.png.import b/addons/godot-xr-tools/hands/textures/caucasian_realistic_baseColor.png.import index 3f85a46..877755b 100644 --- a/addons/godot-xr-tools/hands/textures/caucasian_realistic_baseColor.png.import +++ b/addons/godot-xr-tools/hands/textures/caucasian_realistic_baseColor.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dphwanfi4jxrk" +uid="uid://n1xq4cm67o07" path="res://.godot/imported/caucasian_realistic_baseColor.png-6d28d56c1e76917b749358861074492c.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/hands/textures/cleaning_glove_baseColor.png.import b/addons/godot-xr-tools/hands/textures/cleaning_glove_baseColor.png.import index dae2602..6a06dbb 100644 --- a/addons/godot-xr-tools/hands/textures/cleaning_glove_baseColor.png.import +++ b/addons/godot-xr-tools/hands/textures/cleaning_glove_baseColor.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://deh22migllf4t" +uid="uid://dv711ytktesj2" path.s3tc="res://.godot/imported/cleaning_glove_baseColor.png-775896445d04c5f9ecad1dcd0609e336.s3tc.ctex" path.etc2="res://.godot/imported/cleaning_glove_baseColor.png-775896445d04c5f9ecad1dcd0609e336.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/glove_african_dark_camo.png.import b/addons/godot-xr-tools/hands/textures/glove_african_dark_camo.png.import index 684dbd8..f3ad84f 100644 --- a/addons/godot-xr-tools/hands/textures/glove_african_dark_camo.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_african_dark_camo.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://c2hanl27i7oc1" +uid="uid://cocorrka3dtq3" path="res://.godot/imported/glove_african_dark_camo.png-3a526d8d251e73995f6fd3ba5cdd0b4e.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/hands/textures/glove_african_green_camo.png.import b/addons/godot-xr-tools/hands/textures/glove_african_green_camo.png.import index 1beed18..a75b6fe 100644 --- a/addons/godot-xr-tools/hands/textures/glove_african_green_camo.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_african_green_camo.png.import @@ -2,26 +2,28 @@ importer="texture" type="CompressedTexture2D" -uid="uid://vfkxkijr37rm" -path="res://.godot/imported/glove_african_green_camo.png-b4a9e045aac0313108230034e03317fd.ctex" +uid="uid://bidphehpipwhg" +path.s3tc="res://.godot/imported/glove_african_green_camo.png-b4a9e045aac0313108230034e03317fd.s3tc.ctex" +path.etc2="res://.godot/imported/glove_african_green_camo.png-b4a9e045aac0313108230034e03317fd.etc2.ctex" metadata={ -"vram_texture": false +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true } [deps] source_file="res://addons/godot-xr-tools/hands/textures/glove_african_green_camo.png" -dest_files=["res://.godot/imported/glove_african_green_camo.png-b4a9e045aac0313108230034e03317fd.ctex"] +dest_files=["res://.godot/imported/glove_african_green_camo.png-b4a9e045aac0313108230034e03317fd.s3tc.ctex", "res://.godot/imported/glove_african_green_camo.png-b4a9e045aac0313108230034e03317fd.etc2.ctex"] [params] -compress/mode=0 +compress/mode=2 compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 -mipmaps/generate=false +mipmaps/generate=true mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" @@ -31,4 +33,4 @@ process/normal_map_invert_y=false process/hdr_as_srgb=false process/hdr_clamp_exposure=false process/size_limit=0 -detect_3d/compress_to=1 +detect_3d/compress_to=0 diff --git a/addons/godot-xr-tools/hands/textures/glove_caucasian_dark_camo.png.import b/addons/godot-xr-tools/hands/textures/glove_caucasian_dark_camo.png.import index a4fef8f..747c121 100644 --- a/addons/godot-xr-tools/hands/textures/glove_caucasian_dark_camo.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_caucasian_dark_camo.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://daphmv2yp22x" +uid="uid://c7jutkax2fd1k" path.s3tc="res://.godot/imported/glove_caucasian_dark_camo.png-338e35680a2de0f7c6ad596eba6a3d5f.s3tc.ctex" path.etc2="res://.godot/imported/glove_caucasian_dark_camo.png-338e35680a2de0f7c6ad596eba6a3d5f.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/glove_caucasian_green_camo.png.import b/addons/godot-xr-tools/hands/textures/glove_caucasian_green_camo.png.import index e0bcacd..d7a9d9e 100644 --- a/addons/godot-xr-tools/hands/textures/glove_caucasian_green_camo.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_caucasian_green_camo.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bvbbghjfsau1b" +uid="uid://dgkfppran5j1f" path.s3tc="res://.godot/imported/glove_caucasian_green_camo.png-009f6b98bc0f9d73ac78a6b6900a0d00.s3tc.ctex" path.etc2="res://.godot/imported/glove_caucasian_green_camo.png-009f6b98bc0f9d73ac78a6b6900a0d00.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/glove_fingerless_normal.png.import b/addons/godot-xr-tools/hands/textures/glove_fingerless_normal.png.import index f2dc3f2..075d303 100644 --- a/addons/godot-xr-tools/hands/textures/glove_fingerless_normal.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_fingerless_normal.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://duqdr6qqrim0s" +uid="uid://bw8rmigwt5pr4" path.s3tc="res://.godot/imported/glove_fingerless_normal.png-46736b8f0a977e37b17257f7bbbb718f.s3tc.ctex" path.etc2="res://.godot/imported/glove_fingerless_normal.png-46736b8f0a977e37b17257f7bbbb718f.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/glove_fingerless_occlusionRoughnessMetallic.png.import b/addons/godot-xr-tools/hands/textures/glove_fingerless_occlusionRoughnessMetallic.png.import index a53ed10..8b11c53 100644 --- a/addons/godot-xr-tools/hands/textures/glove_fingerless_occlusionRoughnessMetallic.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_fingerless_occlusionRoughnessMetallic.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://3fax6yglkrd3" +uid="uid://d2iocwfr47kqp" path.s3tc="res://.godot/imported/glove_fingerless_occlusionRoughnessMetallic.png-441bf1f84442c3cd6ae3834c9c982565.s3tc.ctex" path.etc2="res://.godot/imported/glove_fingerless_occlusionRoughnessMetallic.png-441bf1f84442c3cd6ae3834c9c982565.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/glove_normal.png.import b/addons/godot-xr-tools/hands/textures/glove_normal.png.import index 92ef95b..23724ec 100644 --- a/addons/godot-xr-tools/hands/textures/glove_normal.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_normal.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dasjkfath7rqu" +uid="uid://dt6k4nuvpo38o" path.s3tc="res://.godot/imported/glove_normal.png-da82759e655cb7106cb0172b7076b948.s3tc.ctex" path.etc2="res://.godot/imported/glove_normal.png-da82759e655cb7106cb0172b7076b948.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/glove_occlusionRoughnessMetallic.png.import b/addons/godot-xr-tools/hands/textures/glove_occlusionRoughnessMetallic.png.import index c7df30b..2bfd161 100644 --- a/addons/godot-xr-tools/hands/textures/glove_occlusionRoughnessMetallic.png.import +++ b/addons/godot-xr-tools/hands/textures/glove_occlusionRoughnessMetallic.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://b5v1xfnkyjaf6" +uid="uid://yslwgnpbpeen" path.s3tc="res://.godot/imported/glove_occlusionRoughnessMetallic.png-1a61c4638e30c81daa59d92c8681eb2c.s3tc.ctex" path.etc2="res://.godot/imported/glove_occlusionRoughnessMetallic.png-1a61c4638e30c81daa59d92c8681eb2c.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/hands_normal.png.import b/addons/godot-xr-tools/hands/textures/hands_normal.png.import index c9b8104..998156c 100644 --- a/addons/godot-xr-tools/hands/textures/hands_normal.png.import +++ b/addons/godot-xr-tools/hands/textures/hands_normal.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dlkn0p2k7gfqc" +uid="uid://b6tgv6ucbgv3r" path="res://.godot/imported/hands_normal.png-291c7217751274bfe1199e3de899450f.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png.import b/addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png.import index 4400d8b..30c1736 100644 --- a/addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png.import +++ b/addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dy5hyp5n7o6gl" +uid="uid://h3sjbnu6uplb" path.s3tc="res://.godot/imported/hands_occlusionRoughnessMetallic.png-73229fc54301aa8833117ebde8abfd4e.s3tc.ctex" path.etc2="res://.godot/imported/hands_occlusionRoughnessMetallic.png-73229fc54301aa8833117ebde8abfd4e.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/hands/textures/labglove_baseColor.png.import b/addons/godot-xr-tools/hands/textures/labglove_baseColor.png.import index 1bf3b7e..4320130 100644 --- a/addons/godot-xr-tools/hands/textures/labglove_baseColor.png.import +++ b/addons/godot-xr-tools/hands/textures/labglove_baseColor.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://cxwjhfe1yvm65" +uid="uid://d4gbpgjwjuovb" path.s3tc="res://.godot/imported/labglove_baseColor.png-2eb9fa4d9955a5755a96f0663ee3ceb2.s3tc.ctex" path.etc2="res://.godot/imported/labglove_baseColor.png-2eb9fa4d9955a5755a96f0663ee3ceb2.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/images/icon.png.import b/addons/godot-xr-tools/images/icon.png.import index b7cc4b7..7f90741 100644 --- a/addons/godot-xr-tools/images/icon.png.import +++ b/addons/godot-xr-tools/images/icon.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://b8a7ol64q60tb" +uid="uid://bcll0cv3rie0i" path="res://.godot/imported/icon.png-1d8efcc4c33e64800e22ea3150ef148d.ctex" metadata={ "vram_texture": false diff --git a/addons/godot-xr-tools/images/ring.png.import b/addons/godot-xr-tools/images/ring.png.import index 301b20e..dfa1e53 100644 --- a/addons/godot-xr-tools/images/ring.png.import +++ b/addons/godot-xr-tools/images/ring.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://ciimvkgy0mee0" +uid="uid://8s03ra8tp0hr" path.s3tc="res://.godot/imported/ring.png-34d9c9e9780f2732148a5b14fcac48dd.s3tc.ctex" path.etc2="res://.godot/imported/ring.png-34d9c9e9780f2732148a5b14fcac48dd.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/images/teleport_arrow.png.import b/addons/godot-xr-tools/images/teleport_arrow.png.import index 0862ba6..bc4f101 100644 --- a/addons/godot-xr-tools/images/teleport_arrow.png.import +++ b/addons/godot-xr-tools/images/teleport_arrow.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bbfwq7mhqgwjm" +uid="uid://ddoj6c345cb0c" path.s3tc="res://.godot/imported/teleport_arrow.png-f1bd44b6f478277692b3fa29171b62d3.s3tc.ctex" path.etc2="res://.godot/imported/teleport_arrow.png-f1bd44b6f478277692b3fa29171b62d3.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/images/teleport_target.png.import b/addons/godot-xr-tools/images/teleport_target.png.import index 6a4f980..1e39e03 100644 --- a/addons/godot-xr-tools/images/teleport_target.png.import +++ b/addons/godot-xr-tools/images/teleport_target.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://cygfooytyfhyd" +uid="uid://cu4j1s8qr1rjq" path.s3tc="res://.godot/imported/teleport_target.png-cd812f7d5692711ac91f6c8a4753ad73.s3tc.ctex" path.etc2="res://.godot/imported/teleport_target.png-cd812f7d5692711ac91f6c8a4753ad73.etc2.ctex" metadata={ diff --git a/addons/godot-xr-tools/interactables/interactable_handle.gd b/addons/godot-xr-tools/interactables/interactable_handle.gd index 672018e..91c6617 100644 --- a/addons/godot-xr-tools/interactables/interactable_handle.gd +++ b/addons/godot-xr-tools/interactables/interactable_handle.gd @@ -47,29 +47,29 @@ func _ready() -> void: # Called on every frame when the handle is held to check for snapping func _process(_delta: float) -> void: # Skip if not picked up - if !picked_up_by: + if not is_picked_up(): return # If too far from the origin then drop the handle var origin_pos = handle_origin.global_transform.origin var handle_pos = global_transform.origin if handle_pos.distance_to(origin_pos) > snap_distance: - picked_up_by.drop_object() + drop() # Called when the handle is picked up -func pick_up(by, with_controller) -> void: +func pick_up(by) -> void: # Call the base-class to perform the pickup - super(by, with_controller) + super(by) # Enable the process function while held set_process(true) # Called when the handle is dropped -func let_go(_p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void: +func let_go(by: Node3D, _p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void: # Call the base-class to perform the drop, but with no velocity - super(Vector3.ZERO, Vector3.ZERO) + super(by, Vector3.ZERO, Vector3.ZERO) # Disable the process function as no-longer held set_process(false) diff --git a/addons/godot-xr-tools/interactables/interactable_hinge.tscn b/addons/godot-xr-tools/interactables/interactable_hinge.tscn index ca39b0a..11e5ed8 100644 --- a/addons/godot-xr-tools/interactables/interactable_hinge.tscn +++ b/addons/godot-xr-tools/interactables/interactable_hinge.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=2 format=3 uid="uid://bwqiturebyt3h"] +[gd_scene load_steps=2 format=2] -[ext_resource type="Script" path="res://addons/godot-xr-tools/interactables/interactable_hinge.gd" id="1"] +[ext_resource path="res://addons/godot-xr-tools/interactables/interactable_hinge.gd" type="Script" id=1] [node name="InteractableHinge" type="Spatial"] -script = ExtResource("1") +script = ExtResource( 1 ) diff --git a/addons/godot-xr-tools/interactables/interactable_joystick.tscn b/addons/godot-xr-tools/interactables/interactable_joystick.tscn index 6ec1496..1dcd9a4 100644 --- a/addons/godot-xr-tools/interactables/interactable_joystick.tscn +++ b/addons/godot-xr-tools/interactables/interactable_joystick.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=2 format=3 uid="uid://cnfk38alyp72q"] +[gd_scene load_steps=2 format=2] -[ext_resource type="Script" path="res://addons/godot-xr-tools/interactables/interactable_joystick.gd" id="1"] +[ext_resource path="res://addons/godot-xr-tools/interactables/interactable_joystick.gd" type="Script" id=1] [node name="InteractableJoystick" type="Spatial"] -script = ExtResource("1") +script = ExtResource( 1 ) diff --git a/addons/godot-xr-tools/misc/hold_button.tscn b/addons/godot-xr-tools/misc/hold_button.tscn index 84f9aaa..2e69092 100644 --- a/addons/godot-xr-tools/misc/hold_button.tscn +++ b/addons/godot-xr-tools/misc/hold_button.tscn @@ -10,9 +10,9 @@ resource_local_to_scene = true render_priority = 0 shader = ExtResource("2") shader_parameter/albedo = Color(1, 1, 1, 1) -shader_parameter/value = 0.2 shader_parameter/fade = 0.05 shader_parameter/radius = 0.8 +shader_parameter/value = 0.2 shader_parameter/width = 0.2 [node name="HoldButton" type="Node3D"] diff --git a/addons/godot-xr-tools/misc/vr_common_shader_cache.tscn b/addons/godot-xr-tools/misc/vr_common_shader_cache.tscn index 597bab7..8c9ab26 100644 --- a/addons/godot-xr-tools/misc/vr_common_shader_cache.tscn +++ b/addons/godot-xr-tools/misc/vr_common_shader_cache.tscn @@ -1,7 +1,7 @@ -[gd_scene load_steps=8 format=3 uid="uid://cjccb67fjl4aw"] +[gd_scene load_steps=8 format=3] [ext_resource type="Script" path="res://addons/godot-xr-tools/misc/vr_common_shader_cache.gd" id="1"] -[ext_resource type="Material" uid="uid://bk72wfw25ff0v" path="res://addons/godot-xr-tools/materials/teleport.tres" id="2_6822k"] +[ext_resource type="Material" path="res://addons/godot-xr-tools/materials/teleport.tres" id="2_6822k"] [ext_resource type="Material" path="res://addons/godot-xr-tools/materials/target.tres" id="3_agvdv"] [ext_resource type="Material" path="res://addons/godot-xr-tools/materials/capsule.tres" id="4_gxjsg"] [ext_resource type="Material" path="res://addons/godot-xr-tools/materials/pointer.tres" id="5_12251"] diff --git a/addons/godot-xr-tools/objects/climbable.gd b/addons/godot-xr-tools/objects/climbable.gd index 7864e18..1cea381 100644 --- a/addons/godot-xr-tools/objects/climbable.gd +++ b/addons/godot-xr-tools/objects/climbable.gd @@ -15,8 +15,15 @@ extends Node3D ## If true, the grip control must be held to keep holding the climbable var press_to_hold : bool = true -## Dictionary of temporary grab-handles indexed by the pickup node. -var grab_locations := {} + +## Array of permanent grab points. +var _grab_points : Array[XRToolsGrabPoint] = [] + +## Dictionary of temporary grabs keyed by the pickup node +var _grab_temps : Dictionary = {} + +## Dictionary of active grabs keyed by the pickup node +var _grabs : Dictionary = {} # Add support for is_xr_class on XRTools classes @@ -24,41 +31,79 @@ func is_xr_class(name : String) -> bool: return name == "XRToolsClimbable" +# Called when the node becomes "ready" +func _ready() -> void: + # Get all grab points + for child in get_children(): + var grab_point := child as XRToolsGrabPoint + if grab_point: + _grab_points.push_back(grab_point) + + # Called by XRToolsFunctionPickup func is_picked_up() -> bool: return false + func can_pick_up(_by: Node3D) -> bool: return true + # Called by XRToolsFunctionPickup when user presses the action button while holding this object func action(): pass + # Ignore highlighting requests from XRToolsFunctionPickup func request_highlight(_from, _on) -> void: pass + # Called by XRToolsFunctionPickup when this is picked up by a controller -func pick_up(by: Node3D, _with_controller: XRController3D) -> void: - # Get the ID to save the grab handle under - var id = by.get_instance_id() +func pick_up(by: Node3D) -> void: + # Get the best permanent grab-point + var point := _get_grab_point(by) + if not point: + # Get a temporary grab-point for the pickup + point = _grab_temps.get(by) + if not point: + # Create a new temporary grab-point childed to the climbable + point = Node3D.new() + add_child(point) + _grab_temps[by] = point - # Get or construct the grab handle - var handle = grab_locations.get(id) - if not handle: - handle = Node3D.new() - add_child(handle) - grab_locations[id] = handle + # Set the temporary to the current positon + point.global_transform = by.global_transform + + # Save the grab + _grabs[by] = point - # Set the handles global transform. As it's a child of this - # climbable it will move as the climbable moves - handle.global_transform = by.global_transform # Called by XRToolsFunctionPickup when this is let go by a controller -func let_go(_p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void: - pass +func let_go(by: Node3D, _p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void: + _grabs.erase(by); + # Get the grab handle -func get_grab_handle(p: Node3D) -> Node3D: - return grab_locations.get(p.get_instance_id()) +func get_grab_handle(by: Node3D) -> Node3D: + return _grabs.get(by) + + +## Find the most suitable grab-point for the grabber +func _get_grab_point(by : Node3D) -> Node3D: + # Find the best grab-point + var fitness := 0.0 + var point : XRToolsGrabPoint = null + for p in _grab_points: + var f := p.can_grab(by, null) + if f > fitness: + fitness = f + point = p + + # Resolve redirection + while point is XRToolsGrabPointRedirect: + point = point.target + + # Return the best grab point + print_verbose("%s> picked grab-point %s" % [name, point]) + return point diff --git a/addons/godot-xr-tools/objects/force_body/force_body.gd b/addons/godot-xr-tools/objects/force_body/force_body.gd index cf258dd..7d68584 100644 --- a/addons/godot-xr-tools/objects/force_body/force_body.gd +++ b/addons/godot-xr-tools/objects/force_body/force_body.gd @@ -1,11 +1,11 @@ @tool class_name XRToolsForceBody -extends StaticBody3D +extends AnimatableBody3D ## XRTools Force Body script ## -## This script enhances StaticBody3D with move_and_slide and the ability +## This script enhances AnimatableBody3D with move_and_slide and the ability ## to push bodies by emparting forces on them. @@ -42,6 +42,9 @@ func is_xr_class(name : String) -> bool: ## This function moves and slides along the [param move] vector. It returns ## information about the last collision, or null if no collision func move_and_slide(move : Vector3) -> ForceBodyCollision: + # Make sure this is off or weird shit happens... + sync_to_physics = false + # Loop performing the movement steps var step_move := move var ret : ForceBodyCollision = null diff --git a/addons/godot-xr-tools/objects/grab_points/grab.gd b/addons/godot-xr-tools/objects/grab_points/grab.gd new file mode 100644 index 0000000..0ee42d8 --- /dev/null +++ b/addons/godot-xr-tools/objects/grab_points/grab.gd @@ -0,0 +1,171 @@ +class_name Grab +extends Grabber + + +## Grab Class +## +## This class encodes information about an active grab. Additionally it applies +## hand poses and collision exceptions as appropriate. + + +## Priority for grip poses +const GRIP_POSE_PRIORITY := 100 + +## Priority for grip targeting +const GRIP_TARGET_PRIORITY := 100 + + +## Grab target +var what : XRToolsPickable + +## Grab point information +var point : XRToolsGrabPoint + +## Hand grab point information +var hand_point : XRToolsGrabPointHand + +## Grab transform +var transform : Transform3D + +## Position drive strength +var drive_position : float = 1.0 + +## Angle drive strength +var drive_angle : float = 1.0 + +## Aim drive strength +var drive_aim : float = 0.0 + +## Has target arrived at grab point +var _arrived : bool = false + + +## Initialize the grab +func _init( + p_grabber : Grabber, + p_what : XRToolsPickable, + p_point : XRToolsGrabPoint, + p_precise : bool) -> void: + + # Copy the grabber information + by = p_grabber.by + pickup = p_grabber.pickup + controller = p_grabber.controller + hand = p_grabber.hand + collision_hand = p_grabber.collision_hand + + # Set the point + what = p_what + point = p_point + hand_point = p_point as XRToolsGrabPointHand + + # Calculate the grab transform + if p_point: + transform = p_point.transform + elif p_precise: + transform = p_what.global_transform.inverse() * by.global_transform + else: + transform = Transform3D.IDENTITY + + # Set the drive parameters + if hand_point: + drive_position = hand_point.drive_position + drive_angle = hand_point.drive_angle + drive_aim = hand_point.drive_aim + + # Apply collision exceptions + if collision_hand: + what.add_collision_exception_with(collision_hand) + collision_hand.add_collision_exception_with(what) + + +## Set the target as arrived at the grab-point +func set_arrived() -> void: + # Ignore if already arrived + if _arrived: + return + + # Set arrived and apply any hand pose + print_verbose("%s> arrived at %s" % [what.name, point]) + _arrived = true + _set_hand_pose() + + # Report the grab + print_verbose("%s> grabbed by %s", [what.name, by.name]) + what.grabbed.emit(what, by) + + +## Set the grab point +func set_grab_point(p_point : XRToolsGrabPoint) -> void: + # Skip if no change + if p_point == point: + return + + # Remove any current pose override + _clear_hand_pose() + + # Update the grab point + point = p_point + hand_point = point as XRToolsGrabPointHand + + # Update the transform + if point: + transform = point.transform + + # Apply the new hand grab-point settings + if hand_point: + drive_position = hand_point.drive_position + drive_angle = hand_point.drive_angle + drive_aim = hand_point.drive_aim + + # Apply any pose overrides + if _arrived: + _set_hand_pose() + + # Report switch + print_verbose("%s> switched grab point to %s", [what.name, point.name]) + what.released.emit(what, by) + what.grabbed.emit(what, by) + + +## Release the grip +func release() -> void: + # Clear any hand pose + _clear_hand_pose() + + # Remove collision exceptions + if is_instance_valid(collision_hand): + what.remove_collision_exception_with(collision_hand) + collision_hand.remove_collision_exception_with(what) + + # Report the release + print_verbose("%s> released by %s", [what.name, by.name]) + what.released.emit(what, by) + + +# Set hand-pose overrides +func _set_hand_pose() -> void: + # Skip if not hand + if not is_instance_valid(hand) or not is_instance_valid(hand_point): + return + + # Apply the hand-pose + if hand_point.hand_pose: + hand.add_pose_override(hand_point, GRIP_POSE_PRIORITY, hand_point.hand_pose) + + # Apply hand snapping + if hand_point.snap_hand: + hand.add_target_override(hand_point, GRIP_TARGET_PRIORITY) + + +# Clear any hand-pose overrides +func _clear_hand_pose() -> void: + # Skip if not hand + if not is_instance_valid(hand) or not is_instance_valid(hand_point): + return + + # Remove hand-pose + hand.remove_pose_override(hand_point) + + # Remove hand snapping + hand.remove_target_override(hand_point) diff --git a/addons/godot-xr-tools/objects/grab_points/grab_driver.gd b/addons/godot-xr-tools/objects/grab_points/grab_driver.gd new file mode 100644 index 0000000..2825f3d --- /dev/null +++ b/addons/godot-xr-tools/objects/grab_points/grab_driver.gd @@ -0,0 +1,216 @@ +class_name XRToolsGrabDriver +extends RemoteTransform3D + + +## Grab state +enum State { + LERP, + SNAP, +} + + +## Drive state +var state : State = State.SNAP + +## Target pickable +var target : XRToolsPickable + +## Primary grab information +var primary : Grab = null + +## Secondary grab information +var secondary : Grab = null + +## Lerp start position +var lerp_start : Transform3D + +## Lerp total duration +var lerp_duration : float = 1.0 + +## Lerp time +var lerp_time : float = 0.0 + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _physics_process(delta : float) -> void: + # Skip if no primary node + if not is_instance_valid(primary): + return + + # Set destination from primary grab + var destination := primary.by.global_transform * primary.transform.inverse() + + # If present, apply secondary-node contributions + if is_instance_valid(secondary): + # Calculate lerp coefficients based on drive strengths + var position_lerp := _vote(primary.drive_position, secondary.drive_position) + var angle_lerp := _vote(primary.drive_angle, secondary.drive_angle) + + # Calculate the transform from secondary grab + var x1 := destination + var x2 := secondary.by.global_transform * secondary.transform.inverse() + + # Independently lerp the angle and position + destination = Transform3D( + x1.basis.slerp(x2.basis, angle_lerp), + x1.origin.lerp(x2.origin, position_lerp)) + + # Test if we need to apply aiming + if secondary.drive_aim > 0.0: + # Convert destination from global to primary-local + destination = primary.by.global_transform.inverse() * destination + + # Calculate the from and to vectors in primary-local space + var secondary_from := destination * secondary.transform.origin + var secondary_to := primary.by.to_local(secondary.by.global_position) + + # Build shortest arc + secondary_from = secondary_from.normalized() + secondary_to = secondary_to.normalized() + var spherical := Quaternion(secondary_from, secondary_to) + + # Build aim-rotation + var rotate := Basis.IDENTITY.slerp(Basis(spherical), secondary.drive_aim) + destination = Transform3D(rotate, Vector3.ZERO) * destination + + # Convert destination from primary-local to global + destination = primary.by.global_transform * destination + + # Handle update + match state: + State.LERP: + # Progress the lerp + lerp_time += delta + if lerp_time < lerp_duration: + # Interpolate from lerp_start to destination + destination = lerp_start.interpolate_with( + destination, + lerp_time / lerp_duration) + else: + # Lerp completed + state = State.SNAP + if primary: primary.set_arrived() + if secondary: secondary.set_arrived() + + # Apply the destination transform + global_transform = destination + force_update_transform() + if is_instance_valid(target): + target.force_update_transform() + + +## Set the secondary grab point +func add_grab(p_grab : Grab) -> void: + # Set the secondary grab + if p_grab.hand_point and p_grab.hand_point.mode == XRToolsGrabPointHand.Mode.PRIMARY: + print_verbose("%s> new primary grab %s" % [target.name, p_grab.by.name]) + secondary = primary + primary = p_grab + else: + print_verbose("%s> new secondary grab %s" % [target.name, p_grab.by.name]) + secondary = p_grab + + # If snapped then report arrived at the new grab + if state == State.SNAP: + p_grab.set_arrived() + + +## Get the grab information for the grab node +func get_grab(by : Node3D) -> Grab: + if primary and primary.by == by: + return primary + + if secondary and secondary.by == by: + return secondary + + return null + + +func remove_grab(p_grab : Grab) -> void: + # Remove the appropriate grab + if p_grab == primary: + # Remove primary (secondary promoted) + print_verbose("%s> %s (primary) released" % [target.name, p_grab.by.name]) + primary = secondary + secondary = null + elif p_grab == secondary: + # Remove secondary + print_verbose("%s> %s (secondary) released" % [target.name, p_grab.by.name]) + secondary = null + + +# Discard the driver +func discard(): + remote_path = NodePath() + queue_free() + + +# Create the driver to lerp the target from its current location to the +# primary grab-point. +static func create_lerp( + p_target : Node3D, + p_grab : Grab, + p_lerp_speed : float) -> XRToolsGrabDriver: + + print_verbose("%s> lerping %s" % [p_target.name, p_grab.by.name]) + + # Construct the driver lerping from the current position + var driver := XRToolsGrabDriver.new() + driver.name = p_target.name + "_driver" + driver.top_level = true + driver.process_physics_priority = -80 + driver.state = State.LERP + driver.target = p_target + driver.primary = p_grab + driver.global_transform = p_target.global_transform + + # Calculate the start and duration + var end := p_grab.by.global_transform * p_grab.transform + var delta := end.origin - p_target.global_position + driver.lerp_start = p_target.global_transform + driver.lerp_duration = delta.length() / p_lerp_speed + + # Add the driver as a neighbor of the target as RemoteTransform3D nodes + # cannot be descendands of the targets they drive. + p_target.get_parent().add_child(driver) + driver.remote_path = driver.get_path_to(p_target) + + # Return the driver + return driver + + +# Create the driver to instantly snap to the primary grab-point. +static func create_snap( + p_target : Node3D, + p_grab : Grab) -> XRToolsGrabDriver: + + print_verbose("%s> snapping to %s" % [p_target.name, p_grab.by.name]) + + # Construct the driver snapped to the held position + var driver := XRToolsGrabDriver.new() + driver.name = p_target.name + "_driver" + driver.top_level = true + driver.process_physics_priority = -80 + driver.state = State.SNAP + driver.target = p_target + driver.primary = p_grab + driver.global_transform = p_grab.by.global_transform * p_grab.transform.inverse() + + # Snapped to grab-point so report arrived + p_grab.set_arrived() + + # Add the driver as a neighbor of the target as RemoteTransform3D nodes + # cannot be descendands of the targets they drive. + p_target.get_parent().add_child(driver) + driver.remote_path = driver.get_path_to(p_target) + + # Return the driver + return driver + + +# Calculate the lerp voting from a to b +static func _vote(a : float, b : float) -> float: + if a == 0.0 and b == 0.0: + return 0.0 + + return b / (a + b) diff --git a/addons/godot-xr-tools/objects/grab_points/grab_point.gd b/addons/godot-xr-tools/objects/grab_points/grab_point.gd index 51a5d03..201b99e 100644 --- a/addons/godot-xr-tools/objects/grab_points/grab_point.gd +++ b/addons/godot-xr-tools/objects/grab_points/grab_point.gd @@ -13,6 +13,16 @@ extends Marker3D @export var enabled : bool = true -## Test if a grabber can grab by this grab-point -func can_grab(_grabber : Node) -> bool: - return enabled +## Evaluate fitness of the proposed grab, with 0.0 for not allowed. +func can_grab(grabber : Node3D, _current : XRToolsGrabPoint) -> float: + if not enabled: + return 0.0 + + # Return the distance-weighted fitness + return _weight(grabber) + + +# Return a distance-weighted fitness weight in the range (0.0 - max] +func _weight(grabber : Node3D, max : float = 1.0) -> float: + var distance := global_position.distance_to(grabber.global_position) + return max / (1.0 + distance) diff --git a/addons/godot-xr-tools/objects/grab_points/grab_point_hand.gd b/addons/godot-xr-tools/objects/grab_points/grab_point_hand.gd index 65f435d..7cc0ef1 100644 --- a/addons/godot-xr-tools/objects/grab_points/grab_point_hand.gd +++ b/addons/godot-xr-tools/objects/grab_points/grab_point_hand.gd @@ -16,6 +16,13 @@ enum Hand { RIGHT, ## Right hand } +## Grab mode for this grab point +enum Mode { + GENERAL, ## General grab point + PRIMARY, ## Primary-hand grab point + SECONDARY ## Secondary-hand grab point +} + ## Hand preview option enum PreviewMode { CLOSED, ## Preview hand closed @@ -30,15 +37,33 @@ const LEFT_HAND_PATH := "res://addons/godot-xr-tools/hands/scenes/lowpoly/left_h const RIGHT_HAND_PATH := "res://addons/godot-xr-tools/hands/scenes/lowpoly/right_hand_low.tscn" +## Grab-point handle +@export var handle : String + ## Which hand this grab point is for @export var hand : Hand: set = _set_hand +## Hand grab mode +@export var mode : Mode = Mode.GENERAL + +## Snap the hand mesh to the grab-point +@export var snap_hand : bool = true + ## Hand pose @export var hand_pose : XRToolsHandPoseSettings: set = _set_hand_pose ## If true, the hand is shown in the editor @export var editor_preview_mode : PreviewMode = PreviewMode.CLOSED: set = _set_editor_preview_mode +## How much this grab-point drives the position +@export var drive_position : float = 1.0 + +## How much this grab-point drives the angle +@export var drive_angle : float = 1.0 + +## How much this grab-point drives the aim +@export var drive_aim : float = 0.0 + ## Hand to use for editor preview var _editor_preview_hand : XRToolsHand @@ -52,26 +77,27 @@ func _ready(): ## Test if a grabber can grab by this grab-point -func can_grab(_grabber : Node) -> bool: +func can_grab(grabber : Node3D, current : XRToolsGrabPoint) -> float: # Skip if not enabled if not enabled: - return false + return 0.0 - # Get the grabber controller - var controller := _get_grabber_controller(_grabber) - if not controller: - return false + # Verify the hand matches + if not _is_correct_hand(grabber): + return 0.0 - # Only allow left controller to grab left-hand grab points - if hand == Hand.LEFT and controller.tracker != "left_hand": - return false + # Fail if the hand grab is not permitted + if not _is_valid_hand_grab(current): + return 0.0 - # Only allow right controller to grab right-hand grab points - if hand == Hand.RIGHT and controller.tracker != "right_hand": - return false + # Get the distance-weighted fitness in the range (0.0 - 0.5], but boost + # to [0.5 - 1.0] for valid "specific" grabs. + var fitness := _weight(grabber, 0.5) + if mode != Mode.GENERAL: + fitness += 0.5 - # Allow grab - return true + # Return the grab fitness + return fitness func _set_hand(new_value : Hand) -> void: @@ -122,17 +148,58 @@ func _update_editor_preview() -> void: add_child(_editor_preview_hand) +# Is the grabber for the correct hand +func _is_correct_hand(grabber : Node3D) -> bool: + # Find the controller + var controller := _get_grabber_controller(grabber) + if not controller: + return false + + # If left hand then verify left controller + if hand == Hand.LEFT and controller.tracker != "left_hand": + return false + + # If right hand then verify right controller + if hand == Hand.RIGHT and controller.tracker != "right_hand": + return false + + # Controller matches hand + return true + + +# Test if hand grab is permitted +func _is_valid_hand_grab(current : XRToolsGrabPoint) -> bool: + # Not a valid hand grab if currently held by something other than a hand + var current_hand := current as XRToolsGrabPointHand + if current and not current_hand: + return false + + # Not valid if grabbing the same named handle + if handle and current_hand and handle == current_hand.handle: + return false + + # Not valid if attempting PRIMARY grab while current is PRIMARY + if mode == Mode.PRIMARY and current_hand and current_hand.mode == Mode.PRIMARY: + return false + + # Not valid if attempting SECONDARY grab while no current + if mode == Mode.SECONDARY and not current_hand: + return false + + # Hand is allowed to grab + return true + + # Get the controller associated with a grabber -static func _get_grabber_controller(_grabber : Node) -> XRController3D: +static func _get_grabber_controller(grabber : Node3D) -> XRController3D: # Ensure the grabber is valid - if not is_instance_valid(_grabber): + if not is_instance_valid(grabber): return null # Ensure the pickup is a function pickup for a controller - var pickup := _grabber as XRToolsFunctionPickup + var pickup := grabber as XRToolsFunctionPickup if not pickup: return null # Get the controller associated with the pickup return pickup.get_controller() - diff --git a/addons/godot-xr-tools/objects/grab_points/grab_point_redirect.gd b/addons/godot-xr-tools/objects/grab_points/grab_point_redirect.gd new file mode 100644 index 0000000..508643a --- /dev/null +++ b/addons/godot-xr-tools/objects/grab_points/grab_point_redirect.gd @@ -0,0 +1,17 @@ +@tool +class_name XRToolsGrabPointRedirect +extends XRToolsGrabPoint + + +## Grab point to redirect grabbing to +@export var target : XRToolsGrabPoint + + +## Evaluate fitness of the proposed grab, with 0.0 for not allowed. +func can_grab(grabber : Node3D, current : XRToolsGrabPoint) -> float: + # Fail if no target + if not is_instance_valid(target): + return 0.0 + + # Consult the target + return target.can_grab(grabber, current) diff --git a/addons/godot-xr-tools/objects/grab_points/grab_point_redirect.tscn b/addons/godot-xr-tools/objects/grab_points/grab_point_redirect.tscn new file mode 100644 index 0000000..353bf58 --- /dev/null +++ b/addons/godot-xr-tools/objects/grab_points/grab_point_redirect.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://ca3daqmpo0tua"] + +[ext_resource type="Script" path="res://addons/godot-xr-tools/objects/grab_points/grab_point_redirect.gd" id="1_vyuch"] + +[node name="GrabPointRedirect" type="Marker3D"] +script = ExtResource("1_vyuch") diff --git a/addons/godot-xr-tools/objects/grab_points/grab_point_snap.gd b/addons/godot-xr-tools/objects/grab_points/grab_point_snap.gd index 46a6925..52eaf4c 100644 --- a/addons/godot-xr-tools/objects/grab_points/grab_point_snap.gd +++ b/addons/godot-xr-tools/objects/grab_points/grab_point_snap.gd @@ -23,27 +23,27 @@ func _ready(): add_child(Marker3D.new()) -## Test if a grabber can grab by this grab-point -func can_grab(_grabber : Node) -> bool: - # Skip if not enabled - if not enabled: - return false +## Evaluate fitness of the proposed grab, with 0.0 for not allowed. +func can_grab(grabber : Node3D, current : XRToolsGrabPoint) -> float: + # Skip if not enabled or current grab + if not enabled or current: + return 0.0 # Ensure the pickup is valid - if not is_instance_valid(_grabber): - return false + if not is_instance_valid(grabber): + return 0.0 # Ensure the grabber is a snap-zone - if not _grabber is XRToolsSnapZone: - return false + if not grabber is XRToolsSnapZone: + return 0.0 # Refuse if the grabber is not in the required group - if not require_group.is_empty() and not _grabber.is_in_group(require_group): - return false + if not require_group.is_empty() and not grabber.is_in_group(require_group): + return 0.0 # Refuse if the grabber is in the excluded group - if not exclude_group.is_empty() and _grabber.is_in_group(exclude_group): - return false + if not exclude_group.is_empty() and grabber.is_in_group(exclude_group): + return 0.0 - # Allow the grab - return true + # Return the distance-weighted fitness + return _weight(grabber) diff --git a/addons/godot-xr-tools/objects/grab_points/grabber.gd b/addons/godot-xr-tools/objects/grab_points/grabber.gd new file mode 100644 index 0000000..2576ca6 --- /dev/null +++ b/addons/godot-xr-tools/objects/grab_points/grabber.gd @@ -0,0 +1,32 @@ +class_name Grabber + + +## Grabber Class +## +## This class contains relevant information for a grabber including any +## assocated pickup, controller, and hand nodes. + + +## Grabber node +var by : Node3D + +## Pickup associated with the grabber +var pickup : XRToolsFunctionPickup + +## Controller associated with the grabber +var controller : XRController3D + +## Hand associated with the grabber +var hand : XRToolsHand + +## Collision hand associated with the grabber +var collision_hand : XRToolsCollisionHand + + +## Initialize the grabber +func _init(p_by : Node3D) -> void: + by = p_by + pickup = p_by as XRToolsFunctionPickup + controller = pickup.get_controller() if pickup else null + hand = XRToolsHand.find_instance(controller) + collision_hand = XRToolsCollisionHand.find_instance(controller) diff --git a/addons/godot-xr-tools/objects/hand_pose_area.gd b/addons/godot-xr-tools/objects/hand_pose_area.gd index 9d39e72..43b0082 100644 --- a/addons/godot-xr-tools/objects/hand_pose_area.gd +++ b/addons/godot-xr-tools/objects/hand_pose_area.gd @@ -19,7 +19,19 @@ extends Area3D ## Right hand pose settings (XRToolsHandPoseSettings) @export var right_pose : XRToolsHandPoseSettings +## Array of grabpoints this hand pose area disables when active +@export var grabpoints : Array[XRToolsGrabPointHand] # Add support for is_xr_class on XRTools classes func is_xr_class(name : String) -> bool: return name == "XRToolsHandPoseArea" + +# Disables grabpoints +func disable_grab_points(): + for grabpoint in grabpoints: + grabpoint.enabled = false + +# Enables grabpoints +func enable_grab_points(): + for grabpoint in grabpoints: + grabpoint.enabled = true diff --git a/addons/godot-xr-tools/objects/pickable.gd b/addons/godot-xr-tools/objects/pickable.gd index ff7423c..0bf5ba4 100644 --- a/addons/godot-xr-tools/objects/pickable.gd +++ b/addons/godot-xr-tools/objects/pickable.gd @@ -15,12 +15,18 @@ extends RigidBody3D ## child nodes controlling hand and snap-zone grab locations. -# Signal emitted when the user picks up this object +# Signal emitted when this object is picked up (held by a player or snap-zone) signal picked_up(pickable) -# Signal emitted when the user drops this object +# Signal emitted when this object is dropped signal dropped(pickable) +# Signal emitted when this object is grabbed (primary or secondary) +signal grabbed(pickable, by) + +# Signal emitted when this object is released (primary or secondary) +signal released(pickable, by) + # Signal emitted when the user presses the action button while holding this object signal action_pressed(pickable) @@ -28,12 +34,6 @@ signal action_pressed(pickable) signal highlight_updated(pickable, enable) -## Method used to hold object -enum HoldMethod { - REMOTE_TRANSFORM, ## Object is held via a remote transform - REPARENT, ## Object is held by reparenting -} - ## Method used to grab object at range enum RangedMethod { NONE, ## Ranged grab is not supported @@ -41,26 +41,22 @@ enum RangedMethod { LERP, ## Object lerps to holder } -## Current pickable object state -enum PickableState { - IDLE, ## Object not held - GRABBING_RANGED, ## Object being grabbed at range - HELD, ## Object held -} - enum ReleaseMode { ORIGINAL = -1, ## Preserve original mode when picked up UNFROZEN = 0, ## Release and unfreeze FROZEN = 1, ## Release and freeze } +enum SecondHandGrab { + IGNORE, ## Ignore second grab + SWAP, ## Swap to second hand + SECOND, ## Second hand grab +} + # Default layer for held objects is 17:held-object const DEFAULT_LAYER := 0b0000_0000_0000_0001_0000_0000_0000_0000 -## Priority for grip poses -const GRIP_POSE_PRIORITY = 100 - ## If true, the pickable supports being picked up @export var enabled : bool = true @@ -69,10 +65,7 @@ const GRIP_POSE_PRIORITY = 100 @export var press_to_hold : bool = true ## Layer for this object while picked up -@export_flags_3d_physics var picked_up_layer = DEFAULT_LAYER - -## Method used to hold an object -@export var hold_method : HoldMethod = HoldMethod.REMOTE_TRANSFORM +@export_flags_3d_physics var picked_up_layer : int = DEFAULT_LAYER ## Release mode to use when releasing the object @export var release_mode : ReleaseMode = ReleaseMode.ORIGINAL @@ -80,6 +73,9 @@ const GRIP_POSE_PRIORITY = 100 ## Method used to perform a ranged grab @export var ranged_grab_method : RangedMethod = RangedMethod.SNAP: set = _set_ranged_grab_method +## Second hand grab mode +@export var second_hand_grab : SecondHandGrab = SecondHandGrab.IGNORE + ## Speed for ranged grab @export var ranged_grab_speed : float = 20.0 @@ -96,38 +92,14 @@ var can_ranged_grab: bool = true ## Frozen state to restore to when dropped var restore_freeze : bool = false -## Entity holding this item -var picked_up_by: Node3D = null - -## Controller holding this item (may be null if held by snap-zone) -var by_controller : XRController3D = null - -## What node "holds" the object -var hold_node : Node3D = null - -## Hand holding this item (may be null if held by snap-zone) -var by_hand : XRToolsHand = null - -## Collision hand holding this item (may be null) -var by_collision_hand : XRToolsCollisionHand = null - # Count of 'is_closest' grabbers var _closest_count: int = 0 -# Current state -var _state = PickableState.IDLE - -# Remote transform -var _remote_transform: RemoteTransform3D = null - -# Move-to node for performing remote grab -var _move_to: XRToolsMoveTo = null +# Grab Driver to control position while grabbed +var _grab_driver: XRToolsGrabDriver = null # Array of grab points -var _grab_points : Array = [] - -# Currently active grab-point -var _active_grab_point : XRToolsGrabPoint +var _grab_points : Array[XRToolsGrabPoint] = [] # Dictionary of nodes requesting highlight var _highlight_requests : Dictionary = {} @@ -137,7 +109,6 @@ var _highlighted : bool = false # Remember some state so we can return to it when the user drops the object -@onready var original_parent = get_parent() @onready var original_collision_mask : int = collision_mask @onready var original_collision_layer : int = collision_layer @@ -156,14 +127,46 @@ func _ready(): _grab_points.push_back(grab_point) +# Called when the node exits the tree +func _exit_tree(): + # Skip if not picked up + if not is_instance_valid(_grab_driver): + return + + # Release primary grab + if _grab_driver.primary: + _grab_driver.primary.release() + + # Release secondary grab + if _grab_driver.secondary: + _grab_driver.secondary.release() + + # Test if this object can be picked up -func can_pick_up(_by: Node3D) -> bool: - return enabled and _state == PickableState.IDLE +func can_pick_up(by: Node3D) -> bool: + # Refuse if not enabled + if not enabled: + return false + + # Allow if not held by anything + if not is_picked_up(): + return true + + # Fail if second hand grabbing isn't allowed + if second_hand_grab == SecondHandGrab.IGNORE: + return false + + # Fail if either pickup isn't by a hand + if not _grab_driver.primary.pickup or not by is XRToolsFunctionPickup: + return false + + # Allow second hand grab + return true # Test if this object is picked up -func is_picked_up(): - return _state == PickableState.HELD +func is_picked_up() -> bool: + return _grab_driver and _grab_driver.primary # action is called when user presses the action button while holding this object @@ -195,42 +198,58 @@ func request_highlight(from : Node, on : bool = true) -> void: emit_signal("highlight_updated", self, _highlighted) -func drop_and_free(): - if picked_up_by: - picked_up_by.drop_object() +func drop(): + # Skip if not picked up + if not is_picked_up(): + return + # Request secondary grabber to drop + if _grab_driver.secondary: + _grab_driver.secondary.by.drop_object() + + # Request primary grabber to drop + _grab_driver.primary.by.drop_object() + + +func drop_and_free(): + drop() queue_free() # Called when this object is picked up -func pick_up(by: Node3D, with_controller: XRController3D) -> void: - # Skip if disabled or already picked up - if not enabled or _state != PickableState.IDLE: +func pick_up(by: Node3D) -> void: + # Skip if not enabled + if not enabled: return - if picked_up_by: - let_go(Vector3.ZERO, Vector3.ZERO) + # Find the grabber information + var grabber := Grabber.new(by) - # remember who picked us up - picked_up_by = by - by_controller = with_controller - hold_node = with_controller if with_controller else by - by_hand = XRToolsHand.find_instance(by_controller) - by_collision_hand = XRToolsCollisionHand.find_instance(by_controller) - _active_grab_point = _get_grab_point(by) + # Test if we're already picked up: + if is_picked_up(): + # Ignore if we don't support second-hand grab + if second_hand_grab == SecondHandGrab.IGNORE: + print_verbose("%s> second-hand grab not enabled" % name) + return - # If we have been picked up by a hand then apply the hand-pose-override - # from the grab-point. - if by_hand and _active_grab_point: - var grab_point_hand := _active_grab_point as XRToolsGrabPointHand - if grab_point_hand and grab_point_hand.hand_pose: - by_hand.add_pose_override(self, GRIP_POSE_PRIORITY, grab_point_hand.hand_pose) + # Ignore if either pickup isn't by a hand + if not _grab_driver.primary.pickup or not grabber.pickup: + return - # If we have been picked up by a collision hand then add collision - # exceptions to prevent the hand and pickable colliding. - if by_collision_hand: - add_collision_exception_with(by_collision_hand) - by_collision_hand.add_collision_exception_with(self) + # Construct the second grab + if second_hand_grab != SecondHandGrab.SWAP: + # Grab the object + var by_grab_point := _get_grab_point(by, _grab_driver.primary.point) + var grab := Grab.new(grabber, self, by_grab_point, true) + _grab_driver.add_grab(grab) + + # Report the secondary grab + grabbed.emit(self, by) + return + + # Swapping hands, let go with the primary grab + print_verbose("%s> letting go to swap hands" % name) + let_go(_grab_driver.primary.by, Vector3.ZERO, Vector3.ZERO) # Remember the mode before pickup match release_mode: @@ -248,36 +267,61 @@ func pick_up(by: Node3D, with_controller: XRController3D) -> void: collision_layer = picked_up_layer collision_mask = 0 + # Find a suitable primary hand grab + var by_grab_point := _get_grab_point(by, null) + + # Construct the grab driver if by.picked_up_ranged: if ranged_grab_method == RangedMethod.LERP: - _start_ranged_grab() + var grab := Grab.new(grabber, self, by_grab_point, false) + _grab_driver = XRToolsGrabDriver.create_lerp(self, grab, ranged_grab_speed) else: - _do_snap_grab() - elif _active_grab_point: - _do_snap_grab() + var grab := Grab.new(grabber, self, by_grab_point, false) + _grab_driver = XRToolsGrabDriver.create_snap(self, grab) else: - _do_precise_grab() + var grab := Grab.new(grabber, self, by_grab_point, true) + _grab_driver = XRToolsGrabDriver.create_snap(self, grab) + + # Report picked up and grabbed + picked_up.emit(self) + grabbed.emit(self, by) # Called when this object is dropped -func let_go(p_linear_velocity: Vector3, p_angular_velocity: Vector3) -> void: - # Skip if idle - if _state == PickableState.IDLE: +func let_go(by: Node3D, p_linear_velocity: Vector3, p_angular_velocity: Vector3) -> void: + # Skip if not picked up + if not is_picked_up(): return - # If held then detach from holder - if _state == PickableState.HELD: - match hold_method: - HoldMethod.REPARENT: - var original_transform = global_transform - picked_up_by.remove_child(self) - original_parent.add_child(self) - global_transform = original_transform + # Get the grab information + var grab := _grab_driver.get_grab(by) + if not grab: + return - HoldMethod.REMOTE_TRANSFORM: - _remote_transform.remote_path = NodePath() - _remote_transform.queue_free() - _remote_transform = null + # Remove the grab from the driver and release the grab + _grab_driver.remove_grab(grab) + grab.release() + + # Test if still grabbing + if _grab_driver.primary: + # Test if we need to swap grab-points + if is_instance_valid(_grab_driver.primary.hand_point): + # Verify the current primary grab point is a valid primary grab point + if _grab_driver.primary.hand_point.mode != XRToolsGrabPointHand.Mode.SECONDARY: + return + + # Find a more suitable grab-point + var new_grab_point := _get_grab_point(_grab_driver.primary.by, null) + print_verbose("%s> held only by secondary, swapping grab points" % name) + switch_active_grab_point(new_grab_point) + + # Grab is still good + return + + # Drop the grab-driver + print_verbose("%s> dropping" % name) + _grab_driver.discard() + _grab_driver = null # Restore RigidBody mode freeze = restore_freeze @@ -288,185 +332,67 @@ func let_go(p_linear_velocity: Vector3, p_angular_velocity: Vector3) -> void: linear_velocity = p_linear_velocity angular_velocity = p_angular_velocity - # If we are held by a hand then remove any hand-pose-override we may have - # given it. - if by_hand: - by_hand.remove_pose_override(self) - - # If we are held by a cillision hand then remove any collision exceptions - # we may have added. - if by_collision_hand: - remove_collision_exception_with(by_collision_hand) - by_collision_hand.remove_collision_exception_with(self) - - # we are no longer picked up - _state = PickableState.IDLE - picked_up_by = null - by_controller = null - by_hand = null - by_collision_hand = null - hold_node = null - - # Stop any XRToolsMoveTo being used for remote grabbing - if _move_to: - _move_to.stop() - _move_to.queue_free() - _move_to = null - # let interested parties know - emit_signal("dropped", self) + dropped.emit(self) + + +## Get the node currently holding this object +func get_picked_up_by() -> Node3D: + # Skip if not picked up + if not is_picked_up(): + return null + + # Get the primary pickup + return _grab_driver.primary.by ## Get the controller currently holding this object func get_picked_up_by_controller() -> XRController3D: - return by_controller + # Skip if not picked up + if not is_picked_up(): + return null - -## Get the hand currently holding this object -func get_picked_up_by_hand() -> XRToolsHand: - return by_hand + # Get the primary pickup controller + return _grab_driver.primary.controller ## Get the active grab-point this object is held by func get_active_grab_point() -> XRToolsGrabPoint: - return _active_grab_point + # Skip if not picked up + if not is_picked_up(): + return null + + return _grab_driver.primary.point ## Switch the active grab-point for this object func switch_active_grab_point(grab_point : XRToolsGrabPoint): - # Verify switching from one grab point to another - if not _active_grab_point or not grab_point or _state != PickableState.HELD: - return + # Skip if not picked up + if not is_picked_up(): + return null - # Set the new active grab-point - _active_grab_point = grab_point - - # Update the hold transform - match hold_method: - HoldMethod.REMOTE_TRANSFORM: - # Update the remote transform - _remote_transform.transform = _active_grab_point.transform.inverse() - - HoldMethod.REPARENT: - # Update our transform - transform = _active_grab_point.global_transform.inverse() * global_transform - - # Update the pose - if by_hand and _active_grab_point: - var grab_point_hand := _active_grab_point as XRToolsGrabPointHand - if grab_point_hand and grab_point_hand.hand_pose: - by_hand.add_pose_override(self, GRIP_POSE_PRIORITY, grab_point_hand.hand_pose) - else: - by_hand.remove_pose_override(self) + # Apply the grab point + _grab_driver.primary.set_grab_point(grab_point) -func _start_ranged_grab() -> void: - # Set state to grabbing at range and enable processing - _state = PickableState.GRABBING_RANGED +## Find the most suitable grab-point for the grabber +func _get_grab_point(grabber : Node3D, current : XRToolsGrabPoint) -> XRToolsGrabPoint: + # Find the best grab-point + var fitness := 0.0 + var point : XRToolsGrabPoint = null + for p in _grab_points: + var f := p.can_grab(grabber, current) + if f > fitness: + fitness = f + point = p - # Calculate the transform offset - var offset : Transform3D - if _active_grab_point: - offset = _active_grab_point.transform.inverse() - else: - offset = Transform3D.IDENTITY + # Resolve redirection + while point is XRToolsGrabPointRedirect: + point = point.target - # Create a XRToolsMoveTo to perform the remote-grab. The remote grab will move - # us to the pickup object at the ranged-grab speed, and also takes into account - # the center-pickup position - _move_to = XRToolsMoveTo.new() - _move_to.start(self, hold_node, offset, ranged_grab_speed) - _move_to.move_complete.connect(_ranged_grab_complete) - self.add_child(_move_to) - - -func _ranged_grab_complete() -> void: - # Discard the XRToolsMoveTo performing the remote-grab - _move_to.queue_free() - _move_to = null - - # Perform the snap grab - _do_snap_grab() - - -func _do_snap_grab() -> void: - # Set state to held - _state = PickableState.HELD - - # Perform the hold - match hold_method: - HoldMethod.REMOTE_TRANSFORM: - # Calculate the snap transform for remote-transforming - var snap_transform: Transform3D - if _active_grab_point: - snap_transform = _active_grab_point.transform.inverse() - else: - snap_transform = Transform3D.IDENTITY - - # Construct the remote transform - _remote_transform = RemoteTransform3D.new() - _remote_transform.set_name("PickupRemoteTransform") - hold_node.add_child(_remote_transform) - _remote_transform.transform = snap_transform - _remote_transform.remote_path = _remote_transform.get_path_to(self) - - HoldMethod.REPARENT: - # Calculate the snap transform for reparenting - var snap_transform: Transform3D - if _active_grab_point: - snap_transform = _active_grab_point.global_transform.inverse() * global_transform - else: - snap_transform = Transform3D.IDENTITY - - # Reparent to the holder with snap transform - original_parent.remove_child(self) - hold_node.add_child(self) - transform = snap_transform - - # Emit the picked up signal - emit_signal("picked_up", self) - - -func _do_precise_grab() -> void: - # Set state to held - _state = PickableState.HELD - - # Reparent to the holder - match hold_method: - HoldMethod.REMOTE_TRANSFORM: - # Calculate the precise transform for remote-transforming - var precise_transform = hold_node.global_transform.inverse() * global_transform - - # Construct the remote transform - _remote_transform = RemoteTransform3D.new() - _remote_transform.set_name("PickupRemoteTransform") - hold_node.add_child(_remote_transform) - _remote_transform.transform = hold_node.global_transform.inverse() * global_transform - _remote_transform.remote_path = _remote_transform.get_path_to(self) - - HoldMethod.REPARENT: - # Calculate the precise transform for reparenting - var precise_transform = global_transform - - # Reparent to the holder with precise transform - original_parent.remove_child(self) - hold_node.add_child(self) - global_transform = precise_transform - - # Emit the picked up signal - emit_signal("picked_up", self) - - -## Find the first grab-point for the grabber -func _get_grab_point(_grabber : Node) -> XRToolsGrabPoint: - # Iterate over all grab points - for g in _grab_points: - var grab_point : XRToolsGrabPoint = g - if grab_point.can_grab(_grabber): - return grab_point - - # No suitable grab-point found - return null + # Return the best grab point + print_verbose("%s> picked grab-point %s" % [name, point]) + return point func _set_ranged_grab_method(new_value: int) -> void: diff --git a/addons/godot-xr-tools/objects/snap_zone.gd b/addons/godot-xr-tools/objects/snap_zone.gd index dcce610..8b4afc7 100644 --- a/addons/godot-xr-tools/objects/snap_zone.gd +++ b/addons/godot-xr-tools/objects/snap_zone.gd @@ -137,17 +137,17 @@ func action(): # Ignore highlighting requests from XRToolsFunctionPickup func request_highlight(from : Node, on : bool = true) -> void: - if picked_up_object: + if is_instance_valid(picked_up_object): picked_up_object.request_highlight(from, on) # Pickable Method: Object being grabbed from this snap zone -func pick_up(_by: Node3D, _with_controller: XRController3D) -> void: +func pick_up(_by: Node3D) -> void: pass # Pickable Method: Player never graps snap-zone -func let_go(_p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void: +func let_go(_by: Node3D, _p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void: pass @@ -157,7 +157,7 @@ func drop_object() -> void: return # let go of this object - picked_up_object.let_go(Vector3.ZERO, Vector3.ZERO) + picked_up_object.let_go(self, Vector3.ZERO, Vector3.ZERO) picked_up_object = null has_dropped.emit() highlight_updated.emit(self, enabled) @@ -251,7 +251,7 @@ func pick_up_object(target: Node3D) -> void: player.stream = stash_sound player.play() - target.pick_up(self, null) + target.pick_up(self) # If object picked up then emit signal if is_instance_valid(picked_up_object): diff --git a/addons/godot-xr-tools/objects/viewport_2d_in_3d.gd b/addons/godot-xr-tools/objects/viewport_2d_in_3d.gd index 6386cab..ba87a7f 100644 --- a/addons/godot-xr-tools/objects/viewport_2d_in_3d.gd +++ b/addons/godot-xr-tools/objects/viewport_2d_in_3d.gd @@ -80,6 +80,15 @@ const DEFAULT_LAYER := 0b0000_0000_0101_0000_0000_0000_0000_0001 ## Update throttle property @export var throttle_fps : float = 30.0 +# Input property group +@export_group("Input") + +## Allow physical keyboard input to viewport +@export var input_keyboard : bool = true + +## Allow gamepad input to viewport +@export var input_gamepad : bool = false + # Rendering property group @export_group("Rendering") @@ -197,9 +206,17 @@ func _on_pointer_event(event : XRToolsPointerEvent) -> void: pointer_event.emit(event) -# Handler for input eventsd +# Handler for input events func _input(event): - $Viewport.push_input(event) + # Map keyboard events to the viewport if enabled + if input_keyboard and (event is InputEventKey or event is InputEventShortcut): + $Viewport.push_input(event) + return + + # Map gamepad events to the viewport if enable + if input_gamepad and (event is InputEventJoypadButton or event is InputEventJoypadMotion): + $Viewport.push_input(event) + return # Process event @@ -318,10 +335,10 @@ func set_filter(new_filter: bool) -> void: func _update_screen_size() -> void: $Screen.mesh.size = screen_size $StaticBody3D.screen_size = screen_size - $StaticBody3D/CollisionShape3D.shape.extents = Vector3( - screen_size.x * 0.5, - screen_size.y * 0.5, - 0.01) + $StaticBody3D/CollisionShape3D.shape.size = Vector3( + screen_size.x, + screen_size.y, + 0.02) # Enabled update handler @@ -436,8 +453,14 @@ func _update_render() -> void: # If using a temporary material then update transparency if _screen_material and not material: - _screen_material.flags_transparent = transparent != TransparancyMode.OPAQUE - _screen_material.params_use_alpha_scissor = transparent == TransparancyMode.SCISSOR + # Set the transparancy mode + match transparent: + TransparancyMode.OPAQUE: + _screen_material.transparency = BaseMaterial3D.TRANSPARENCY_DISABLED + TransparancyMode.TRANSPARENT: + _screen_material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA + TransparancyMode.SCISSOR: + _screen_material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR # Set the viewport background transparency mode and force a redraw $Viewport.transparent_bg = transparent != TransparancyMode.OPAQUE diff --git a/addons/godot-xr-tools/objects/world_grab_area.gd b/addons/godot-xr-tools/objects/world_grab_area.gd new file mode 100644 index 0000000..f3180e7 --- /dev/null +++ b/addons/godot-xr-tools/objects/world_grab_area.gd @@ -0,0 +1,64 @@ +@tool +@icon("res://addons/godot-xr-tools/editor/icons/hand.svg") +class_name XRToolsWorldGrabArea +extends Area3D + + +## XR Tools World-Grab Area +## +## This script adds world-grab areas to an environment +## +## For world-grab to work, the player must have an [XRToolsMovementWorldGrab] +## node configured appropriately. + + +## If true, the grip control must be held to keep holding the climbable +var press_to_hold : bool = true + +## Dictionary of temporary grab-handles indexed by the pickup node. +var grab_locations := {} + + +# Add support for is_xr_class on XRTools classes +func is_xr_class(name : String) -> bool: + return name == "XRToolsWorldGrabArea" + + +# Called by XRToolsFunctionPickup +func is_picked_up() -> bool: + return false + +func can_pick_up(_by: Node3D) -> bool: + return true + +# Called by XRToolsFunctionPickup when user presses the action button while holding this object +func action(): + pass + +# Ignore highlighting requests from XRToolsFunctionPickup +func request_highlight(_from, _on) -> void: + pass + +# Called by XRToolsFunctionPickup when this is picked up by a controller +func pick_up(by: Node3D, _with_controller: XRController3D) -> void: + # Get the ID to save the grab handle under + var id = by.get_instance_id() + + # Get or construct the grab handle + var handle = grab_locations.get(id) + if not handle: + handle = Node3D.new() + add_child(handle) + grab_locations[id] = handle + + # Set the handles global transform. As it's a child of this + # climbable it will move as the climbable moves + handle.global_transform = by.global_transform + +# Called by XRToolsFunctionPickup when this is let go by a controller +func let_go(_by: Node3D, _p_linear_velocity: Vector3, _p_angular_velocity: Vector3) -> void: + pass + +# Get the grab handle +func get_grab_handle(p: Node3D) -> Node3D: + return grab_locations.get(p.get_instance_id()) diff --git a/addons/godot-xr-tools/objects/world_grab_area.tscn b/addons/godot-xr-tools/objects/world_grab_area.tscn new file mode 100644 index 0000000..925abaa --- /dev/null +++ b/addons/godot-xr-tools/objects/world_grab_area.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://57q7hhomocdh"] + +[ext_resource type="Script" path="res://addons/godot-xr-tools/objects/world_grab_area.gd" id="1_uxhq5"] + +[node name="WorldGrabArea" type="Area3D"] +script = ExtResource("1_uxhq5") diff --git a/addons/godot-xr-tools/player/player_body.gd b/addons/godot-xr-tools/player/player_body.gd index 9efb51d..7bba58c 100644 --- a/addons/godot-xr-tools/player/player_body.gd +++ b/addons/godot-xr-tools/player/player_body.gd @@ -65,6 +65,9 @@ const NEAR_GROUND_DISTANCE := 1.0 ## Maximum player height @export var player_height_max : float = 2.5 +## Slew-rate for player height overriding (button-crouch) +@export var player_height_rate : float = 4.0 + ## Eyes forward offset from center of body in player_radius units @export_range(0.0, 1.0) var eye_forward_offset : float = 0.5 @@ -130,14 +133,20 @@ var up_player := Vector3.UP # Array of [XRToolsMovementProvider] nodes for the player var _movement_providers := Array() -# Jump cool-down counter -var _jump_cooldown := 0 - # Player height overrides var _player_height_overrides := { } -# Player height override (enabled when non-negative) -var _player_height_override : float = -1.0 +# Player height override - current height +var _player_height_override_current : float = 0.0 + +# Player height override - target height +var _player_height_override_target : float = 0.0 + +# Player height override - enabled +var _player_height_override_enabled : bool = false + +# Player height override - lerp between real and override +var _player_height_override_lerp : float = 0.0 # Previous ground node var _previous_ground_node : Node3D = null @@ -151,6 +160,9 @@ var _previous_ground_global : Vector3 = Vector3.ZERO # Player body Collision node var _collision_node : CollisionShape3D +# Player head shape cast +var _head_shape_cast : ShapeCast3D + ## XROrigin3D node @onready var origin_node : XROrigin3D = XRHelpers.get_xr_origin(self) @@ -193,6 +205,16 @@ func _ready(): _collision_node.transform.origin = Vector3(0.0, 0.8, 0.0) add_child(_collision_node) + # Create the shape-cast for head collisions + _head_shape_cast = ShapeCast3D.new() + _head_shape_cast.enabled = false + _head_shape_cast.margin = 0.01 + _head_shape_cast.collision_mask = collision_mask + _head_shape_cast.max_results = 1 + _head_shape_cast.shape = SphereShape3D.new() + _head_shape_cast.shape.radius = player_radius + add_child(_head_shape_cast) + # Get the movement providers ordered by increasing order _movement_providers = get_tree().get_nodes_in_group("movement_providers") _movement_providers.sort_custom(sort_by_order) @@ -240,10 +262,6 @@ func _physics_process(delta: float): set_physics_process(false) return - # Decrement the jump cool-down on each physics update - if _jump_cooldown: - _jump_cooldown -= 1 - # Calculate the players "up" direction and plane up_player = origin_node.global_transform.basis.y @@ -252,7 +270,7 @@ func _physics_process(delta: float): gravity = gravity_state.total_gravity # Update the kinematic body to be under the camera - _update_body_under_camera() + _update_body_under_camera(delta) # Allow the movement providers a chance to perform pre-movement updates. The providers can: # - Adjust the gravity direction @@ -325,14 +343,15 @@ func teleport(target : Transform3D) -> void: ## Request a jump func request_jump(skip_jump_velocity := false): - # Skip if cooling down from a previous jump - if _jump_cooldown: - return; - # Skip if not on ground if !on_ground: return + # Skip if our vertical velocity is not essentially the same as the ground + var ground_relative := velocity - ground_velocity + if abs(ground_relative.dot(up_player)) > 0.01: + return + # Skip if jump disabled on this ground var jump_velocity := XRToolsGroundPhysicsSettings.get_jump_velocity( ground_physics, default_physics) @@ -351,7 +370,6 @@ func request_jump(skip_jump_velocity := false): # Report the jump emit_signal("player_jumped") - _jump_cooldown = 4 ## This method moves the players body using the provided velocity. Movement ## providers may use this function if they are exclusively driving the player. @@ -443,9 +461,15 @@ func override_player_height(key, value: float = -1.0): else: _player_height_overrides[key] = value - # Set or clear the override value + # Evaluate whether a height override is active var override = _player_height_overrides.values().min() - _player_height_override = override if override != null else -1.0 + if override != null: + # Enable override with the target height + _player_height_override_target = override + _player_height_override_enabled = true + else: + # Disable height override + _player_height_override_enabled = false # Estimate body forward direction func _estimate_body_forward_dir() -> Vector3: @@ -482,7 +506,7 @@ func _estimate_body_forward_dir() -> Vector3: return forward # This method updates the player body to match the player position -func _update_body_under_camera(): +func _update_body_under_camera(delta : float): # Initially calibration of player height if player_calibrate_height: calibrate_player_height() @@ -496,13 +520,77 @@ func _update_body_under_camera(): player_height_min * XRServer.world_scale, player_height_max * XRServer.world_scale) - # Allow forced overriding of height - if _player_height_override >= 0.0: - player_height = _player_height_override * XRServer.world_scale + # Manage any player height overriding such as: + # - Slewing between software override heights + # - Slewing the lerp between player and software-override heights + if _player_height_override_enabled: + # Update the current override height to the target height + if _player_height_override_lerp <= 0.0: + # Override not in use, snap to target + _player_height_override_current = _player_height_override_target + elif _player_height_override_current < _player_height_override_target: + # Override in use, slew up to target override height + _player_height_override_current = min( + _player_height_override_current + player_height_rate * delta, + _player_height_override_target) + elif _player_height_override_current > _player_height_override_target: + # Override in use, slew down to target override height + _player_height_override_current = max( + _player_height_override_current - player_height_rate * delta, + _player_height_override_target) + + # Slew towards height being controlled by software-override + _player_height_override_lerp = min( + _player_height_override_lerp + player_height_rate * delta, + 1.0) + else: + # Slew towards height being controlled by player + _player_height_override_lerp = max( + _player_height_override_lerp - player_height_rate * delta, + 0.0) + + # Blend the player height between the player and software-override + player_height = lerp( + player_height, + _player_height_override_current, + _player_height_override_lerp) # Ensure player height makes mathematical sense player_height = max(player_height, player_radius) + # Test if the player is trying to get taller + var current_height : float = _collision_node.shape.height + if player_height > current_height: + # Calculate how tall we would like to get this frame + var target_height : float = min( + current_height + player_height_rate * delta, + player_height) + + # Calculate a reduced height - slghtly smaller than the current player + # height so we can cast a virtual head up and probe the where we hit the + # ceiling. + var reduced_height : float = max( + current_height - 0.1, + player_radius) + + # Calculate how much we want to grow to hit the target height + var grow := target_height - reduced_height + + # Cast the virtual head up from the reduced-height position up to the + # target height to check for ceiling collisions. + _head_shape_cast.shape.radius = player_radius + _head_shape_cast.transform.origin.y = reduced_height - player_radius + _head_shape_cast.collision_mask = collision_mask + _head_shape_cast.target_position = Vector3.UP * grow + _head_shape_cast.force_shapecast_update() + + # Use the ceiling collision information to decide how much to grow the + # player height + var safe := _head_shape_cast.get_closest_collision_safe_fraction() + player_height = max( + reduced_height + grow * safe, + current_height) + # Adjust the collision shape to match the player geometry _collision_node.shape.radius = player_radius _collision_node.shape.height = player_height @@ -644,7 +732,7 @@ func _apply_velocity_and_control(delta: float): # Detect if bounce should be performed if bounciness > 0.0 and magnitude >= bounce_threshold: - local_velocity += 2 * collision.normal * magnitude * bounciness + local_velocity += 2 * collision.get_normal() * magnitude * bounciness velocity = local_velocity + ground_velocity emit_signal("player_bounced", collision_node, magnitude) diff --git a/addons/godot-xr-tools/player/poke/poke.tscn b/addons/godot-xr-tools/player/poke/poke.tscn index dfef510..cf0690a 100644 --- a/addons/godot-xr-tools/player/poke/poke.tscn +++ b/addons/godot-xr-tools/player/poke/poke.tscn @@ -14,7 +14,7 @@ height = 0.01 radial_segments = 32 rings = 16 -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yhep2"] +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_g1b1h"] transparency = 1 shading_mode = 0 albedo_color = Color(0.8, 0.8, 1, 0.5) @@ -22,10 +22,11 @@ albedo_color = Color(0.8, 0.8, 1, 0.5) [node name="Poke" type="Node3D"] script = ExtResource("1") -[node name="PokeBody" type="StaticBody3D" parent="."] +[node name="PokeBody" type="AnimatableBody3D" parent="."] top_level = true collision_layer = 131072 collision_mask = 4259839 +sync_to_physics = false script = ExtResource("2") [node name="CollisionShape" type="CollisionShape3D" parent="PokeBody"] @@ -33,7 +34,7 @@ shape = SubResource("1") [node name="MeshInstance" type="MeshInstance3D" parent="PokeBody"] mesh = SubResource("2") -surface_material_override/0 = SubResource("StandardMaterial3D_yhep2") +surface_material_override/0 = SubResource("StandardMaterial3D_g1b1h") [connection signal="body_contact_end" from="PokeBody" to="." method="_on_PokeBody_body_contact_end"] [connection signal="body_contact_start" from="PokeBody" to="." method="_on_PokeBody_body_contact_start"] diff --git a/addons/godot-xr-tools/plugin.cfg b/addons/godot-xr-tools/plugin.cfg index 7e18202..d8bf9c4 100644 --- a/addons/godot-xr-tools/plugin.cfg +++ b/addons/godot-xr-tools/plugin.cfg @@ -3,5 +3,5 @@ name="Godot XR Tools" description="Godot XR Tools plugin" author="Bastiaan Olij and Contributors" -version="4.2.1" +version="4.3.0" script="plugin.gd" diff --git a/addons/godot-xr-tools/staging/loading_screen.tscn b/addons/godot-xr-tools/staging/loading_screen.tscn index 749402e..305c89f 100644 --- a/addons/godot-xr-tools/staging/loading_screen.tscn +++ b/addons/godot-xr-tools/staging/loading_screen.tscn @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/godot-xr-tools/staging/loading_screen.gd" id="2"] [ext_resource type="Shader" uid="uid://4i0pwdtfmtsv" path="res://addons/godot-xr-tools/staging/loading_screen/loading_screen_shader.tres" id="3"] -[ext_resource type="Texture2D" uid="uid://b77u06jwo4l5y" path="res://addons/godot-xr-tools/assets/misc/progress_bar.png" id="4"] -[ext_resource type="Texture2D" uid="uid://dbbxlk5acoxfg" path="res://addons/godot-xr-tools/assets/misc/Hold trigger to continue.png" id="5"] +[ext_resource type="Texture2D" uid="uid://clbtsf0ahb3fm" path="res://addons/godot-xr-tools/assets/misc/progress_bar.png" id="4"] +[ext_resource type="Texture2D" uid="uid://ocyj01x5mtt7" path="res://addons/godot-xr-tools/assets/misc/Hold trigger to continue.png" id="5"] [ext_resource type="PackedScene" uid="uid://cymteydkxagpp" path="res://addons/godot-xr-tools/misc/hold_button.tscn" id="6"] [sub_resource type="Curve" id="21"] diff --git a/addons/godot-xr-tools/staging/staging.gd b/addons/godot-xr-tools/staging/staging.gd index 26fd7ba..a826222 100644 --- a/addons/godot-xr-tools/staging/staging.gd +++ b/addons/godot-xr-tools/staging/staging.gd @@ -196,15 +196,28 @@ func load_scene(p_scene_path : String, user_data = null) -> void: ResourceLoader.load_threaded_request(p_scene_path) # Loop waiting for the scene to load + var res : ResourceLoader.ThreadLoadStatus while true: var progress := [] - var res := ResourceLoader.load_threaded_get_status(p_scene_path, progress) + res = ResourceLoader.load_threaded_get_status(p_scene_path, progress) if res != ResourceLoader.THREAD_LOAD_IN_PROGRESS: break; $LoadingScreen.progress = progress[0] await get_tree().create_timer(0.1).timeout + # Handle load error + if res != ResourceLoader.THREAD_LOAD_LOADED: + # Report the error to the log and console + push_error("Error ", res, " loading resource ", p_scene_path) + + # Halt if running in the debugger + # gdlint:ignore=expression-not-assigned + breakpoint + + # Terminate with a non-zero error code to indicate failure + get_tree().quit(1) + # Get the loaded scene new_scene = ResourceLoader.load_threaded_get(p_scene_path) diff --git a/addons/godot-xr-tools/staging/staging.tscn b/addons/godot-xr-tools/staging/staging.tscn index 7fc0b02..d78690b 100644 --- a/addons/godot-xr-tools/staging/staging.tscn +++ b/addons/godot-xr-tools/staging/staging.tscn @@ -4,7 +4,7 @@ [ext_resource type="PackedScene" uid="uid://bqumugyvkct4r" path="res://addons/godot-xr-tools/staging/loading_screen.tscn" id="2"] [ext_resource type="Environment" uid="uid://ckiwtcdsam7ed" path="res://addons/godot-xr-tools/staging/staging_env.tres" id="3_40x3a"] [ext_resource type="Shader" path="res://addons/godot-xr-tools/staging/fade.gdshader" id="4"] -[ext_resource type="PackedScene" uid="uid://cjccb67fjl4aw" path="res://addons/godot-xr-tools/misc/vr_common_shader_cache.tscn" id="5"] +[ext_resource type="PackedScene" path="res://addons/godot-xr-tools/misc/vr_common_shader_cache.tscn" id="5"] [ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="6_balvx"] [sub_resource type="QuadMesh" id="4"] diff --git a/addons/godot-xr-tools/user_settings/user_settings.gd b/addons/godot-xr-tools/user_settings/user_settings.gd index 36bc920..d00ebaf 100644 --- a/addons/godot-xr-tools/user_settings/user_settings.gd +++ b/addons/godot-xr-tools/user_settings/user_settings.gd @@ -43,9 +43,9 @@ var webxr_auto_primary := 0 # Called when the node enters the scene tree for the first time. func _ready(): - # var webxr_interface = XRServer.find_interface("WebXR") - # if webxr_interface: - # XRServer.tracker_added.connect(self._on_webxr_tracker_added) + var webxr_interface = XRServer.find_interface("WebXR") + if webxr_interface: + XRServer.tracker_added.connect(self._on_webxr_tracker_added) _load()