Merge pull request #102 from Nitwel/performance

Implement basic hand collisions
This commit is contained in:
Nitwel 2024-02-27 16:40:30 +01:00 committed by GitHub
commit 1a47406e9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 198 additions and 29 deletions

View File

@ -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"]

View File

@ -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):
@ -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

View File

@ -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

View File

@ -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

16
content/ui/console.gd Normal file
View File

@ -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)

34
content/ui/console.tscn Normal file
View File

@ -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")

View File

@ -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")

View File

@ -0,0 +1,66 @@
extends Node3D
const Finger = preload ("res://lib/utils/touch/finger.gd")
## Record<Finger.Type, Area3D>
var finger_areas: Dictionary
## Record<TouchBody3D, Array<Finger.Type>>
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)