refactor touch and trigger handling to allow for touch controls

This commit is contained in:
Crispy 2021-10-12 14:51:22 +02:00
parent a073c19e9c
commit dc6a9929b7
11 changed files with 145 additions and 63 deletions

View file

@ -1,6 +1,7 @@
[gd_scene load_steps=2 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/overlay_interaction.gd" type="Script" id=1]
[ext_resource path="res://addons/openvr_overlay/interaction/OverlayArea.tscn" type="PackedScene" id=2]
[node name="OverlayInteraction" type="Node"]
script = ExtResource( 1 )
@ -15,6 +16,8 @@ controller_id = 2
[node name="head" type="ARVRCamera" parent="VR"]
visible = false
[node name="OverlayArea" parent="." instance=ExtResource( 2 )]
[connection signal="button_pressed" from="VR/left" to="." method="_on_LeftHand_button_pressed"]
[connection signal="button_release" from="VR/left" to="." method="_on_LeftHand_button_release"]
[connection signal="button_pressed" from="VR/right" to="." method="_on_RightHand_button_pressed"]

View file

@ -1,6 +1,7 @@
[gd_scene load_steps=2 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/OverlayActivator.tscn" type="PackedScene" id=1]
[ext_resource path="res://addons/openvr_overlay/interaction/HandCollider.tscn" type="PackedScene" id=1]
[ext_resource path="res://addons/openvr_overlay/interaction/TouchCollider.tscn" type="PackedScene" id=2]
[node name="OverlayInteractionRoot" type="Node"]
@ -8,16 +9,32 @@
[node name="left" type="ARVRController" parent="VR"]
[node name="OverlayActivator" parent="VR/left" instance=ExtResource( 1 )]
[node name="HandCollider" parent="VR/left" groups=[
"left",
] instance=ExtResource( 1 )]
collision_layer = 4
collision_mask = 4
[node name="TouchCollider" parent="VR/left" groups=[
"left",
] instance=ExtResource( 2 )]
collision_layer = 16
collision_mask = 16
[node name="right" type="ARVRController" parent="VR"]
controller_id = 2
[node name="OverlayActivator" parent="VR/right" instance=ExtResource( 1 )]
[node name="HandCollider" parent="VR/right" groups=[
"right",
] instance=ExtResource( 1 )]
collision_layer = 2
collision_mask = 2
[node name="TouchCollider" parent="VR/right" groups=[
"right",
] instance=ExtResource( 2 )]
collision_layer = 8
collision_mask = 8
[node name="head" type="ARVRCamera" parent="VR"]
visible = false

View file

@ -2,11 +2,9 @@
[sub_resource type="SphereShape" id=1]
margin = 0.001
radius = 0.01
radius = 0.03
[node name="OverlayActivator" type="StaticBody" groups=[
"OverlayActivator",
]]
[node name="HandCollider" type="StaticBody"]
[node name="Collision" type="CollisionShape" parent="."]
shape = SubResource( 1 )

View file

@ -4,9 +4,18 @@
resource_local_to_scene = true
extents = Vector3( 0.2, 0.2, 0.01 )
[node name="OverlayArea" type="Area"]
[node name="OverlayArea" type="Spatial"]
[node name="AreaNear" type="Area" parent="."]
collision_layer = 0
collision_mask = 6
[node name="CollisionShape" type="CollisionShape" parent="."]
[node name="CollisionShape" type="CollisionShape" parent="AreaNear"]
shape = SubResource( 1 )
[node name="AreaTouch" type="Area" parent="."]
collision_layer = 0
collision_mask = 24
[node name="CollisionShape" type="CollisionShape" parent="AreaTouch"]
shape = SubResource( 1 )

View file

@ -0,0 +1,10 @@
[gd_scene load_steps=2 format=2]
[sub_resource type="SphereShape" id=1]
margin = 0.001
radius = 0.0
[node name="TouchCollider" type="StaticBody"]
[node name="Collision" type="CollisionShape" parent="."]
shape = SubResource( 1 )

View file

@ -23,11 +23,17 @@ func _process(_delta: float) -> void:
#get canvas position of active controller
func get_canvas_pos() -> Vector2:
if not _i.active_controller:
var active
if _i.state.right.near:
active = "right"
elif _i.state.left.near:
active = "left"
else:
return Vector2(-1000, 1000) # offscreen
#if not (_i.state.right.near or _i.state.left.near):
var controller_local_pos = _i._overlay_area.global_transform.xform_inv(\
_i.tracker_nodes[_i.active_controller].translation)
_i.tracker_nodes[active].translation)
var pos = Vector2(controller_local_pos.x, controller_local_pos.y)
var overlay_size = Vector2(2048, 2048)
@ -61,10 +67,10 @@ func _send_click_event(state: bool):
viewport.input(click_event)
func _trigger_on():
func _trigger_on(controller):
_send_click_event(true)
func _trigger_off():
func _trigger_off(controller):
_send_click_event(false)

View file

@ -22,18 +22,18 @@ func _ready() -> void:
get_parent().connect("trigger_off", self, "_trigger_off")
func _trigger_on():
func _trigger_on(controller):
if Settings.s.grab_mode or _interaction.grab_mode:
begin_move()
begin_move(controller)
func _trigger_off():
func _trigger_off(_controller):
finish_move()
func begin_move():
if not _interaction.active_controller:
print("Could not begin moving overlay, no controller is touching overlay. <", _overlay.name, ">")
func begin_move(controller="right"):
if not _interaction.state[controller].near:
print("Could not begin moving overlay, " + controller + " controller is not touching overlay. <", _overlay.name, ">")
return
if is_moving:
return
@ -41,7 +41,7 @@ func begin_move():
_interaction.pause_triggers = true
# store current states to revert after move
_pre_move_target = _overlay.current_target
_mover_hand_name = _interaction.active_controller
_mover_hand_name = controller
_mover_hand_offsets = _overlay.get_offset(_mover_hand_name)
# calculate offsets from active controller to overlay

View file

@ -1,22 +1,37 @@
extends Node
signal touch_on # a controller entered
signal touch_off # a controller exited
signal trigger_on # trigger pushed while touching
signal trigger_off# trigger released
var touch_state := false
var trigger_state := false
signal near_on # a controller entered the near area (enable cursor and/or touch visualiser)
signal near_off # a controller exited
signal touch_on
signal touch_off
signal trigger_on # trigger pushed while touching
signal trigger_off # trigger released
var grab_mode := false setget set_grab_mode
# controller that currently has the trigger down
var active_controller := ""
# reference to the area node thats used for touch
var _overlay_area = preload("res://addons/openvr_overlay/interaction/OverlayArea.tscn").instance()
var _overlay_area: Spatial# = preload("res://addons/openvr_overlay/interaction/OverlayArea.tscn").instance()
var _right_is_activator := false # this hand has a collider on it to trigger things on the overlay
var _left_is_activator := false
var pause_triggers := false # disable triggers updating
var pause_triggers := false # disable triggers updating (used by grab module)
var state := {
"right": {
"active": false,
"near": false,
"touch": false,
"trigger": false,
},
"left": {
"active": false,
"near": false,
"touch": false,
"trigger": false,
},
}
onready var tracker_nodes = {
"head": $VR/head,
@ -27,9 +42,12 @@ onready var tracker_nodes = {
func _ready() -> void:
add_child(_overlay_area)
_overlay_area.connect("body_entered", self, "_on_OverlayArea_entered")
_overlay_area.connect("body_exited", self, "_on_OverlayArea_exited")
#add_child(_overlay_area)
_overlay_area = $OverlayArea
_overlay_area.get_node("AreaNear").connect("body_entered", self, "_on_Near_entered")
_overlay_area.get_node("AreaNear").connect("body_exited", self, "_on_Near_exited")
_overlay_area.get_node("AreaTouch").connect("body_entered", self, "_on_Touch_entered")
_overlay_area.get_node("AreaTouch").connect("body_exited", self, "_on_Touch_exited")
get_parent().connect("width_changed", self, "_update_width")
get_parent().connect("offset_changed", self, "_update_offset")
@ -45,37 +63,57 @@ func _ready() -> void:
func _trigger_on(controller):
if touch_state:
active_controller = controller
trigger_state = true
emit_signal("trigger_on")
if state[controller].near:
state[controller].trigger = true
emit_signal("trigger_on", controller)
func _trigger_off():
trigger_state = false
emit_signal("trigger_off")
func _trigger_off(controller):
state[controller].trigger = false
emit_signal("trigger_off", controller)
func _on_OverlayArea_entered(body: Node) -> void:
func _on_Near_entered(body: Node) -> void:
if pause_triggers or !get_parent().overlay_visible:
return
touch_state = true
active_controller = body.get_parent().name
var hand = body.get_groups()[0]
state[hand].near = true
update_selection()
emit_signal("near_on")
func _on_Near_exited(body: Node) -> void:
if pause_triggers or !get_parent().overlay_visible:
return
var hand = body.get_groups()[0]
state[hand].near = false
update_selection()
emit_signal("near_off")
func _on_Touch_entered(body: Node) -> void:
if pause_triggers or !get_parent().overlay_visible:
return
var hand = body.get_groups()[0]
state[hand].touch = true
update_selection()
emit_signal("touch_on")
func _on_OverlayArea_exited(body: Node) -> void:
func _on_Touch_exited(body: Node) -> void:
if pause_triggers or !get_parent().overlay_visible:
return
active_controller = ""
touch_state = false
var hand = body.get_groups()[0]
state[hand].touch = false
update_selection()
emit_signal("touch_off")
func update_selection():
var sel = touch_state and (Settings.s.grab_mode or grab_mode)
var sel = (Settings.s.grab_mode or grab_mode)
sel = sel and (state.right.near or state.left.near)
get_parent().get_node("OverlayViewport/Selected").visible = sel
@ -87,7 +125,7 @@ func set_grab_mode(state: bool) -> void:
func _update_width():
var ratio = OverlayInit.ovr_interface.get_render_targetsize()
var extents = get_parent().width_meters * 0.5
_overlay_area.get_child(0).shape.set_extents(Vector3(extents, extents * ratio.y/ratio.x, 0.05))
_overlay_area.get_node("AreaNear/CollisionShape").shape.set_extents(Vector3(extents, extents * ratio.y/ratio.x, 0.05))
func _update_offset():
@ -101,11 +139,11 @@ func _update_target():
_overlay_area.get_parent().remove_child(_overlay_area)
tracker_nodes[t].add_child(_overlay_area)
_left_is_activator = t != "left"
_right_is_activator = t != "right"
state.right.active = t != "right"
state.left.active = t != "left"
# make area only detect colliders of a different hand
_overlay_area.collision_mask = int(t!="right")*2 # detect right hand
_overlay_area.collision_mask += int(t!="left")*4 # detect left hand
_overlay_area.get_node("AreaNear").collision_mask = int(t!="right")*2 # detect right hand
_overlay_area.get_node("AreaNear").collision_mask += int(t!="left")*4 # detect left hand
func _update_modules():
@ -133,20 +171,20 @@ func _update_modules():
func _on_RightHand_button_pressed(button: int) -> void:
if button == JOY_VR_TRIGGER and _right_is_activator:
if button == JOY_VR_TRIGGER and state.right.active:
_trigger_on("right")
func _on_RightHand_button_release(button: int) -> void:
if button == JOY_VR_TRIGGER and active_controller == "right":
_trigger_off()
if button == JOY_VR_TRIGGER and state.right.trigger:
_trigger_off("right")
func _on_LeftHand_button_pressed(button: int) -> void:
if button == JOY_VR_TRIGGER and _left_is_activator:
if button == JOY_VR_TRIGGER and state.left.active:
_trigger_on("left")
func _on_LeftHand_button_release(button: int) -> void:
if button == JOY_VR_TRIGGER and active_controller == "left":
_trigger_off()
if button == JOY_VR_TRIGGER and state.left.trigger:
_trigger_off("left")

View file

@ -6,6 +6,7 @@ const OVERLAY_PROPERTIES_DEFAULT = {
"allow_hide": true,
# "interaction": true,
"has_cursor": false,
"has_touch": false,
"has_grab": true,
}
@ -21,7 +22,6 @@ var trackers = {
func _init() -> void:
# OS.window_minimized = true
ovr_config = preload("res://addons/godot-openvr/OpenVRConfig.gdns").new()
ovr_config.set_application_type(2) # Set to OVERLAY MODE = 2, NORMAL MODE = 1
ovr_config.set_tracking_universe(1) # Set to SEATED MODE = 0, STANDING MODE = 1, RAW MODE = 2

View file

@ -2,6 +2,7 @@ extends Control
const OVERLAY_PROPERTIES = {
"has_cursor": true,
"has_touch": true,
}
var ihandler
@ -11,8 +12,6 @@ var oinst
func _ready() -> void:
oinst = get_viewport().get_parent()
ihandler = get_viewport().get_node("../OverlayInteraction/OverlayGrab")
#if not oinst.add_cursor:
# oinst.add_cursor()
for t in oinst.TARGETS:
$OptionButton.add_item(t)
$OptionButton.selected = oinst.TARGETS.find(oinst.target)

View file

@ -44,6 +44,8 @@ singletons=[ "res://addons/godot-openvr/godot_openvr.gdnlib" ]
3d_physics/layer_2="right_hand"
3d_physics/layer_3="left_hand"
3d_physics/layer_4="right_touch"
3d_physics/layer_5="left_touch"
[physics]