From c281c17921daf17561c899383e70311112bd3c1d Mon Sep 17 00:00:00 2001 From: Nitwel Date: Tue, 27 Feb 2024 16:39:47 +0100 Subject: [PATCH] implement basic hand collisions --- content/main.tscn | 15 +++++-- content/system/hands/hands.gd | 46 ++++++++++++--------- content/system/hands/hands.tscn | 20 +++++++-- content/system/hands/touch_area.gd | 15 +++++++ content/ui/console.gd | 16 ++++++++ content/ui/console.tscn | 34 +++++++++++++++ content/ui/menu/menu.tscn | 15 ++++++- lib/utils/touch/collide.gd | 66 ++++++++++++++++++++++++++++++ 8 files changed, 198 insertions(+), 29 deletions(-) create mode 100644 content/system/hands/touch_area.gd create mode 100644 content/ui/console.gd create mode 100644 content/ui/console.tscn create mode 100644 lib/utils/touch/collide.gd diff --git a/content/main.tscn b/content/main.tscn index 302c622..288fc42 100644 --- a/content/main.tscn +++ b/content/main.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=15 format=3 uid="uid://eecv28y6jxk4"] +[gd_scene load_steps=16 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"] @@ -10,16 +10,20 @@ [ext_resource type="PackedScene" uid="uid://c3kdssrmv84kv" path="res://content/ui/menu/menu.tscn" id="8_du83w"] [ext_resource type="PackedScene" uid="uid://lrehk38exd5n" path="res://content/system/keyboard/keyboard.tscn" id="9_e5n3p"] [ext_resource type="PackedScene" uid="uid://cbemihbxkd4ll" path="res://content/system/house/house.tscn" id="9_np6mw"] +[ext_resource type="PackedScene" uid="uid://6jhh4qy74px3" path="res://content/ui/console.tscn" id="11_x4ttb"] [sub_resource type="Sky" id="Sky_vhymk"] sky_material = ExtResource("5_wgwf8") [sub_resource type="Environment" id="Environment_7ghp0"] -background_mode = 2 -background_color = Color(0.466667, 0.47451, 0.462745, 0) +background_mode = 1 +background_color = Color(1, 1, 1, 0) +background_energy_multiplier = 0.0 sky = SubResource("Sky_vhymk") +ambient_light_source = 2 ambient_light_color = Color(1, 1, 1, 1) -ambient_light_sky_contribution = 0.72 +ambient_light_energy = 0.5 +reflected_light_source = 1 ssao_radius = 6.52 ssao_intensity = 5.68 @@ -82,4 +86,7 @@ transform = Transform3D(0.499999, -0.000139169, -6.50204e-05, 5.24307e-05, 0.353 [node name="House" parent="." instance=ExtResource("9_np6mw")] +[node name="Console" parent="." instance=ExtResource("11_x4ttb")] +transform = Transform3D(1, -1.39637e-11, 0, 9.47975e-12, 1, 0, 0, 0, 1, 0.987155, -0.000294938, -0.563576) + [editable path="XROrigin3D/XRControllerLeft"] diff --git a/content/system/hands/hands.gd b/content/system/hands/hands.gd index bd7873a..93bc96d 100644 --- a/content/system/hands/hands.gd +++ b/content/system/hands/hands.gd @@ -1,9 +1,10 @@ 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") +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") +const Collide = preload ("res://lib/utils/touch/collide.gd") @onready var hand_right: OpenXRHand = $XRHandRight @onready var hand_left: OpenXRHand = $XRHandLeft @@ -11,6 +12,7 @@ const Touch = preload("res://lib/utils/touch/touch.gd") @export var ray_right: RayCast3D var initiator: Initiator = Initiator.new() var touch: Touch +var collide: Collide var pointer: Pointer var press_distance = 0.03 var grip_distance = 0.03 @@ -22,13 +24,17 @@ var grabbed_left = false var grabbed_right = false func _ready(): - touch = Touch.new({ + var fingers = { 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 - }) + } + + touch = Touch.new(fingers) + collide = Collide.new(hand_left, hand_right, fingers) add_child(touch) + add_child(collide) _ready_hand(hand_right) @@ -39,7 +45,7 @@ func _ready_hand(hand: OpenXRHand): pointer = Pointer.new(initiator, ray_left if hand == hand_left else ray_right) add_child(pointer) -func _process(_delta): +func _physics_process(_delta): _process_hand(hand_right) func _process_hand(hand: OpenXRHand): @@ -52,7 +58,7 @@ func _process_hand(hand: OpenXRHand): 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 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 @@ -61,46 +67,46 @@ func _process_hand(hand: OpenXRHand): if hand == hand_left: if !distance_close: - if trigger_close && !pressed_left: + if trigger_close&&!pressed_left: initiator.on_press.emit(Initiator.EventType.TRIGGER) pressed_left = true - elif !trigger_close && pressed_left: + elif !trigger_close&&pressed_left: initiator.on_release.emit(Initiator.EventType.TRIGGER) pressed_left = false - if grab_close && !grabbed_left: + if grab_close&&!grabbed_left: initiator.on_press.emit(Initiator.EventType.GRIP) grabbed_left = true - elif !grab_close && grabbed_left: + elif !grab_close&&grabbed_left: initiator.on_release.emit(Initiator.EventType.GRIP) grabbed_left = false else: - if trigger_close && !grabbed_right: + if trigger_close&&!grabbed_right: initiator.on_press.emit(Initiator.EventType.GRIP) grabbed_right = true - elif !trigger_close && grabbed_right: + elif !trigger_close&&grabbed_right: initiator.on_release.emit(Initiator.EventType.GRIP) grabbed_right = false else: if !distance_close: - if trigger_close && !pressed_right: + if trigger_close&&!pressed_right: initiator.on_press.emit(Initiator.EventType.TRIGGER) pressed_right = true - elif !trigger_close && pressed_right: + elif !trigger_close&&pressed_right: initiator.on_release.emit(Initiator.EventType.TRIGGER) pressed_right = false - if grab_close && !grabbed_right: + if grab_close&&!grabbed_right: initiator.on_press.emit(Initiator.EventType.GRIP) grabbed_right = true - elif !grab_close && grabbed_right: + elif !grab_close&&grabbed_right: initiator.on_release.emit(Initiator.EventType.GRIP) grabbed_right = false else: - if trigger_close && !grabbed_right: + if trigger_close&&!grabbed_right: initiator.on_press.emit(Initiator.EventType.GRIP) grabbed_right = true - elif !trigger_close && grabbed_right: + 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 index a0efb03..e66dcb1 100644 --- a/content/system/hands/hands.tscn +++ b/content/system/hands/hands.tscn @@ -1,9 +1,13 @@ -[gd_scene load_steps=6 format=3 uid="uid://bsx12q23v8apy"] +[gd_scene load_steps=8 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="StandardMaterial3D" id="StandardMaterial3D_3bjtw"] +transparency = 1 +albedo_color = Color(1, 1, 1, 0.705882) + [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dopke"] radius = 0.001 height = 0.02 @@ -11,6 +15,10 @@ height = 0.02 [sub_resource type="BoxShape3D" id="BoxShape3D_1pxrt"] size = Vector3(0.14, 0.0224609, 0.169383) +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_n27ki"] +transparency = 1 +albedo_color = Color(1, 1, 1, 0.705882) + [node name="Hands" type="Node3D"] script = ExtResource("1_c4f76") @@ -21,6 +29,9 @@ 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) +[node name="vr_glove_left_slim" parent="XRHandLeft/left_hand/Armature_001/Skeleton3D" index="0"] +material_override = SubResource("StandardMaterial3D_3bjtw") + [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.164767) bone_name = "Index_Tip_L" @@ -84,7 +95,7 @@ shape = SubResource("BoxShape3D_1pxrt") 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) +transform = Transform3D(0.999998, -0.000567105, 2.47889e-11, 0, -4.37113e-08, -0.999999, 0.000567104, 0.999999, -4.37113e-08, 0.264391, 0, 0) hand = 1 hand_skeleton = NodePath("right_hand/Armature/Skeleton3D") @@ -92,6 +103,7 @@ hand_skeleton = NodePath("right_hand/Armature/Skeleton3D") [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) +material_override = SubResource("StandardMaterial3D_n27ki") [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.0355401) @@ -124,7 +136,7 @@ external_skeleton = NodePath("../right_hand/Armature/Skeleton3D") 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.00654216) +transform = Transform3D(0.0812011, 0.650531, 0.755126, -0.0155557, -0.756709, 0.653568, 0.996576, -0.0648169, -0.0513262, -0.032112, -0.171612, -0.00654216) bone_name = "Middle_Tip_R" bone_idx = 14 use_external_skeleton = true @@ -144,7 +156,7 @@ transform = Transform3D(1, -7.45058e-09, -2.22045e-16, 7.45058e-09, 1, 0, 0, 0, shape = SubResource("CapsuleShape3D_dopke") [node name="AnimatableBody3D" type="AnimatableBody3D" parent="XRHandRight"] -transform = Transform3D(1, 0, 4.7579e-13, 0, 1, 0, -1.34149e-12, 1.77636e-15, 1, 0, 0, 0) +transform = Transform3D(1, 0, 0, 0, 1, 3.55271e-15, 0, -3.55271e-15, 1, 0, 0, 0) collision_layer = 8 collision_mask = 8 diff --git a/content/system/hands/touch_area.gd b/content/system/hands/touch_area.gd new file mode 100644 index 0000000..01bdf94 --- /dev/null +++ b/content/system/hands/touch_area.gd @@ -0,0 +1,15 @@ +extends Area3D +class_name TouchBody3D + +@export var plane = Plane.PLANE_XZ + +func _ready(): + var collisionShape = null + + for child in get_children(): + if child is CollisionShape3D: + collisionShape = child + break + + if collisionShape != null: + plane.d = collisionShape.shape.size.y / 2 + collisionShape.position.y diff --git a/content/ui/console.gd b/content/ui/console.gd new file mode 100644 index 0000000..ab59980 --- /dev/null +++ b/content/ui/console.gd @@ -0,0 +1,16 @@ +extends StaticBody3D + +@onready var label = $Label3D + +var max_message = 30 +var messages: Array = ["aaa", "bbb"] + +func log(text: String) -> void: + messages.push_front(text) + + if messages.size() > max_message: + messages.pop_back() + +func _process(_delta: float) -> void: + + label.text = "\n".join(messages) diff --git a/content/ui/console.tscn b/content/ui/console.tscn new file mode 100644 index 0000000..682fb56 --- /dev/null +++ b/content/ui/console.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=6 format=3 uid="uid://6jhh4qy74px3"] + +[ext_resource type="Script" path="res://content/ui/console.gd" id="1_ullcc"] +[ext_resource type="Script" path="res://content/functions/movable.gd" id="2_gfjlg"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_6xl4b"] +size = Vector3(1, 0.05, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_087gr"] +cull_mode = 2 + +[sub_resource type="QuadMesh" id="QuadMesh_chf50"] + +[node name="Console" type="StaticBody3D"] +script = ExtResource("1_ullcc") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("BoxShape3D_6xl4b") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.01, 0, 0) +material_override = SubResource("StandardMaterial3D_087gr") +mesh = SubResource("QuadMesh_chf50") + +[node name="Label3D" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.477142, 0.00806178, -0.495248) +pixel_size = 0.001 +text = "Texst +aaa" +horizontal_alignment = 0 +vertical_alignment = 0 + +[node name="Movable" type="Node" parent="."] +script = ExtResource("2_gfjlg") diff --git a/content/ui/menu/menu.tscn b/content/ui/menu/menu.tscn index a8acc5a..dc050e8 100644 --- a/content/ui/menu/menu.tscn +++ b/content/ui/menu/menu.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=19 format=3 uid="uid://c3kdssrmv84kv"] +[gd_scene load_steps=21 format=3 uid="uid://c3kdssrmv84kv"] [ext_resource type="Script" path="res://content/ui/menu/menu.gd" id="1_ng4u3"] [ext_resource type="Material" uid="uid://bnwimm214q67g" path="res://assets/materials/sec-500.material" id="2_0x5at"] [ext_resource type="Script" path="res://content/functions/movable.gd" id="2_8coxu"] +[ext_resource type="Script" path="res://content/system/hands/touch_area.gd" id="2_fxtnc"] [ext_resource type="Script" path="res://content/ui/components/tabs/tabs.gd" id="4_eavfx"] [ext_resource type="PackedScene" uid="uid://crrb0l3ekuotj" path="res://content/ui/menu/edit/edit_menu.tscn" id="4_r2raj"] [ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="5_w4i01"] @@ -12,6 +13,9 @@ [ext_resource type="PackedScene" uid="uid://c01gkeldvjwtr" path="res://content/ui/menu/room/room_menu.tscn" id="10_u4i1x"] [ext_resource type="PackedScene" uid="uid://c6r4higceibif" path="res://content/ui/menu/settings/settings_menu.tscn" id="11_7wm6b"] +[sub_resource type="BoxShape3D" id="BoxShape3D_fgcdq"] +size = Vector3(1, 0.51, 1) + [sub_resource type="BoxShape3D" id="BoxShape3D_e1esh"] size = Vector3(0.38, 0.01, 0.32) @@ -164,6 +168,15 @@ _data = { [node name="Menu" type="StaticBody3D"] script = ExtResource("1_ng4u3") +[node name="TouchBody3D" type="Area3D" parent="."] +collision_layer = 13311 +collision_mask = 0 +script = ExtResource("2_fxtnc") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="TouchBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.245, 0) +shape = SubResource("BoxShape3D_fgcdq") + [node name="CollisionShape3D" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.02, -0.00426685, 1.49012e-08) shape = SubResource("BoxShape3D_e1esh") diff --git a/lib/utils/touch/collide.gd b/lib/utils/touch/collide.gd new file mode 100644 index 0000000..00da480 --- /dev/null +++ b/lib/utils/touch/collide.gd @@ -0,0 +1,66 @@ +extends Node3D + +const Finger = preload ("res://lib/utils/touch/finger.gd") + +## Record +var finger_areas: Dictionary + +## Record> +var bodies_entered = {} +var hand_left: Node3D +var hand_right: Node3D + +@onready var console = get_node("/root/Main/Console") + +func _init(hand_left: OpenXRHand, hand_right: OpenXRHand, finger_areas: Dictionary): + self.finger_areas = finger_areas + self.hand_left = hand_left.get_node("left_hand/Armature_001/Skeleton3D/vr_glove_left_slim") + self.hand_right = hand_right.get_node("right_hand/Armature/Skeleton3D/vr_glove_right_slim") + +func _ready(): + for finger_type in finger_areas.keys(): + + finger_areas[finger_type].area_entered.connect(func(body): + if body is TouchBody3D: + _on_body_entered(finger_type, body) + ) + + finger_areas[finger_type].area_exited.connect(func(body): + if body is TouchBody3D: + _on_body_exited(finger_type, body) + ) + +func _physics_process(_delta): + hand_left.position = Vector3.ZERO + hand_right.position = Vector3.ZERO + + for body in bodies_entered.keys(): + var fingers = bodies_entered[body] + + for finger in fingers: + if finger == Finger.Type.INDEX_LEFT: + var start_pos = finger_areas[finger].global_position + var end_pos = body.to_global(body.plane.project(body.to_local(start_pos))) + + hand_left.global_position = end_pos + (hand_left.global_position - start_pos) + + elif finger == Finger.Type.INDEX_RIGHT: + var start_pos = finger_areas[finger].global_position + var end_pos = body.to_global(body.plane.project(body.to_local(start_pos))) + + hand_right.global_position = end_pos + (hand_right.global_position - start_pos) + +func _on_body_entered(finger_type, body): + if bodies_entered.has(body): + if !bodies_entered[body].has(finger_type): + bodies_entered[body].append(finger_type) + else: + bodies_entered[body] = [finger_type] + +func _on_body_exited(finger_type, body): + if bodies_entered.has(body): + if bodies_entered[body].has(finger_type): + bodies_entered[body].erase(finger_type) + + if bodies_entered[body].size() == 0: + bodies_entered.erase(body) \ No newline at end of file