diff --git a/.gitattributes b/.gitattributes index 753fc59..fe0b2ce 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,6 +10,7 @@ *.tres filter=lfs diff=lfs merge=lfs -text *.bin filter=lfs diff=lfs merge=lfs -text *.blend filter=lfs diff=lfs merge=lfs -text +*.glb filter=lfs diff=lfs merge=lfs -text *.gltf filter=lfs diff=lfs merge=lfs -text *.obj filter=lfs diff=lfs merge=lfs -text *.mtl filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md index 4ac3ccf..a1cad4b 100644 --- a/README.md +++ b/README.md @@ -117,15 +117,15 @@ It is also possible to bubble up information by returning a dictionary from a fu | Function called | Args | Description | | -- | -- | -- | -| `_on_click` | `[event: EventRay]` | The back trigger button has been pressed and released | -| `_on_press_down` | `[event: EventRay]` | The back trigger button has been pressed down | -| `_on_press_move` | `[event: EventRay]` | The back trigger button has been moved while pressed down | -| `_on_press_up` | `[event: EventRay]` | The back trigger button has been released | -| `_on_grab_down` | `[event: EventRay]` | The side grab button been pressed down | -| `_on_grab_move` | `[event: EventRay]` | The side grab button been pressed down | -| `_on_grab_up` | `[event: EventRay]` | The side grab button been released | -| `_on_ray_enter` | `[event: EventRay]` | The ray-cast enters the the collision body | -| `_on_ray_leave` | `[event: EventRay]` | The ray-cast leaves the the collision body | +| `_on_click` | `[event: EventPointer]` | The back trigger button has been pressed and released | +| `_on_press_down` | `[event: EventPointer]` | The back trigger button has been pressed down | +| `_on_press_move` | `[event: EventPointer]` | The back trigger button has been moved while pressed down | +| `_on_press_up` | `[event: EventPointer]` | The back trigger button has been released | +| `_on_grab_down` | `[event: EventPointer]` | The side grab button been pressed down | +| `_on_grab_move` | `[event: EventPointer]` | The side grab button been pressed down | +| `_on_grab_up` | `[event: EventPointer]` | The side grab button been released | +| `_on_ray_enter` | `[event: EventPointer]` | The ray-cast enters the the collision body | +| `_on_ray_leave` | `[event: EventPointer]` | The ray-cast leaves the the collision body | | `_on_key_down` | `[event: EventKey]` | The ray-cast leaves the the collision body | | `_on_key_up` | `[event: EventKey]` | The ray-cast leaves the the collision body | | `_on_focus_in` | `[event: EventFocus]` | The node is got focused | @@ -140,8 +140,9 @@ Thus I've decided to use a custom event system that is similar to the one used i | Group | Description | | -- | -- | | `entity` | Marks the object as being an entity placed in space | -| `ui_focus` | The element can be focused | -| `ui_focus_skip` | The focus will not be reset. Useful for keyboard | +| `ui_focus` | The element can be focused, can be a parent | +| `ui_focus_skip` | Focus checking on this element will be skipped | +| `ui_focus_stop` | The focus will not be reset. Useful for keyboard | ### Functions 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 ef1c2d3..4b675af 100644 --- a/addons/godot-xr-tools/hands/scenes/highpoly/left_hand.tscn +++ b/addons/godot-xr-tools/hands/scenes/highpoly/left_hand.tscn @@ -1,40 +1,40 @@ [gd_scene load_steps=13 format=3 uid="uid://njx823gyk04n"] -[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://bh786yhm5v4fh" 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_x12eo"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_e6byy"] animation = &"Grip" -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_kw2gg"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_bs8g1"] animation = &"Grip" -[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_o8j0s"] +[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_675c4"] 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_cxcnq"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_2ssci"] animation = &"Grip 5" -[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_yn70n"] +[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_narw6"] 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_v8owg"] +[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_wp4n0"] graph_offset = Vector2(-536, 11) -nodes/ClosedHand1/node = SubResource("AnimationNodeAnimation_x12eo") +nodes/ClosedHand1/node = SubResource("AnimationNodeAnimation_e6byy") nodes/ClosedHand1/position = Vector2(-600, 300) -nodes/ClosedHand2/node = SubResource("AnimationNodeAnimation_kw2gg") +nodes/ClosedHand2/node = SubResource("AnimationNodeAnimation_bs8g1") nodes/ClosedHand2/position = Vector2(-360, 300) -nodes/Grip/node = SubResource("AnimationNodeBlend2_o8j0s") +nodes/Grip/node = SubResource("AnimationNodeBlend2_675c4") nodes/Grip/position = Vector2(0, 20) -nodes/OpenHand/node = SubResource("AnimationNodeAnimation_cxcnq") +nodes/OpenHand/node = SubResource("AnimationNodeAnimation_2ssci") nodes/OpenHand/position = Vector2(-600, 100) -nodes/Trigger/node = SubResource("AnimationNodeBlend2_yn70n") +nodes/Trigger/node = SubResource("AnimationNodeBlend2_narw6") nodes/Trigger/position = Vector2(-360, 20) node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"] @@ -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_v8owg") +tree_root = SubResource("AnimationNodeBlendTree_wp4n0") anim_player = NodePath("../Hand_Nails_L/AnimationPlayer") active = true parameters/Grip/blend_amount = 0.0 diff --git a/assets/immersive_home/button.mtl b/assets/immersive_home/button.mtl new file mode 100644 index 0000000..7fe5d29 --- /dev/null +++ b/assets/immersive_home/button.mtl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86eced068bcbed2d727b107358398aff996d92dddedaeff7277430262507bcb1 +size 233 diff --git a/assets/immersive_home/button.obj b/assets/immersive_home/button.obj new file mode 100644 index 0000000..d34e459 --- /dev/null +++ b/assets/immersive_home/button.obj @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26fbc4673b78bf69b4955cd131e2484f705d833528cb3040223434c8bec9fe18 +size 92814 diff --git a/assets/immersive_home/button.obj.import b/assets/immersive_home/button.obj.import new file mode 100644 index 0000000..b073cd4 --- /dev/null +++ b/assets/immersive_home/button.obj.import @@ -0,0 +1,21 @@ +[remap] + +importer="wavefront_obj" +importer_version=1 +type="Mesh" +uid="uid://iv4lk77axlk4" +path="res://.godot/imported/button.obj-e6c969b54c5afbe601f3ea5c30bde0ec.mesh" + +[deps] + +files=["res://.godot/imported/button.obj-e6c969b54c5afbe601f3ea5c30bde0ec.mesh"] + +source_file="res://assets/immersive_home/button.obj" +dest_files=["res://.godot/imported/button.obj-e6c969b54c5afbe601f3ea5c30bde0ec.mesh", "res://.godot/imported/button.obj-e6c969b54c5afbe601f3ea5c30bde0ec.mesh"] + +[params] + +generate_tangents=true +scale_mesh=Vector3(1, 1, 1) +offset_mesh=Vector3(0, 0, 0) +optimize_mesh=true diff --git a/assets/models/hands_steam/left_hand.glb b/assets/models/hands_steam/left_hand.glb new file mode 100644 index 0000000..a7a1e69 --- /dev/null +++ b/assets/models/hands_steam/left_hand.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:135189e6a2caab7d5fa0182feda4c2c7b1a9485bc5a7b27b0fe7b5b5ed7e33eb +size 40061376 diff --git a/assets/models/hands_steam/left_hand.glb.import b/assets/models/hands_steam/left_hand.glb.import new file mode 100644 index 0000000..9e2f3eb --- /dev/null +++ b/assets/models/hands_steam/left_hand.glb.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://dt4ksvogfctkr" +path="res://.godot/imported/left_hand.glb-d1b6eb8d19651a395c75d8356aea3687.scn" + +[deps] + +source_file="res://assets/models/hands_steam/left_hand.glb" +dest_files=["res://.godot/imported/left_hand.glb-d1b6eb8d19651a395c75d8356aea3687.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/assets/models/hands_steam/left_hand_file2.png b/assets/models/hands_steam/left_hand_file2.png new file mode 100644 index 0000000..bbd7070 --- /dev/null +++ b/assets/models/hands_steam/left_hand_file2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:285a2e53aa6d3054749ffcd965a193cb1ddfeedd0bde1f33c8e339eb3d6e077e +size 30680477 diff --git a/assets/models/hands_steam/left_hand_file2.png.import b/assets/models/hands_steam/left_hand_file2.png.import new file mode 100644 index 0000000..f092ffe --- /dev/null +++ b/assets/models/hands_steam/left_hand_file2.png.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://y2l04213se8o" +path.s3tc="res://.godot/imported/left_hand_file2.png-753ecb3429d6d797b17376208f876be4.s3tc.ctex" +path.etc2="res://.godot/imported/left_hand_file2.png-753ecb3429d6d797b17376208f876be4.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://assets/models/hands_steam/left_hand_file2.png" +dest_files=["res://.godot/imported/left_hand_file2.png-753ecb3429d6d797b17376208f876be4.s3tc.ctex", "res://.godot/imported/left_hand_file2.png-753ecb3429d6d797b17376208f876be4.etc2.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=1 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=1 +roughness/src_normal="res://left_hand_file2.png" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/assets/models/hands_steam/left_hand_file3.png b/assets/models/hands_steam/left_hand_file3.png new file mode 100644 index 0000000..593ac6f --- /dev/null +++ b/assets/models/hands_steam/left_hand_file3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7877cf67239ad881c8c4fa5773b9f09d7f35ca763345163800d18e25a52253c +size 18391772 diff --git a/assets/models/hands_steam/left_hand_file3.png.import b/assets/models/hands_steam/left_hand_file3.png.import new file mode 100644 index 0000000..0b80895 --- /dev/null +++ b/assets/models/hands_steam/left_hand_file3.png.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmrf63au6a5jr" +path.s3tc="res://.godot/imported/left_hand_file3.png-88d88e1602347accb4d3c945bb045e57.s3tc.ctex" +path.etc2="res://.godot/imported/left_hand_file3.png-88d88e1602347accb4d3c945bb045e57.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://assets/models/hands_steam/left_hand_file3.png" +dest_files=["res://.godot/imported/left_hand_file3.png-88d88e1602347accb4d3c945bb045e57.s3tc.ctex", "res://.godot/imported/left_hand_file3.png-88d88e1602347accb4d3c945bb045e57.etc2.ctex"] + +[params] + +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=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/assets/models/hands_steam/openxr_glove_left_model_slim.glb b/assets/models/hands_steam/openxr_glove_left_model_slim.glb new file mode 100644 index 0000000..a7a1e69 --- /dev/null +++ b/assets/models/hands_steam/openxr_glove_left_model_slim.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:135189e6a2caab7d5fa0182feda4c2c7b1a9485bc5a7b27b0fe7b5b5ed7e33eb +size 40061376 diff --git a/assets/models/hands_steam/openxr_glove_left_model_slim.glb.import b/assets/models/hands_steam/openxr_glove_left_model_slim.glb.import new file mode 100644 index 0000000..8b87f9b --- /dev/null +++ b/assets/models/hands_steam/openxr_glove_left_model_slim.glb.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://cxaoselwp17hj" +path="res://.godot/imported/openxr_glove_left_model_slim.glb-3bc08bf7e42d440cc1352baebd3824f3.scn" + +[deps] + +source_file="res://assets/models/hands_steam/openxr_glove_left_model_slim.glb" +dest_files=["res://.godot/imported/openxr_glove_left_model_slim.glb-3bc08bf7e42d440cc1352baebd3824f3.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/assets/models/hands_steam/openxr_glove_left_model_slim_file2.png b/assets/models/hands_steam/openxr_glove_left_model_slim_file2.png new file mode 100644 index 0000000..bbd7070 --- /dev/null +++ b/assets/models/hands_steam/openxr_glove_left_model_slim_file2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:285a2e53aa6d3054749ffcd965a193cb1ddfeedd0bde1f33c8e339eb3d6e077e +size 30680477 diff --git a/assets/models/hands_steam/openxr_glove_left_model_slim_file2.png.import b/assets/models/hands_steam/openxr_glove_left_model_slim_file2.png.import new file mode 100644 index 0000000..349e6a1 --- /dev/null +++ b/assets/models/hands_steam/openxr_glove_left_model_slim_file2.png.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqq4ir2g3dtts" +path.s3tc="res://.godot/imported/openxr_glove_left_model_slim_file2.png-b570006e307615a62ead358262b940b2.s3tc.ctex" +path.etc2="res://.godot/imported/openxr_glove_left_model_slim_file2.png-b570006e307615a62ead358262b940b2.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://assets/models/hands_steam/openxr_glove_left_model_slim_file2.png" +dest_files=["res://.godot/imported/openxr_glove_left_model_slim_file2.png-b570006e307615a62ead358262b940b2.s3tc.ctex", "res://.godot/imported/openxr_glove_left_model_slim_file2.png-b570006e307615a62ead358262b940b2.etc2.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=1 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=1 +roughness/src_normal="res://hands/openxr_glove_left_model_slim_file2.png" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/assets/models/hands_steam/openxr_glove_left_model_slim_file3.png b/assets/models/hands_steam/openxr_glove_left_model_slim_file3.png new file mode 100644 index 0000000..593ac6f --- /dev/null +++ b/assets/models/hands_steam/openxr_glove_left_model_slim_file3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7877cf67239ad881c8c4fa5773b9f09d7f35ca763345163800d18e25a52253c +size 18391772 diff --git a/assets/models/hands_steam/openxr_glove_left_model_slim_file3.png.import b/assets/models/hands_steam/openxr_glove_left_model_slim_file3.png.import new file mode 100644 index 0000000..0131e05 --- /dev/null +++ b/assets/models/hands_steam/openxr_glove_left_model_slim_file3.png.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjyf87dcd0me5" +path.s3tc="res://.godot/imported/openxr_glove_left_model_slim_file3.png-e75731c876f664216c04a5bf1e9c9169.s3tc.ctex" +path.etc2="res://.godot/imported/openxr_glove_left_model_slim_file3.png-e75731c876f664216c04a5bf1e9c9169.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://assets/models/hands_steam/openxr_glove_left_model_slim_file3.png" +dest_files=["res://.godot/imported/openxr_glove_left_model_slim_file3.png-e75731c876f664216c04a5bf1e9c9169.s3tc.ctex", "res://.godot/imported/openxr_glove_left_model_slim_file3.png-e75731c876f664216c04a5bf1e9c9169.etc2.ctex"] + +[params] + +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=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/assets/models/hands_steam/right_hand.glb b/assets/models/hands_steam/right_hand.glb new file mode 100644 index 0000000..05d9acb --- /dev/null +++ b/assets/models/hands_steam/right_hand.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7d207229f1878c83742db31a111de44f7cf3136d03a3e7bf1f9c786bc30d550 +size 40061252 diff --git a/assets/models/hands_steam/right_hand.glb.import b/assets/models/hands_steam/right_hand.glb.import new file mode 100644 index 0000000..806a76c --- /dev/null +++ b/assets/models/hands_steam/right_hand.glb.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://c0kow4g10wolq" +path="res://.godot/imported/right_hand.glb-499944075af999d8767516b6c91d6fd4.scn" + +[deps] + +source_file="res://assets/models/hands_steam/right_hand.glb" +dest_files=["res://.godot/imported/right_hand.glb-499944075af999d8767516b6c91d6fd4.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/assets/models/hands_steam/right_hand_file2.png b/assets/models/hands_steam/right_hand_file2.png new file mode 100644 index 0000000..bbd7070 --- /dev/null +++ b/assets/models/hands_steam/right_hand_file2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:285a2e53aa6d3054749ffcd965a193cb1ddfeedd0bde1f33c8e339eb3d6e077e +size 30680477 diff --git a/assets/models/hands_steam/right_hand_file2.png.import b/assets/models/hands_steam/right_hand_file2.png.import new file mode 100644 index 0000000..af6b9ff --- /dev/null +++ b/assets/models/hands_steam/right_hand_file2.png.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://evlov5fjs1p8" +path.s3tc="res://.godot/imported/right_hand_file2.png-9b7fb1444ba3b2f541b7b4585d90cdef.s3tc.ctex" +path.etc2="res://.godot/imported/right_hand_file2.png-9b7fb1444ba3b2f541b7b4585d90cdef.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://assets/models/hands_steam/right_hand_file2.png" +dest_files=["res://.godot/imported/right_hand_file2.png-9b7fb1444ba3b2f541b7b4585d90cdef.s3tc.ctex", "res://.godot/imported/right_hand_file2.png-9b7fb1444ba3b2f541b7b4585d90cdef.etc2.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=1 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=1 +roughness/src_normal="res://hands/right_hand_file2.png" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/assets/models/hands_steam/right_hand_file3.png b/assets/models/hands_steam/right_hand_file3.png new file mode 100644 index 0000000..593ac6f --- /dev/null +++ b/assets/models/hands_steam/right_hand_file3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7877cf67239ad881c8c4fa5773b9f09d7f35ca763345163800d18e25a52253c +size 18391772 diff --git a/assets/models/hands_steam/right_hand_file3.png.import b/assets/models/hands_steam/right_hand_file3.png.import new file mode 100644 index 0000000..52acc6c --- /dev/null +++ b/assets/models/hands_steam/right_hand_file3.png.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cydfo11uxp7yl" +path.s3tc="res://.godot/imported/right_hand_file3.png-b171de262cdca817d47ed129181b9a5c.s3tc.ctex" +path.etc2="res://.godot/imported/right_hand_file3.png-b171de262cdca817d47ed129181b9a5c.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://assets/models/hands_steam/right_hand_file3.png" +dest_files=["res://.godot/imported/right_hand_file3.png-b171de262cdca817d47ed129181b9a5c.s3tc.ctex", "res://.godot/imported/right_hand_file3.png-b171de262cdca817d47ed129181b9a5c.etc2.ctex"] + +[params] + +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=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/content/entities/light/light.tscn b/content/entities/light/light.tscn index 2c0a129..0d76a2f 100644 --- a/content/entities/light/light.tscn +++ b/content/entities/light/light.tscn @@ -91,6 +91,7 @@ bottom_radius = 0.006 height = 0.004 [node name="Light" type="StaticBody3D" groups=["entity"]] +collision_mask = 0 script = ExtResource("1_ykxy3") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] @@ -127,6 +128,7 @@ libraries = { [node name="Rod" type="StaticBody3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.0903599) +collision_mask = 0 [node name="MeshInstance3D" type="MeshInstance3D" parent="Rod"] mesh = SubResource("CylinderMesh_j3pn3") diff --git a/content/entities/media_player/media_player.tscn b/content/entities/media_player/media_player.tscn index c587e08..75b72ae 100644 --- a/content/entities/media_player/media_player.tscn +++ b/content/entities/media_player/media_player.tscn @@ -8,6 +8,7 @@ size = Vector3(0.23, 0.142768, 0.01) [node name="MediaPlayer" type="StaticBody3D" groups=["entity"]] +collision_mask = 0 script = ExtResource("1_ame17") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/content/entities/sensor/sensor.tscn b/content/entities/sensor/sensor.tscn index 19818c2..5117fb1 100644 --- a/content/entities/sensor/sensor.tscn +++ b/content/entities/sensor/sensor.tscn @@ -7,6 +7,7 @@ radius = 0.1 [node name="Sensor" type="StaticBody3D" groups=["entity"]] +collision_mask = 0 script = ExtResource("1_57ac8") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/content/entities/switch/switch.tscn b/content/entities/switch/switch.tscn index b37a547..44f8635 100644 --- a/content/entities/switch/switch.tscn +++ b/content/entities/switch/switch.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=7 format=3 uid="uid://cscl5k7lhopj5"] [ext_resource type="Script" path="res://content/entities/switch/switch.gd" id="1_8ffhi"] -[ext_resource type="Texture2D" uid="uid://b72vsbcvqqxg7" path="res://assets/materials/swich_on.png" id="1_w68gw"] -[ext_resource type="Texture2D" uid="uid://cvc0o6dsktnvl" path="res://assets/materials/switch_off.png" id="2_86ba1"] +[ext_resource type="Texture2D" uid="uid://br3p0c2foputg" path="res://assets/materials/swich_on.png" id="1_w68gw"] +[ext_resource type="Texture2D" uid="uid://co2ishj2hx57p" path="res://assets/materials/switch_off.png" id="2_86ba1"] [ext_resource type="Script" path="res://content/functions/movable.gd" id="4_6xr03"] [sub_resource type="SphereShape3D" id="SphereShape3D_ukj14"] @@ -23,6 +23,7 @@ animations = [{ }] [node name="Switch" type="StaticBody3D" groups=["entity"]] +collision_mask = 0 script = ExtResource("1_8ffhi") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/content/functions/clickable.gd b/content/functions/clickable.gd index 01dcab5..0106177 100644 --- a/content/functions/clickable.gd +++ b/content/functions/clickable.gd @@ -1,39 +1,39 @@ extends Function class_name Clickable -signal on_click(event: EventRay) -signal on_press_down(event: EventRay) -signal on_press_move(event: EventRay) -signal on_press_up(event: EventRay) -signal on_grab_down(event: EventRay) -signal on_grab_move(event: EventRay) -signal on_grab_up(event: EventRay) -signal on_ray_enter(event: EventRay) -signal on_ray_leave(event: EventRay) +signal on_click(event: EventPointer) +signal on_press_down(event: EventPointer) +signal on_press_move(event: EventPointer) +signal on_press_up(event: EventPointer) +signal on_grab_down(event: EventPointer) +signal on_grab_move(event: EventPointer) +signal on_grab_up(event: EventPointer) +signal on_ray_enter(event: EventPointer) +signal on_ray_leave(event: EventPointer) -func _on_click(event: EventRay): +func _on_click(event: EventPointer): on_click.emit(event) -func _on_press_down(event: EventRay): +func _on_press_down(event: EventPointer): on_press_down.emit(event) -func _on_press_move(event: EventRay): +func _on_press_move(event: EventPointer): on_press_move.emit(event) -func _on_press_up(event: EventRay): +func _on_press_up(event: EventPointer): on_press_up.emit(event) -func _on_grab_down(event: EventRay): +func _on_grab_down(event: EventPointer): on_grab_down.emit(event) -func _on_grab_move(event: EventRay): +func _on_grab_move(event: EventPointer): on_grab_move.emit(event) -func _on_grab_up(event: EventRay): +func _on_grab_up(event: EventPointer): on_grab_up.emit(event) -func _on_ray_enter(event: EventRay): +func _on_ray_enter(event: EventPointer): on_ray_enter.emit(event) -func _on_ray_leave(event: EventRay): +func _on_ray_leave(event: EventPointer): on_ray_leave.emit(event) \ No newline at end of file diff --git a/content/functions/movable.gd b/content/functions/movable.gd index 07f3bad..8bcf12f 100644 --- a/content/functions/movable.gd +++ b/content/functions/movable.gd @@ -4,15 +4,15 @@ class_name Movable var hit_node := Node3D.new() -func _on_grab_down(event: EventRay): - event.controller.add_child(hit_node) +func _on_grab_down(event: EventPointer): + event.initiator.node.add_child(hit_node) hit_node.global_transform = get_parent().global_transform -func _on_grab_move(_event: EventRay): +func _on_grab_move(_event: EventPointer): get_parent().global_transform = hit_node.global_transform -func _on_grab_up(event: EventRay): - event.controller.remove_child(hit_node) +func _on_grab_up(event: EventPointer): + event.initiator.node.remove_child(hit_node) func _get_configuration_warnings() -> PackedStringArray: var warnings := PackedStringArray() diff --git a/content/main.tscn b/content/main.tscn index 047de62..581f3a4 100644 --- a/content/main.tscn +++ b/content/main.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=13 format=3 uid="uid://eecv28y6jxk4"] +[gd_scene load_steps=14 format=3 uid="uid://eecv28y6jxk4"] [ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="1_i4c04"] [ext_resource type="Script" path="res://content/main.gd" id="1_uvrd4"] [ext_resource type="PackedScene" uid="uid://b30w6tywfj4fp" path="res://content/system/controller_left/controller_left.tscn" id="2_2lraw"] [ext_resource type="PackedScene" uid="uid://d3f8glx1xgm5w" path="res://content/system/raycast/raycast.tscn" id="3_67lii"] +[ext_resource type="PackedScene" uid="uid://bsx12q23v8apy" path="res://content/system/hands/hands.tscn" id="4_v8xu6"] [ext_resource type="PackedScene" uid="uid://ctltchlf2j2r4" path="res://addons/xr-simulator/XRSimulator.tscn" id="5_3qc8g"] [ext_resource type="Material" uid="uid://bf5ina366dwm6" path="res://assets/materials/sky.material" id="5_wgwf8"] [ext_resource type="PackedScene" uid="uid://83lb5p4e0qk0" path="res://content/scenes/house.tscn" id="8_qkrg7"] @@ -50,6 +51,11 @@ mesh = SubResource("BoxMesh_ir3co") [node name="Raycast" parent="XROrigin3D/XRControllerRight" instance=ExtResource("3_67lii")] +[node name="Hands" parent="XROrigin3D" node_paths=PackedStringArray("ray_left", "ray_right") instance=ExtResource("4_v8xu6")] +transform = Transform3D(0.999968, -1.39576e-11, 0, 9.52038e-12, 0.999984, -2.59206e-11, -2.91038e-11, 5.22959e-11, 0.999984, 0, 0, 0) +ray_left = NodePath("../XRControllerLeft/Raycast") +ray_right = NodePath("../XRControllerRight/Raycast") + [node name="StartXR" parent="." instance=ExtResource("1_i4c04")] enable_passthrough = true @@ -69,3 +75,5 @@ visible = false [node name="Keyboard" parent="." instance=ExtResource("9_e5n3p")] transform = Transform3D(0.499999, -6.98142e-12, 0, 4.74065e-12, 0.5, -2.27374e-13, 0, 2.27374e-13, 0.5, -0.125313, 0.424282, -0.263966) + +[editable path="XROrigin3D/XRControllerLeft"] diff --git a/content/system/controller_left/controller_left.gd b/content/system/controller_left/controller_left.gd index a8fa9d0..ad5b344 100644 --- a/content/system/controller_left/controller_left.gd +++ b/content/system/controller_left/controller_left.gd @@ -34,7 +34,7 @@ var trash_bin_large: bool = false: func _ready(): trash_bin_visible = false - EventSystem.on_grab_down.connect(func(event: EventRay): + EventSystem.on_grab_down.connect(func(event: EventPointer): trash_bin_visible = event.target.is_in_group("entity") ) @@ -53,7 +53,7 @@ func _ready(): ) - EventSystem.on_grab_up.connect(func(_event: EventRay): + EventSystem.on_grab_up.connect(func(_event: EventPointer): if !trash_bin_visible: return diff --git a/content/system/controller_left/controller_left.tscn b/content/system/controller_left/controller_left.tscn index fb8344e..9e9ec9b 100644 --- a/content/system/controller_left/controller_left.tscn +++ b/content/system/controller_left/controller_left.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" path="res://content/system/controller_left/controller_left.gd" id="1_2j3qs"] [ext_resource type="PackedScene" uid="uid://c3kdssrmv84kv" path="res://content/ui/menu/menu.tscn" id="1_ccbr3"] -[ext_resource type="PackedScene" uid="uid://cj42our8uhfq6" path="res://assets/models/trash_bin/trash_bin.gltf" id="3_m33ce"] +[ext_resource type="PackedScene" uid="uid://dqjcqdhe3rbtn" path="res://assets/models/trash_bin/trash_bin.gltf" id="3_m33ce"] [ext_resource type="PackedScene" uid="uid://d3f8glx1xgm5w" path="res://content/system/raycast/raycast.tscn" id="4_n7lao"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m58yb"] @@ -111,6 +111,7 @@ transform = Transform3D(0.03, 0, 0, 0, 0.03, 0, 0, 0, 0.03, 0.106903, -0.228617, [node name="Area3D" type="Area3D" parent="trash_bin"] transform = Transform3D(25, 0, 0, 0, 25, 0, 0, 0, 25, 0, 0, 0) +collision_layer = 0 [node name="CollisionShape3D" type="CollisionShape3D" parent="trash_bin/Area3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0542412, 0) diff --git a/content/system/hands/hands.gd b/content/system/hands/hands.gd new file mode 100644 index 0000000..bd7873a --- /dev/null +++ b/content/system/hands/hands.gd @@ -0,0 +1,106 @@ +extends Node3D + +const Pointer = preload("res://lib/utils/pointer/pointer.gd") +const Initiator = preload("res://lib/utils/pointer/initiator.gd") +const Finger = preload("res://lib/utils/touch/finger.gd") +const Touch = preload("res://lib/utils/touch/touch.gd") + +@onready var hand_right: OpenXRHand = $XRHandRight +@onready var hand_left: OpenXRHand = $XRHandLeft +@export var ray_left: RayCast3D +@export var ray_right: RayCast3D +var initiator: Initiator = Initiator.new() +var touch: Touch +var pointer: Pointer +var press_distance = 0.03 +var grip_distance = 0.03 +var close_distance = 0.1 + +var pressed_left = false +var pressed_right = false +var grabbed_left = false +var grabbed_right = false + +func _ready(): + touch = Touch.new({ + Finger.Type.INDEX_RIGHT: $XRHandRight/IndexTip/TouchArea, + Finger.Type.INDEX_LEFT: $XRHandLeft/IndexTip/TouchArea, + Finger.Type.MIDDLE_RIGHT: $XRHandRight/MiddleTip/TouchArea, + Finger.Type.MIDDLE_LEFT: $XRHandLeft/MiddleTip/TouchArea + }) + add_child(touch) + + _ready_hand(hand_right) + +func _ready_hand(hand: OpenXRHand): + initiator.type = Initiator.Type.HAND_RIGHT if hand == hand_right else Initiator.Type.HAND_LEFT + initiator.node = ray_left.get_parent() if hand == hand_left else ray_right.get_parent() + + pointer = Pointer.new(initiator, ray_left if hand == hand_left else ray_right) + add_child(pointer) + +func _process(_delta): + _process_hand(hand_right) + +func _process_hand(hand: OpenXRHand): + var index_tip = hand.get_node("IndexTip/Marker3D") + var thumb_tip = hand.get_node("ThumbTip/Marker3D") + var middle_tip = hand.get_node("MiddleTip/Marker3D") + + var _ray = ray_left if hand == hand_left else ray_right + + var distance_trigger = index_tip.global_position.distance_to(thumb_tip.global_position) + var distance_grab = middle_tip.global_position.distance_to(thumb_tip.global_position) + + var distance_target = _ray.get_collision_point().distance_to(_ray.global_position) + + var trigger_close = distance_trigger <= press_distance + var grab_close = distance_grab <= grip_distance + var distance_close = distance_target <= close_distance + + if hand == hand_left: + + if !distance_close: + if trigger_close && !pressed_left: + initiator.on_press.emit(Initiator.EventType.TRIGGER) + pressed_left = true + elif !trigger_close && pressed_left: + initiator.on_release.emit(Initiator.EventType.TRIGGER) + pressed_left = false + + if grab_close && !grabbed_left: + initiator.on_press.emit(Initiator.EventType.GRIP) + grabbed_left = true + elif !grab_close && grabbed_left: + initiator.on_release.emit(Initiator.EventType.GRIP) + grabbed_left = false + else: + if trigger_close && !grabbed_right: + initiator.on_press.emit(Initiator.EventType.GRIP) + grabbed_right = true + elif !trigger_close && grabbed_right: + initiator.on_release.emit(Initiator.EventType.GRIP) + grabbed_right = false + else: + if !distance_close: + if trigger_close && !pressed_right: + initiator.on_press.emit(Initiator.EventType.TRIGGER) + pressed_right = true + elif !trigger_close && pressed_right: + initiator.on_release.emit(Initiator.EventType.TRIGGER) + pressed_right = false + + if grab_close && !grabbed_right: + initiator.on_press.emit(Initiator.EventType.GRIP) + grabbed_right = true + elif !grab_close && grabbed_right: + initiator.on_release.emit(Initiator.EventType.GRIP) + grabbed_right = false + + else: + if trigger_close && !grabbed_right: + initiator.on_press.emit(Initiator.EventType.GRIP) + grabbed_right = true + elif !trigger_close && grabbed_right: + initiator.on_release.emit(Initiator.EventType.GRIP) + grabbed_right = false \ No newline at end of file diff --git a/content/system/hands/hands.tscn b/content/system/hands/hands.tscn new file mode 100644 index 0000000..4c397c2 --- /dev/null +++ b/content/system/hands/hands.tscn @@ -0,0 +1,160 @@ +[gd_scene load_steps=6 format=3 uid="uid://bsx12q23v8apy"] + +[ext_resource type="Script" path="res://content/system/hands/hands.gd" id="1_c4f76"] +[ext_resource type="PackedScene" uid="uid://c0kow4g10wolq" path="res://assets/models/hands_steam/right_hand.glb" id="1_uekbj"] +[ext_resource type="PackedScene" uid="uid://dt4ksvogfctkr" path="res://assets/models/hands_steam/left_hand.glb" id="2_n73lt"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dopke"] +radius = 0.001 +height = 0.02 + +[sub_resource type="BoxShape3D" id="BoxShape3D_1pxrt"] +size = Vector3(0.14, 0.0577792, 0.169383) + +[node name="Hands" type="Node3D"] +script = ExtResource("1_c4f76") + +[node name="XRHandLeft" type="OpenXRHand" parent="."] +transform = Transform3D(0.999999, -1.39628e-11, 0, 9.48119e-12, 0.999999, -4.54747e-13, 0, 0, 0.999999, -0.25, 0, 0) +hand_skeleton = NodePath("left_hand/Armature_001/Skeleton3D") + +[node name="left_hand" parent="XRHandLeft" instance=ExtResource("2_n73lt")] +transform = Transform3D(1, 4.42441e-11, 0, -1.06936e-10, 1, 1.81899e-12, 5.82077e-11, -1.81899e-12, 1, 0, 0, 0.033) + +[node name="IndexTip" type="BoneAttachment3D" parent="XRHandLeft"] +transform = Transform3D(0.19221, -0.669965, -0.717079, 0.977075, 0.19881, 0.076153, 0.0915428, -0.715277, 0.692819, 0.0345973, 0.0355402, -0.131767) +bone_name = "Index_Tip_L" +bone_idx = 9 +use_external_skeleton = true +external_skeleton = NodePath("../left_hand/Armature_001/Skeleton3D") + +[node name="Marker3D" type="Marker3D" parent="XRHandLeft/IndexTip"] +gizmo_extents = 0.02 + +[node name="TouchArea" type="Area3D" parent="XRHandLeft/IndexTip"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0.01) +collision_layer = 0 +collision_mask = 4 +monitorable = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="XRHandLeft/IndexTip/TouchArea"] +transform = Transform3D(1, -7.45058e-09, -2.22045e-16, 7.45058e-09, 1, 0, 0, 0, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_dopke") + +[node name="ThumbTip" type="BoneAttachment3D" parent="XRHandLeft"] +transform = Transform3D(0.937246, 0.0284254, -0.347508, 0.0184905, 0.991216, 0.130949, 0.348178, -0.129157, 0.928488, 0.0498668, 0.0560917, -0.0797768) +bone_name = "Thumb_Tip_L" +bone_idx = 4 +use_external_skeleton = true +external_skeleton = NodePath("../left_hand/Armature_001/Skeleton3D") + +[node name="Marker3D" type="Marker3D" parent="XRHandLeft/ThumbTip"] +gizmo_extents = 0.02 + +[node name="MiddleTip" type="BoneAttachment3D" parent="XRHandLeft"] +transform = Transform3D(0.0812012, -0.650531, -0.755125, 0.996577, 0.064817, 0.051326, 0.0155558, -0.756708, 0.653568, 0.032112, 0.00654224, -0.138612) +bone_name = "Middle_Tip_L" +bone_idx = 14 +use_external_skeleton = true +external_skeleton = NodePath("../left_hand/Armature_001/Skeleton3D") + +[node name="Marker3D" type="Marker3D" parent="XRHandLeft/MiddleTip"] +gizmo_extents = 0.02 + +[node name="TouchArea" type="Area3D" parent="XRHandLeft/MiddleTip"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0.01) +collision_layer = 0 +collision_mask = 4 +monitorable = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="XRHandLeft/MiddleTip/TouchArea"] +transform = Transform3D(1, -7.45058e-09, -2.22045e-16, 7.45058e-09, 1, 0, 0, 0, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_dopke") + +[node name="AnimatableBody3D" type="AnimatableBody3D" parent="XRHandLeft"] +transform = Transform3D(1, 8.67362e-19, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +collision_layer = 8 +collision_mask = 8 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="XRHandLeft/AnimatableBody3D"] +transform = Transform3D(1, 8.67362e-19, 4.75779e-13, -2.32831e-10, 1, -1.77636e-14, -4.97946e-12, 1.77636e-15, 1, -7.7486e-07, 1.33878e-09, -0.030436) +shape = SubResource("BoxShape3D_1pxrt") + +[node name="RemoteTransform3D" type="RemoteTransform3D" parent="XRHandLeft"] +remote_path = NodePath("../AnimatableBody3D") + +[node name="XRHandRight" type="OpenXRHand" parent="."] +transform = Transform3D(0.999998, -0.000567105, -2.5179e-05, -2.51789e-05, 4.39886e-08, -0.999999, 0.000567104, 0.999999, 2.97064e-08, 0.264391, 0, 0) +hand = 1 +hand_skeleton = NodePath("right_hand/Armature/Skeleton3D") + +[node name="right_hand" parent="XRHandRight" instance=ExtResource("1_uekbj")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.033) + +[node name="vr_glove_right_slim" parent="XRHandRight/right_hand/Armature/Skeleton3D" index="0"] +transform = Transform3D(1, 0, 4.7579e-13, 0, 1, 0, -1.34149e-12, 1.77636e-15, 1, 0, 0, 0) + +[node name="IndexTip" type="BoneAttachment3D" parent="XRHandRight"] +transform = Transform3D(0.19221, 0.669966, 0.717079, -0.091543, -0.715277, 0.69282, 0.977075, -0.19881, -0.0761527, -0.0345977, -0.164767, -0.00254008) +bone_name = "Index_Tip_R" +bone_idx = 9 +use_external_skeleton = true +external_skeleton = NodePath("../right_hand/Armature/Skeleton3D") + +[node name="Marker3D" type="Marker3D" parent="XRHandRight/IndexTip"] +gizmo_extents = 0.02 + +[node name="TouchArea" type="Area3D" parent="XRHandRight/IndexTip"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0.01) +collision_layer = 0 +collision_mask = 4 +monitorable = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="XRHandRight/IndexTip/TouchArea"] +transform = Transform3D(1, -7.45058e-09, -2.22045e-16, 7.45058e-09, 1, 0, 0, 0, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_dopke") + +[node name="ThumbTip" type="BoneAttachment3D" parent="XRHandRight"] +transform = Transform3D(0.937246, -0.0284254, 0.347508, -0.348179, -0.129158, 0.928488, 0.0184906, -0.991216, -0.130949, -0.0498677, -0.112777, -0.0230909) +bone_name = "Thumb_Tip_R" +bone_idx = 4 +use_external_skeleton = true +external_skeleton = NodePath("../right_hand/Armature/Skeleton3D") + +[node name="Marker3D" type="Marker3D" parent="XRHandRight/ThumbTip"] +gizmo_extents = 0.02 + +[node name="MiddleTip" type="BoneAttachment3D" parent="XRHandRight"] +transform = Transform3D(0.0812011, 0.650531, 0.755126, -0.0155557, -0.756708, 0.653568, 0.996576, -0.0648169, -0.0513262, -0.032112, -0.171612, 0.0264578) +bone_name = "Middle_Tip_R" +bone_idx = 14 +use_external_skeleton = true +external_skeleton = NodePath("../right_hand/Armature/Skeleton3D") + +[node name="Marker3D" type="Marker3D" parent="XRHandRight/MiddleTip"] +gizmo_extents = 0.02 + +[node name="TouchArea" type="Area3D" parent="XRHandRight/MiddleTip"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0.01) +collision_layer = 0 +collision_mask = 4 +monitorable = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="XRHandRight/MiddleTip/TouchArea"] +transform = Transform3D(1, -7.45058e-09, -2.22045e-16, 7.45058e-09, 1, 0, 0, 0, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_dopke") + +[node name="AnimatableBody3D" type="AnimatableBody3D" parent="XRHandRight"] +transform = Transform3D(1, 0, 4.7579e-13, -5.82077e-11, 1, 0, -4.97947e-12, 1.77636e-15, 1, 0, 0, 0) +collision_layer = 8 +collision_mask = 8 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="XRHandRight/AnimatableBody3D"] +transform = Transform3D(1, 0, 4.75779e-13, -2.32831e-10, 1, -1.77636e-14, -4.97946e-12, 1.77636e-15, 1, -7.7486e-07, 1.33878e-09, -0.030436) +shape = SubResource("BoxShape3D_1pxrt") + +[node name="RemoteTransform3D" type="RemoteTransform3D" parent="XRHandRight"] +remote_path = NodePath("../AnimatableBody3D") + +[editable path="XRHandLeft/left_hand"] +[editable path="XRHandRight/right_hand"] diff --git a/content/system/keyboard/keyboard.gd b/content/system/keyboard/keyboard.gd index 751f108..947e5f1 100644 --- a/content/system/keyboard/keyboard.gd +++ b/content/system/keyboard/keyboard.gd @@ -71,19 +71,18 @@ func create_key(key: Key): var key_node = button_scene.instantiate() key_node.label = EventKey.key_to_string(key, caps) - key_node.add_to_group("ui_focus_skip") - key_node.get_node("Label").font_size = 32 + key_node.focusable = false + key_node.font_size = 32 key_node.set_meta("key", key) return key_node func update_labels(): for key_button in keys.get_children(): - var label = key_button.get_children()[key_button.get_children().size() - 1] if caps: - label.text = label.text.to_upper() + key_button.label = key_button.label.to_upper() else: - label.text = label.text.to_lower() + key_button.label = key_button.label.to_lower() func _emit_event(type: String, key: Key): var event = EventKey.new() diff --git a/content/system/keyboard/keyboard.tscn b/content/system/keyboard/keyboard.tscn index 9450a96..539dff2 100644 --- a/content/system/keyboard/keyboard.tscn +++ b/content/system/keyboard/keyboard.tscn @@ -11,24 +11,29 @@ size = Vector3(0.79, 0.01, 0.26) [sub_resource type="BoxMesh" id="BoxMesh_7rntc"] size = Vector3(0.79, 0.01, 0.26) -[node name="Keyboard" type="StaticBody3D" groups=["ui_focus_skip"]] +[node name="Keyboard" type="StaticBody3D" groups=["ui_focus_stop"]] transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0) +collision_layer = 2 +collision_mask = 2 script = ExtResource("1_maojw") -[node name="Backspace" parent="." groups=["ui_focus_skip"] instance=ExtResource("1_xdpwr")] +[node name="Backspace" parent="." instance=ExtResource("1_xdpwr")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.66, 0, 0.02) +focusable = false label = "backspace" icon = true metadata/key = 4194308 -[node name="Caps" parent="." groups=["ui_focus_skip"] instance=ExtResource("1_xdpwr")] +[node name="Caps" parent="." instance=ExtResource("1_xdpwr")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.06, 0, 0.15) +focusable = false label = "keyboard_capslock" icon = true toggleable = true -[node name="Paste" parent="." groups=["ui_focus_skip"] instance=ExtResource("1_xdpwr")] +[node name="Paste" parent="." instance=ExtResource("1_xdpwr")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.66, 0, 0.18) +focusable = false label = "assignment" icon = true diff --git a/content/system/raycast/raycast.gd b/content/system/raycast/raycast.gd index a3b2935..89535f6 100644 --- a/content/system/raycast/raycast.gd +++ b/content/system/raycast/raycast.gd @@ -1,31 +1,40 @@ extends RayCast3D +const Pointer = preload("res://lib/utils/pointer/pointer.gd") +const Initiator = preload("res://lib/utils/pointer/initiator.gd") + @onready var cursor: Node3D = $Cursor @onready var decal: Decal = $Decal @export var is_right: bool = true @export var with_decal: bool = false -var controller: XRController3D -var timespan_click = 200.0 +@onready var pointer: Pointer -var last_collided: Object = null -var is_pressed := false -var is_grabbed := false -var time_pressed := 0.0 -var moved := false -var click_point := Vector3.ZERO +var _event_type_map = { + "trigger_click": Initiator.EventType.TRIGGER, + "grip_click": Initiator.EventType.GRIP, +} func _ready(): - controller = get_parent() - assert(controller is XRController3D, "XRController3D is not found in parent") + var initiator = Initiator.new() + initiator.type = Initiator.Type.CONTROLLER_RIGHT if is_right else Initiator.Type.CONTROLLER_LEFT + initiator.node = get_parent() + assert(get_parent() is XRController3D, "Parent must be XRController3D") - controller.button_pressed.connect(_on_button_pressed) - controller.button_released.connect(_on_button_released) + pointer = Pointer.new(initiator, self) + add_child(pointer) + + get_parent().button_pressed.connect(func(button: String): + if _event_type_map.has(button): + initiator.on_press.emit(_event_type_map[button]) + ) + get_parent().button_released.connect(func(button: String): + if _event_type_map.has(button): + initiator.on_release.emit(_event_type_map[button]) + ) func _physics_process(_delta): - _handle_enter_leave() - _handle_move() _handle_cursor() func _handle_cursor(): @@ -40,75 +49,3 @@ func _handle_cursor(): decal.visible = false cursor.global_transform.origin = get_collision_point() + get_collision_normal() * 0.001 # offset to avoid z-fighting cursor.global_transform.basis = Basis.looking_at(get_collision_normal(), Vector3.UP) - -func _handle_move(): - var time_passed = Time.get_ticks_msec() - time_pressed - if time_passed <= timespan_click || (is_pressed == false && is_grabbed == false): - return - - moved = true - - # reset if last_collided gets deleted - if is_instance_valid(last_collided) == false: - last_collided = null - return - - if is_pressed: - _emit_event("press_move", last_collided ) - - if is_grabbed: - _emit_event("grab_move", last_collided ) - -func _handle_enter_leave(): - var collider = get_collider() - - if collider == last_collided || is_grabbed || is_pressed: - return - - _emit_event("ray_enter", collider ) - _emit_event("ray_leave", last_collided ) - - last_collided = collider - -func _on_button_pressed(button: String): - var collider = get_collider() - - if collider == null: - return - - match button: - "trigger_click": - is_pressed = true - time_pressed = Time.get_ticks_msec() - click_point = get_collision_point() - _emit_event("press_down", collider ) - "grip_click": - is_grabbed = true - click_point = get_collision_point() - _emit_event("grab_down", collider ) - -func _on_button_released(button: String): - match button: - "trigger_click": - if is_pressed: - if moved == false: - _emit_event("click", last_collided ) - _emit_event("press_up", last_collided ) - is_pressed = false - last_collided = null - moved = false - "grip_click": - if is_grabbed: - _emit_event("grab_up", last_collided ) - is_grabbed = false - last_collided = null - moved = false - -func _emit_event(type: String, target): - var event = EventRay.new() - event.controller = controller - event.target = target - event.ray = self - event.is_right_controller = is_right - - EventSystem.emit(type, event) diff --git a/content/system/raycast/raycast.tscn b/content/system/raycast/raycast.tscn index 805f0dc..55e4b3d 100644 --- a/content/system/raycast/raycast.tscn +++ b/content/system/raycast/raycast.tscn @@ -6,6 +6,7 @@ [node name="Raycast" type="RayCast3D"] transform = Transform3D(0.999999, -1.39624e-11, 0, 9.48108e-12, 0.999999, 0, 0, 4.54747e-13, 0.999998, -0.000467122, 0.00228411, -0.0016689) target_position = Vector3(0, 0, -5) +collision_mask = 19 script = ExtResource("1_gp8nv") [node name="Decal" type="Decal" parent="."] @@ -18,6 +19,6 @@ lower_fade = 0.000919435 [node name="Cursor" type="Node3D" parent="."] [node name="CursorSprite" type="Sprite3D" parent="Cursor"] -transform = Transform3D(0.03, 3.25261e-20, -2.20405e-39, -3.25261e-20, 0.03, -2.03288e-21, 0, 2.03288e-21, 0.03, 0, 0, 0) +transform = Transform3D(0.03, 2.71051e-20, 0, -5.42101e-20, 0.03, -2.03288e-21, -2.46521e-33, 2.5411e-21, 0.03, 0, 0, 0) pixel_size = 0.001 texture = ExtResource("1_2f2iv") diff --git a/content/ui/components/button/button.gd b/content/ui/components/button/button.gd index e6b9adb..5dbfad1 100644 --- a/content/ui/components/button/button.gd +++ b/content/ui/components/button/button.gd @@ -1,15 +1,31 @@ @tool -extends StaticBody3D +extends Node3D class_name Button3D +const Proxy = preload("res://lib/utils/proxy.gd") + signal on_button_down() signal on_button_up() const IconFont = preload("res://assets/icons/icons.tres") -@onready var label_node: Label3D = $Label +@onready var label_node: Label3D = $Body/Label +@onready var finger_area: Area3D = $FingerArea +@export var focusable: bool = true: + set(value): + focusable = value + if value == false: + add_to_group("ui_focus_stop") + else: + remove_from_group("ui_focus_stop") + +@export var font_size: int = 10: + set(value): + font_size = value + if !is_node_ready(): await ready + label_node.font_size = value @export var label: String = "": set(value): label = value @@ -25,30 +41,41 @@ const IconFont = preload("res://assets/icons/icons.tres") label_node.font_size = 48 label_node.width = 1000 label_node.autowrap_mode = TextServer.AUTOWRAP_OFF + else: + label_node.font = null + label_node.font_size = font_size + label_node.width = 50 + label_node.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - @export var toggleable: bool = false @export var disabled: bool = false -@export var external_state: bool = false @export var initial_active: bool = false -var active: bool = false : +var external_value: Proxy = null +var active: bool = false: + get: + if external_value != null: + return external_value.value + return active set(value): - animation_player.stop() - if value == active: - return - - active = value - - if active: - animation_player.play("down") + if external_value != null: + external_value.value = value else: - animation_player.play_backwards("down") + active = value + update_animation() @onready var animation_player: AnimationPlayer = $AnimationPlayer func _ready(): if initial_active: active = true + +func update_animation(): + var length = animation_player.get_animation("down").length + + if active && animation_player.current_animation_position != length: + animation_player.play("down") + elif !active && animation_player.current_animation_position != 0: + animation_player.play_backwards("down") func _on_press_down(event): if disabled: @@ -57,22 +84,17 @@ func _on_press_down(event): AudioPlayer.play_effect("click") - if external_state || toggleable: + if toggleable: return active = true on_button_down.emit() - - func _on_press_up(event): if disabled: event.bubbling = false return - if external_state: - return - if toggleable: active = !active @@ -83,3 +105,54 @@ func _on_press_up(event): else: active = false on_button_up.emit() + +func _on_touch_enter(event: EventTouch): + animation_player.stop() + animation_player.speed_scale = 0 + animation_player.current_animation = "down" + AudioPlayer.play_effect("click") + _touch_change(event) + +func _on_touch_move(event: EventTouch): + _touch_change(event) + +func _on_touch_leave(_event: EventTouch): + animation_player.stop() + animation_player.speed_scale = 1 + + if toggleable: + active = !active + if active: + on_button_up.emit() + else: + on_button_down.emit() + + +func _touch_change(event: EventTouch): + if disabled: + event.bubbling = false + return + + var pos = Vector3(0, 1, 0) + for finger in event.fingers: + var finger_pos = to_local(finger.area.global_position) + if pos.y > finger_pos.y: + pos = finger_pos + + var button_height = finger_area.get_node("CollisionShape3D").shape.size.y + var button_center = finger_area.position.y + + var percent = clamp((button_center + button_height / 2 - pos.y) / (button_height / 2), 0, 1) + + if !active && percent < 1: + on_button_down.emit() + elif active && percent >= 1: + on_button_up.emit() + + animation_player.seek(percent * animation_player.current_animation_length, true) + + if toggleable: + return + + active = percent < 1 + diff --git a/content/ui/components/button/button.tscn b/content/ui/components/button/button.tscn index ecd1ebd..54cde07 100644 --- a/content/ui/components/button/button.tscn +++ b/content/ui/components/button/button.tscn @@ -1,12 +1,11 @@ -[gd_scene load_steps=8 format=3 uid="uid://bsjqdvkt0u87c"] +[gd_scene load_steps=9 format=3 uid="uid://bsjqdvkt0u87c"] [ext_resource type="Script" path="res://content/ui/components/button/button.gd" id="1_74x7g"] -[ext_resource type="Material" uid="uid://bujy3egn1oqac" path="res://assets/materials/ui_element.material" id="2_h7ln4"] +[ext_resource type="ArrayMesh" uid="uid://iv4lk77axlk4" path="res://assets/immersive_home/button.obj" id="2_cve3l"] -[sub_resource type="BoxMesh" id="BoxMesh_jwpm5"] -resource_local_to_scene = true -material = ExtResource("2_h7ln4") -size = Vector3(0.05, 0.02, 0.05) +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8s8ln"] +transparency = 1 +albedo_color = Color(0, 0.501961, 0.886275, 1) [sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_o4j7g"] points = PackedVector3Array(-0.025, -0.01, -0.025, -0.025, 0.01, -0.025, 0.025, -0.01, -0.025, -0.025, -0.01, 0.025, -0.025, 0.01, 0.025, 0.025, 0.01, -0.025, 0.025, -0.01, 0.025, 0.025, 0.01, 0.025) @@ -16,60 +15,50 @@ length = 0.001 tracks/0/type = "bezier" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath(".:position:y") +tracks/0/path = NodePath("Body:scale:y") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { "handle_modes": PackedInt32Array(0), -"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0), "times": PackedFloat32Array(0) } tracks/1/type = "bezier" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("MeshInstance3D:position:y") +tracks/1/path = NodePath("Body:position:y") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { "handle_modes": PackedInt32Array(0), -"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"points": PackedFloat32Array(0.01, -0.25, 0, 0.25, 0), "times": PackedFloat32Array(0) } [sub_resource type="Animation" id="Animation_iu2ed"] resource_name = "down" length = 0.2 +step = 0.01 tracks/0/type = "bezier" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath(".:position:y") +tracks/0/path = NodePath("Body:scale:y") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { "handle_modes": PackedInt32Array(0, 0), -"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, -0.01, -0.25, 0, 0.25, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.12, -0.00966179, 0.500747, -0.13, 0.00874269, 0.25, 0), "times": PackedFloat32Array(0, 0.2) } tracks/1/type = "bezier" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("MeshInstance3D:mesh:size:y") +tracks/1/path = NodePath("Body:position:y") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { "handle_modes": PackedInt32Array(0, 0), -"points": PackedFloat32Array(0.02, -0.25, 0, 0.25, 0, 0.01, -0.25, 0, 0.25, 0), -"times": PackedFloat32Array(0, 0.2) -} -tracks/2/type = "bezier" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath("MeshInstance3D:position:y") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"handle_modes": PackedInt32Array(0, 0), -"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, 0.005, -0.25, 0, 0.25, 0), +"points": PackedFloat32Array(0.0101447, -0.25, 0, 0.12, 0.000134136, 0.0051993, -0.12, 0.000145131, 0.25, 0), "times": PackedFloat32Array(0, 0.2) } @@ -79,26 +68,46 @@ _data = { "down": SubResource("Animation_iu2ed") } -[node name="Button" type="StaticBody3D" groups=["ui_focus"]] +[sub_resource type="BoxShape3D" id="BoxShape3D_bqjii"] +size = Vector3(0.0501598, 0.0195937, 0.0501598) + +[node name="Button" type="Node3D" groups=["ui_focus"]] script = ExtResource("1_74x7g") label = "Example Text" -[node name="MeshInstance3D" type="MeshInstance3D" parent="."] -mesh = SubResource("BoxMesh_jwpm5") +[node name="Body" type="StaticBody3D" parent="." groups=["ui_focus_skip"]] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.01, 0) +collision_layer = 2 +collision_mask = 0 -[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +[node name="MeshInstance3D" type="MeshInstance3D" parent="Body"] +transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, -0.005, 0) +mesh = ExtResource("2_cve3l") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_8s8ln") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Body"] shape = SubResource("ConvexPolygonShape3D_o4j7g") -[node name="AnimationPlayer" type="AnimationPlayer" parent="."] -libraries = { -"": SubResource("AnimationLibrary_sbgno") -} - -[node name="Label" type="Label3D" parent="."] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0.011, 0) +[node name="Label" type="Label3D" parent="Body"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0.005, 0) pixel_size = 0.001 text = "Example Text" font_size = 10 outline_size = 0 autowrap_mode = 3 width = 50.0 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_sbgno") +} + +[node name="FingerArea" type="Area3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0101447, 0) +collision_layer = 4 +collision_mask = 0 +monitoring = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FingerArea"] +shape = SubResource("BoxShape3D_bqjii") diff --git a/content/ui/components/input/input.gd b/content/ui/components/input/input.gd index 1265a2f..b069c0d 100644 --- a/content/ui/components/input/input.gd +++ b/content/ui/components/input/input.gd @@ -68,6 +68,10 @@ func _process(_delta): if get_tree().debug_collisions_hint && OS.get_name() != "Android": _draw_debug_text_gaps() +func _on_press_down(event): + var pos_x = label.to_local(event.ray.get_collision_point()).x + text_handler.update_caret_position(pos_x) + func _on_press_move(event): var ray_pos = event.ray.global_position var ray_dir = -event.ray.global_transform.basis.z @@ -86,10 +90,7 @@ func _on_press_move(event): caret.position.x = text_handler.get_caret_position() label.text = text_handler.get_display_text() -func _on_focus_in(event): - var pos_x = label.to_local(event.ray.get_collision_point()).x - text_handler.update_caret_position(pos_x) - +func _on_focus_in(_event): caret.position.x = text_handler.get_caret_position() label.text = text_handler.get_display_text() caret.show() @@ -114,6 +115,7 @@ func update_caret_position(event): func _on_focus_out(_event): + print("focus out") animation.stop() caret.hide() diff --git a/content/ui/components/input/input.tscn b/content/ui/components/input/input.tscn index ff9666c..0aefa4c 100644 --- a/content/ui/components/input/input.tscn +++ b/content/ui/components/input/input.tscn @@ -53,6 +53,8 @@ _data = { } [node name="Input" type="StaticBody3D" groups=["ui_focus"]] +collision_layer = 2 +collision_mask = 0 script = ExtResource("1_uml3t") width = 0.2 text = "Example" diff --git a/content/ui/components/input/text_handler.gd b/content/ui/components/input/text_handler.gd index 2dffa73..149f7f2 100644 --- a/content/ui/components/input/text_handler.gd +++ b/content/ui/components/input/text_handler.gd @@ -1,4 +1,4 @@ -extends Object +extends RefCounted var label: Label3D diff --git a/content/ui/menu/edit/device/device.tscn b/content/ui/menu/edit/device/device.tscn index 12fdd5c..9c0237a 100644 --- a/content/ui/menu/edit/device/device.tscn +++ b/content/ui/menu/edit/device/device.tscn @@ -8,6 +8,7 @@ script = ExtResource("1_rbo86") [node name="Button" parent="." instance=ExtResource("2_go2es")] +focusable = true [node name="Clickable" type="Node" parent="."] script = ExtResource("3_6wicx") diff --git a/content/ui/menu/edit/edit_menu.gd b/content/ui/menu/edit/edit_menu.gd index 4e7def5..404417b 100644 --- a/content/ui/menu/edit/edit_menu.gd +++ b/content/ui/menu/edit/edit_menu.gd @@ -1,7 +1,6 @@ extends Node3D -const Device = preload("./device/device.tscn") -const Entity = preload("./entity/entity.tscn") +const ButtonScene = preload("res://content/ui/components/button/button.tscn") const EntityCreator = preload("./entity_creator.gd") @onready var devices_node: GridContainer3D = $Devices @@ -101,33 +100,33 @@ func render_devices(): for device in page_devices: var info = device.values()[0] - var device_instance = Device.instantiate() - device_instance.id = device.keys()[0] - device_instance.get_node("Clickable").on_click.connect(func(_event): - _on_device_click(device_instance.id) + var button_instance = ButtonScene.instantiate() + button_instance.label = info["name"] + button_instance.on_button_down.connect(func(): + _on_device_click(device.keys()[0]) ) - devices_node.add_child(device_instance) - device_instance.set_device_name.call_deferred(info["name"]) + devices_node.add_child(button_instance) devices_node._update_container() func render_entities(): var entities = get_page() - var back_button = Entity.instantiate() - back_button.get_node("Clickable").on_click.connect(func(_event): + var back_button = ButtonScene.instantiate() + back_button.label = "arrow_back" + back_button.icon = true + back_button.on_button_down.connect(func(): _on_entity_click("#back") ) devices_node.add_child(back_button) - back_button.set_entity_name("#back") for entity in entities: - var entity_instance = Entity.instantiate() - entity_instance.get_node("Clickable").on_click.connect(func(_event): + var button_instance = ButtonScene.instantiate() + button_instance.label = entity + button_instance.on_button_down.connect(func(): _on_entity_click(entity) ) - devices_node.add_child(entity_instance) - entity_instance.set_entity_name(entity) + devices_node.add_child(button_instance) devices_node._update_container() diff --git a/content/ui/menu/edit/edit_menu.tscn b/content/ui/menu/edit/edit_menu.tscn index b9ca02f..db65995 100644 --- a/content/ui/menu/edit/edit_menu.tscn +++ b/content/ui/menu/edit/edit_menu.tscn @@ -1,9 +1,8 @@ -[gd_scene load_steps=5 format=3 uid="uid://crrb0l3ekuotj"] +[gd_scene load_steps=4 format=3 uid="uid://crrb0l3ekuotj"] [ext_resource type="Script" path="res://content/ui/menu/edit/edit_menu.gd" id="1_34cbn"] [ext_resource type="Script" path="res://content/ui/menu/grid.gd" id="3_0xvyw"] [ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="4_tvimg"] -[ext_resource type="Script" path="res://content/functions/clickable.gd" id="6_pf8jy"] [node name="EditMenu" type="Node3D"] script = ExtResource("1_34cbn") @@ -26,16 +25,12 @@ outline_size = 0 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.19, 0.01, 0.27) [node name="NextPageButton" parent="Buttons" instance=ExtResource("4_tvimg")] +focusable = true label = "navigate_next" icon = true -[node name="Clickable" type="Node" parent="Buttons/NextPageButton"] -script = ExtResource("6_pf8jy") - [node name="PreviousPageButton" parent="Buttons" instance=ExtResource("4_tvimg")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.08, 0, 0) +focusable = true label = "navigate_before" icon = true - -[node name="Clickable" type="Node" parent="Buttons/PreviousPageButton"] -script = ExtResource("6_pf8jy") diff --git a/content/ui/menu/edit/entity_creator.gd b/content/ui/menu/edit/entity_creator.gd index 61093a6..9d4e5f1 100644 --- a/content/ui/menu/edit/entity_creator.gd +++ b/content/ui/menu/edit/entity_creator.gd @@ -1,4 +1,4 @@ -extends Object +extends RefCounted const Switch = preload("res://content/entities/switch/switch.tscn") const Light = preload("res://content/entities/light/light.tscn") diff --git a/content/ui/menu/menu.gd b/content/ui/menu/menu.gd index 0d4aca1..061bb0d 100644 --- a/content/ui/menu/menu.gd +++ b/content/ui/menu/menu.gd @@ -1,5 +1,7 @@ extends Node3D +const Proxy = preload("res://lib/utils/proxy.gd") + @onready var _controller := XRHelpers.get_xr_controller(self) @onready var nav_view = $AnimationContainer/Navigation/View @@ -34,10 +36,25 @@ func _ready(): show_menu = !show_menu ) - select_menu(nav_edit) + var nav_buttons = [ + nav_view, + nav_edit, + nav_room, + nav_automate, + nav_settings + ] -func _on_click(event): - select_menu(event.target) + for nav_button in nav_buttons: + var getter = func(): + return nav_button == selected_nav + + var setter = func(value): + if value: + select_menu(nav_button) + + nav_button.external_value = Proxy.new(getter, setter) + + select_menu(nav_edit) func select_menu(nav): if _is_valid_nav(nav) == false || selected_nav == nav: @@ -46,13 +63,15 @@ func select_menu(nav): for child in content.get_children(): content.remove_child(child) - if selected_nav != null: - selected_nav.active = false + var old_nav = selected_nav selected_nav = nav + if old_nav != null: + old_nav.update_animation() + if selected_nav != null: - selected_nav.active = true + selected_nav.update_animation() var menu = _nav_to_menu(selected_nav) if menu != null: content.add_child(menu) diff --git a/content/ui/menu/menu.tscn b/content/ui/menu/menu.tscn index 888355e..a91b2c6 100644 --- a/content/ui/menu/menu.tscn +++ b/content/ui/menu/menu.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=12 format=3 uid="uid://c3kdssrmv84kv"] +[gd_scene load_steps=13 format=3 uid="uid://c3kdssrmv84kv"] [ext_resource type="Script" path="res://content/ui/menu/menu.gd" id="1_ng4u3"] [ext_resource type="PackedScene" uid="uid://crrb0l3ekuotj" path="res://content/ui/menu/edit/edit_menu.tscn" id="4_r2raj"] @@ -13,6 +13,9 @@ material = SubResource("StandardMaterial3D_ti5t2") size = Vector3(0.3, 0.01, 0.3) +[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_mgnm0"] +points = PackedVector3Array(-0.15, -0.005, -0.15, -0.15, 0.005, -0.15, 0.15, -0.005, -0.15, -0.15, -0.005, 0.15, -0.15, 0.005, 0.15, 0.15, 0.005, -0.15, 0.15, -0.005, 0.15, 0.15, 0.005, 0.15) + [sub_resource type="Animation" id="Animation_61md4"] length = 0.001 tracks/0/type = "bezier" @@ -153,13 +156,17 @@ _data = { [node name="Menu" type="Node3D"] script = ExtResource("1_ng4u3") -[node name="AnimationContainer" type="Node3D" parent="."] +[node name="AnimationContainer" type="StaticBody3D" parent="."] [node name="Background" type="MeshInstance3D" parent="AnimationContainer"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.21, 0, 0.15) mesh = SubResource("BoxMesh_08du6") skeleton = NodePath("../..") +[node name="CollisionShape3D" type="CollisionShape3D" parent="AnimationContainer"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.21, 0, 0.15) +shape = SubResource("ConvexPolygonShape3D_mgnm0") + [node name="Navigation" type="Node3D" parent="AnimationContainer"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.06, 0, 0) @@ -168,35 +175,30 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.03) label = "visibility" icon = true toggleable = true -external_state = true [node name="Edit" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.09) label = "widgets" icon = true toggleable = true -external_state = true [node name="Room" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.15) label = "view_in_ar" icon = true toggleable = true -external_state = true [node name="Automate" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.21) label = "schema" icon = true toggleable = true -external_state = true [node name="Settings" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.27) label = "settings" icon = true toggleable = true -external_state = true [node name="Content" type="Node3D" parent="AnimationContainer"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.06, 0, 0) diff --git a/content/ui/menu/room/room_menu.gd b/content/ui/menu/room/room_menu.gd index 9e1eddd..82a4485 100644 --- a/content/ui/menu/room/room_menu.gd +++ b/content/ui/menu/room/room_menu.gd @@ -27,10 +27,17 @@ func _ready(): add_corner(event.ray.get_collision_point()) ) - toggle_edit_button.get_node("Clickable").on_press_up.connect(func(event): - edit_enabled = event.target.active + toggle_edit_button.on_button_down.connect(func(): + edit_enabled = true + + wall_corners.visible = true + wall_edges.visible = true + wall_mesh.visible = false + ) + + toggle_edit_button.on_button_up.connect(func(): + edit_enabled = false - if edit_enabled == false: wall_corners.visible = false wall_edges.visible = false wall_mesh.mesh = generate_mesh() @@ -45,14 +52,13 @@ func _ready(): for collision in collisions: var static_body = StaticBody3D.new() + static_body.set_collision_layer_value(4, true) + static_body.set_collision_layer_value(5, true) + static_body.collision_mask = 0 static_body.add_child(collision) wall_collisions.add_child(static_body) wall_mesh.visible = true - else: - wall_corners.visible = true - wall_edges.visible = true - wall_mesh.visible = false ) func generate_mesh(): diff --git a/content/ui/menu/room/room_menu.tscn b/content/ui/menu/room/room_menu.tscn index b706edd..71a507b 100644 --- a/content/ui/menu/room/room_menu.tscn +++ b/content/ui/menu/room/room_menu.tscn @@ -18,6 +18,8 @@ script = ExtResource("1_ch4jb") [node name="TeleportRoot" type="Node3D" parent="."] [node name="Ground" type="StaticBody3D" parent="TeleportRoot"] +collision_layer = 24 +collision_mask = 0 [node name="CollisionShape3D" type="CollisionShape3D" parent="TeleportRoot/Ground"] shape = SubResource("WorldBoundaryShape3D_08sv0") diff --git a/content/ui/menu/settings/ball.tscn b/content/ui/menu/settings/ball.tscn index f549a12..b982d05 100644 --- a/content/ui/menu/settings/ball.tscn +++ b/content/ui/menu/settings/ball.tscn @@ -9,6 +9,8 @@ bounce = 0.7 radius = 0.08 [node name="Ball" type="RigidBody3D"] +collision_layer = 8 +collision_mask = 24 physics_material_override = SubResource("PhysicsMaterial_f6jtg") angular_damp = 4.0 diff --git a/content/ui/menu/settings/credits.tscn b/content/ui/menu/settings/credits.tscn index 252500f..c5375a5 100644 --- a/content/ui/menu/settings/credits.tscn +++ b/content/ui/menu/settings/credits.tscn @@ -36,7 +36,7 @@ outline_size = 0 autowrap_mode = 3 [node name="Room" type="Label3D" parent="Content"] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, -0.06) +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 9.31323e-10, -0.049608) pixel_size = 0.001 modulate = Color(0, 0, 0, 1) text = "This work is based on \"Living Room\" (https://sketchfab.com/3d-models/living-room-2978ca6c93fb4f5c83e346d5ecdef0b0) by Chin.Seng.Choy (https://sketchfab.com/Chin.Seng.Choy) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)" diff --git a/content/ui/menu/settings/settings_menu.gd b/content/ui/menu/settings/settings_menu.gd index 8642a89..f454b0e 100644 --- a/content/ui/menu/settings/settings_menu.gd +++ b/content/ui/menu/settings/settings_menu.gd @@ -3,7 +3,7 @@ extends Node3D const ball_scene = preload("./ball.tscn") const credits_scene = preload("./credits.tscn") -@onready var clickable = $Content/Button/Clickable +@onready var ball_button = $Content/Button @onready var connection_status = $Content/ConnectionStatus @onready var input_url = $Content/InputURL @@ -15,10 +15,12 @@ const credits_scene = preload("./credits.tscn") func _ready(): background.visible = false - clickable.on_click.connect(func(event): + ball_button.on_button_down.connect(func(): var ball = ball_scene.instantiate() - ball.transform = event.controller.transform - ball.linear_velocity = -event.controller.transform.basis.z * 5 + Vector3(0, 5, 0) + var controller = XRHelpers.get_right_controller(self) + + ball.transform = controller.transform + ball.linear_velocity = -controller.transform.basis.z * 5 + Vector3(0, 5, 0) get_tree().root.add_child(ball) ) diff --git a/export_presets.cfg b/export_presets.cfg index 079a9ed..7f41361 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -43,9 +43,9 @@ launcher_icons/adaptive_foreground_432x432="" launcher_icons/adaptive_background_432x432="" graphics/opengl_debug=false xr_features/xr_mode=1 -xr_features/hand_tracking=0 +xr_features/hand_tracking=1 xr_features/hand_tracking_frequency=1 -xr_features/passthrough=1 +xr_features/passthrough=2 screen/immersive_mode=true screen/support_small=true screen/support_normal=true diff --git a/export_presets_prod.cfg b/export_presets_prod.cfg index 925ce4e..8311756 100644 --- a/export_presets_prod.cfg +++ b/export_presets_prod.cfg @@ -43,9 +43,9 @@ launcher_icons/adaptive_foreground_432x432="" launcher_icons/adaptive_background_432x432="" graphics/opengl_debug=false xr_features/xr_mode=1 -xr_features/hand_tracking=0 +xr_features/hand_tracking=1 xr_features/hand_tracking_frequency=1 -xr_features/passthrough=1 +xr_features/passthrough=2 screen/immersive_mode=true screen/support_small=true screen/support_normal=true diff --git a/lib/events/event_focus.gd b/lib/events/event_focus.gd index 7c88f49..24b0449 100644 --- a/lib/events/event_focus.gd +++ b/lib/events/event_focus.gd @@ -1,6 +1,5 @@ extends Event class_name EventFocus -var ray: RayCast3D var target: Node var previous_target: Node \ No newline at end of file diff --git a/lib/events/event_pointer.gd b/lib/events/event_pointer.gd new file mode 100644 index 0000000..1b87346 --- /dev/null +++ b/lib/events/event_pointer.gd @@ -0,0 +1,7 @@ +extends EventBubble +class_name EventPointer + +const Initiator = preload("res://lib/utils/pointer/initiator.gd") + +var initiator: Initiator +var ray: RayCast3D \ No newline at end of file diff --git a/lib/events/event_ray.gd b/lib/events/event_ray.gd deleted file mode 100644 index aa2765d..0000000 --- a/lib/events/event_ray.gd +++ /dev/null @@ -1,6 +0,0 @@ -extends EventBubble -class_name EventRay - -var controller: XRController3D -var is_right_controller: bool -var ray: RayCast3D \ No newline at end of file diff --git a/lib/events/event_touch.gd b/lib/events/event_touch.gd new file mode 100644 index 0000000..3c38616 --- /dev/null +++ b/lib/events/event_touch.gd @@ -0,0 +1,12 @@ +extends EventBubble +class_name EventTouch + +const Finger = preload("res://lib/utils/touch/finger.gd") + +var fingers: Array[Finger] = [] + +func has_finger(finger: Finger.Type): + for f in fingers: + if f.type == finger: + return true + return false \ No newline at end of file diff --git a/lib/globals/event_system.gd b/lib/globals/event_system.gd index fed2f1b..3ccabc5 100644 --- a/lib/globals/event_system.gd +++ b/lib/globals/event_system.gd @@ -4,15 +4,15 @@ const FN_PREFIX = "_on_" const SIGNAL_PREFIX = "on_" # Interaction Events -signal on_click(event: EventRay) -signal on_press_down(event: EventRay) -signal on_press_move(event: EventRay) -signal on_press_up(event: EventRay) -signal on_grab_down(event: EventRay) -signal on_grab_move(event: EventRay) -signal on_grab_up(event: EventRay) -signal on_ray_enter(event: EventRay) -signal on_ray_leave(event: EventRay) +signal on_click(event: EventPointer) +signal on_press_down(event: EventPointer) +signal on_press_move(event: EventPointer) +signal on_press_up(event: EventPointer) +signal on_grab_down(event: EventPointer) +signal on_grab_move(event: EventPointer) +signal on_grab_up(event: EventPointer) +signal on_ray_enter(event: EventPointer) +signal on_ray_leave(event: EventPointer) signal on_key_down(event: EventKey) signal on_key_up(event: EventKey) @@ -20,43 +20,53 @@ signal on_key_up(event: EventKey) signal on_focus_in(event: EventFocus) signal on_focus_out(event: EventFocus) +signal on_touch_enter(event: EventTouch) +signal on_touch_move(event: EventTouch) +signal on_touch_leave(event: EventTouch) + var _active_node: Node = null func emit(type: String, event: Event): if event is EventBubble: _bubble_call(type, event.target, event) - if type == "press_down": - _handle_focus(event) else: _root_call(type, event) func is_focused(node: Node): return _active_node == node -func _handle_focus(event: EventRay): - if event.target != null && event.target.is_in_group("ui_focus_skip"): - return +func _handle_focus(target: Variant, event: EventBubble): + print("focus ", target, " ", target.get_groups(), " ", event) + + if target != null: + if target.is_in_group("ui_focus_skip"): + return false + if target.is_in_group("ui_focus_stop"): + return true var event_focus = EventFocus.new() event_focus.previous_target = _active_node - event_focus.target = event.target - event_focus.ray = event.ray + event_focus.target = target if _active_node != null && _active_node.has_method(FN_PREFIX + "focus_out"): _active_node.call(FN_PREFIX + "focus_out", event_focus) on_focus_out.emit(event_focus) - if event.target == null || event.target.is_in_group("ui_focus") == false: + if target == null || target.is_in_group("ui_focus") == false: _active_node = null - return + return false - _active_node = event.target + _active_node = target + + print("focus", _active_node ) if _active_node != null && _active_node.has_method(FN_PREFIX + "focus_in"): _active_node.call(FN_PREFIX + "focus_in", event_focus) on_focus_in.emit(event_focus) -func _bubble_call(type: String, target: Variant, event: EventBubble): + return true + +func _bubble_call(type: String, target: Variant, event: EventBubble, focused = false): if target == null: return false @@ -70,6 +80,9 @@ func _bubble_call(type: String, target: Variant, event: EventBubble): if event.bubbling == false: return false + if (type == "press_down" || type == "touch_enter") && focused == false: + focused = _handle_focus(target, event) + for child in target.get_children(): if child is Function && child.has_method(FN_PREFIX + type): child.call(FN_PREFIX + type, event) @@ -77,7 +90,7 @@ func _bubble_call(type: String, target: Variant, event: EventBubble): var parent = target.get_parent() if parent != null && parent is Node: - _bubble_call(type, parent, event) + _bubble_call(type, parent, event, focused) else: # in case the top has been reached _root_call(type, event) diff --git a/lib/utils/pointer/initiator.gd b/lib/utils/pointer/initiator.gd new file mode 100644 index 0000000..d76af07 --- /dev/null +++ b/lib/utils/pointer/initiator.gd @@ -0,0 +1,22 @@ +extends RefCounted + +enum Type { + CONTROLLER_LEFT, + CONTROLLER_RIGHT, + HAND_LEFT, + HAND_RIGHT, +} + +enum EventType { + GRIP, + TRIGGER, +} + +signal on_press(type: EventType) +signal on_release(type: EventType) + +var node: Node3D +var type: Type + +func is_right() -> bool: + return type == Type.CONTROLLER_RIGHT || type == Type.HAND_RIGHT \ No newline at end of file diff --git a/lib/utils/pointer/pointer.gd b/lib/utils/pointer/pointer.gd new file mode 100644 index 0000000..90bd707 --- /dev/null +++ b/lib/utils/pointer/pointer.gd @@ -0,0 +1,98 @@ +extends Node + +const Initiator = preload("./initiator.gd") + +var initiator: Initiator +var ray: RayCast3D + +var timespan_click = 400.0 + +var last_collided: Object = null +var is_pressed := false +var is_grabbed := false +var time_pressed := 0.0 +var moved := false +var click_point := Vector3.ZERO + +func _init(initiator: Initiator, ray: RayCast3D): + self.initiator = initiator + self.ray = ray + +func _ready(): + initiator.on_press.connect(_on_pressed) + initiator.on_release.connect(_on_released) + +func _physics_process(_delta): + _handle_enter_leave() + _handle_move() + +func _handle_move(): + var time_passed = Time.get_ticks_msec() - time_pressed + if time_passed <= timespan_click || (is_pressed == false && is_grabbed == false): + return + + moved = true + + # reset if last_collided gets deleted + if is_instance_valid(last_collided) == false: + last_collided = null + return + + if is_pressed: + _emit_event("press_move", last_collided ) + + if is_grabbed: + _emit_event("grab_move", last_collided ) + +func _handle_enter_leave(): + var collider = ray.get_collider() + + if collider == last_collided || is_grabbed || is_pressed: + return + + _emit_event("ray_enter", collider ) + _emit_event("ray_leave", last_collided ) + + last_collided = collider + +func _on_pressed(type: Initiator.EventType): + var collider = ray.get_collider() + + if collider == null: + return + + match type: + Initiator.EventType.TRIGGER: + is_pressed = true + time_pressed = Time.get_ticks_msec() + click_point = ray.get_collision_point() + _emit_event("press_down", collider ) + Initiator.EventType.GRIP: + is_grabbed = true + click_point = ray.get_collision_point() + _emit_event("grab_down", collider ) + +func _on_released(type: Initiator.EventType): + match type: + Initiator.EventType.TRIGGER: + if is_pressed: + if moved == false: + _emit_event("click", last_collided ) + _emit_event("press_up", last_collided ) + is_pressed = false + last_collided = null + moved = false + Initiator.EventType.GRIP: + if is_grabbed: + _emit_event("grab_up", last_collided ) + is_grabbed = false + last_collided = null + moved = false + +func _emit_event(type: String, target): + var event = EventPointer.new() + event.initiator = initiator + event.target = target + event.ray = ray + + EventSystem.emit(type, event) diff --git a/lib/utils/proxy.gd b/lib/utils/proxy.gd new file mode 100644 index 0000000..376db93 --- /dev/null +++ b/lib/utils/proxy.gd @@ -0,0 +1,14 @@ +extends RefCounted + +var gettable: Callable +var settable: Callable + +func _init(gettable: Callable, settable: Callable): + self.gettable = gettable + self.settable = settable + +var value: Variant: + get: + return gettable.call() + set(new_value): + settable.call(new_value) \ No newline at end of file diff --git a/lib/utils/touch/finger.gd b/lib/utils/touch/finger.gd new file mode 100644 index 0000000..4b29b84 --- /dev/null +++ b/lib/utils/touch/finger.gd @@ -0,0 +1,17 @@ +extends RefCounted + +enum Type { + THUMB_RIGHT, + INDEX_RIGHT, + MIDDLE_RIGHT, + RING_RIGHT, + LITTLE_RIGHT, + THUMB_LEFT, + INDEX_LEFT, + MIDDLE_LEFT, + RING_LEFT, + LITTLE_LEFT, +} + +var type: Type +var area: Area3D \ No newline at end of file diff --git a/lib/utils/touch/touch.gd b/lib/utils/touch/touch.gd new file mode 100644 index 0000000..3fc2642 --- /dev/null +++ b/lib/utils/touch/touch.gd @@ -0,0 +1,57 @@ +extends Node + +const Finger = preload("res://lib/utils/touch/finger.gd") + +## Record +var finger_areas: Dictionary + +var areas_entered = {} + +func _init(finger_areas: Dictionary): + self.finger_areas = finger_areas + +func _ready(): + for finger_type in finger_areas.keys(): + finger_areas[finger_type].area_entered.connect(func(area): + _on_area_entered(finger_type, area) + ) + + finger_areas[finger_type].area_exited.connect(func(area): + _on_area_exited(finger_type, area) + ) + +func _physics_process(_delta): + for area in areas_entered.keys(): + _emit_event("touch_move", area) + +func _on_area_entered(finger_type, area): + if areas_entered.has(area): + if !areas_entered[area].has(finger_type): + areas_entered[area].append(finger_type) + _emit_event("touch_enter", area) + else: + areas_entered[area] = [finger_type] + _emit_event("touch_enter", area) + +func _on_area_exited(finger_type, area): + if areas_entered.has(area): + if areas_entered[area].has(finger_type): + areas_entered[area].erase(finger_type) + + if areas_entered[area].size() == 0: + _emit_event("touch_leave", area) + areas_entered.erase(area) + +func _emit_event(type: String, target): + var event = EventTouch.new() + event.target = target + var fingers: Array[Finger] = [] + for finger_type in areas_entered[target]: + var finger = Finger.new() + finger.type = finger_type + finger.area = finger_areas[finger_type] + fingers.append(finger) + + event.fingers = fingers + + EventSystem.emit(type, event) diff --git a/project.godot b/project.godot index 3b09c45..800e839 100644 --- a/project.godot +++ b/project.godot @@ -28,10 +28,22 @@ EventSystem="*res://lib/globals/event_system.gd" enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg") +[filesystem] + +import/fbx/enabled=false + [gui] theme/custom_font="res://assets/fonts/ui_font_500.tres" +[layer_names] + +3d_physics/layer_1="entities" +3d_physics/layer_2="interface" +3d_physics/layer_3="touch" +3d_physics/layer_4="physics" +3d_physics/layer_5="room" + [rendering] renderer/rendering_method="mobile"