implement basic hand collisions
This commit is contained in:
parent
e5206f896b
commit
c281c17921
|
@ -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"]
|
||||
|
|
|
@ -4,6 +4,7 @@ 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):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
15
content/system/hands/touch_area.gd
Normal file
15
content/system/hands/touch_area.gd
Normal 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
16
content/ui/console.gd
Normal 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
34
content/ui/console.tscn
Normal 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")
|
|
@ -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")
|
||||
|
|
66
lib/utils/touch/collide.gd
Normal file
66
lib/utils/touch/collide.gd
Normal 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)
|
Loading…
Reference in New Issue
Block a user