mirror of
https://github.com/CrispyPin/ovr-utils.git
synced 2025-04-11 23:18:30 +02:00
214 lines
6.3 KiB
GDScript
214 lines
6.3 KiB
GDScript
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 setget ,get_touch_state
|
|
var _trigger_state = false setget ,get_trigger_state
|
|
|
|
# controller that currently the trigger down
|
|
var _active_controller: ARVRController setget ,get_active_controller
|
|
# reference to the area node thats used for touch
|
|
var _overlay_area = preload("res://addons/openvr_overlay/interaction/OverlayArea.tscn").instance()
|
|
var _cursor_node = preload("res://addons/openvr_overlay/interaction/Cursor.tscn").instance()
|
|
var _right_is_activator = false
|
|
var _left_is_activator = false
|
|
|
|
var is_moving := false
|
|
var _pre_move_target = ""# what offset is being changed
|
|
var _mover_hand_name = ""# left or right, which hand is grabbing (/active controller)
|
|
var _mover_hand_offsets = {"pos": Vector3(), "rot": Vector3()} # original offsets for grabbing hand
|
|
|
|
onready var viewport: Viewport = get_node("../OverlayViewport")
|
|
onready var tracker_nodes = {
|
|
"head": $VR/head,
|
|
"left": $VR/left,
|
|
"right": $VR/right,
|
|
"world": $VR
|
|
}
|
|
|
|
|
|
func _ready() -> void:
|
|
add_child(_overlay_area)
|
|
get_node("../OverlayViewport").add_child(_cursor_node)
|
|
_overlay_area.connect("body_entered", self, "_on_OverlayArea_entered")
|
|
_overlay_area.connect("body_exited", self, "_on_OverlayArea_exited")
|
|
|
|
get_parent().connect("width_changed", self, "_update_width")
|
|
get_parent().connect("offset_changed", self, "_update_offset")
|
|
get_parent().connect("target_changed", self, "_update_target")
|
|
|
|
_update_width()
|
|
_update_offset()
|
|
_update_target()
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
_update_cursor()
|
|
|
|
|
|
func begin_move():
|
|
if not _active_controller:
|
|
print("Could not begin moving overlay, no controller active. ", get_parent().name)
|
|
return
|
|
is_moving = true
|
|
_pre_move_target = get_parent().current_target
|
|
_mover_hand_name = _active_controller.name
|
|
_mover_hand_offsets.pos = get_parent().translation
|
|
_mover_hand_offsets.rot = get_parent().rotation
|
|
|
|
# offset from active controller to overlay
|
|
var global_rot = _overlay_area.global_transform.basis.get_rotation_quat()
|
|
var hand_rot = _active_controller.transform.basis.get_rotation_quat()
|
|
get_parent().offsets[_mover_hand_name].rot = hand_rot.inverse() * global_rot
|
|
|
|
get_parent().offsets[_mover_hand_name].pos = _active_controller.transform.xform_inv(_overlay_area.global_transform.origin)
|
|
|
|
get_parent().current_target = _mover_hand_name
|
|
|
|
|
|
func finish_move():
|
|
is_moving = false
|
|
var new_pos = tracker_nodes[_pre_move_target].transform.xform_inv(_overlay_area.global_transform.origin)
|
|
|
|
var new_rot = tracker_nodes[_pre_move_target].transform.basis.get_rotation_quat().inverse() * _overlay_area.global_transform.basis.get_rotation_quat()
|
|
|
|
get_parent().update_current_target()
|
|
get_parent().update_tracker_id()
|
|
get_parent().offsets[get_parent().current_target].pos = new_pos
|
|
get_parent().offsets[get_parent().current_target].rot = new_rot
|
|
get_parent().update_offset()
|
|
_update_target()
|
|
|
|
|
|
#get canvas position of active controller
|
|
func get_canvas_pos() -> Vector2:
|
|
if _active_controller == null:
|
|
return Vector2(-1000, 1000) # offscreen
|
|
|
|
var controller_local_pos = _overlay_area.global_transform.xform_inv(\
|
|
_active_controller.global_transform.origin)
|
|
var pos = Vector2(controller_local_pos.x, controller_local_pos.y)
|
|
|
|
var overlay_size = OverlayInit.ovr_interface.get_render_targetsize()
|
|
# scale to pixels
|
|
pos *= overlay_size.x
|
|
pos /= get_parent().width_meters
|
|
# adjust to center
|
|
pos.y *= -1
|
|
pos += overlay_size * 0.5
|
|
return pos
|
|
|
|
|
|
func _update_cursor():
|
|
_cursor_node.rect_position = get_canvas_pos()
|
|
|
|
|
|
func _send_click_event(state: bool):
|
|
var click_event = InputEventMouseButton.new()
|
|
click_event.position = get_canvas_pos()
|
|
click_event.pressed = state
|
|
click_event.button_index = 1
|
|
viewport.input(click_event)
|
|
|
|
|
|
func _trigger_on(controller):
|
|
if _touch_state:
|
|
_active_controller = controller
|
|
_trigger_state = true
|
|
_send_click_event(true)
|
|
emit_signal("trigger_on")
|
|
|
|
|
|
func _trigger_off():
|
|
_trigger_state = false
|
|
_send_click_event(false)
|
|
emit_signal("trigger_off")
|
|
|
|
|
|
func _on_OverlayArea_entered(body: Node) -> void:
|
|
if body.get_node("../../..") != self or is_moving:
|
|
return
|
|
_touch_state = true
|
|
if not is_moving:
|
|
_active_controller = body.get_parent()
|
|
emit_signal("touch_on")
|
|
|
|
|
|
func _on_OverlayArea_exited(body: Node) -> void:
|
|
if body.get_node("../../..") != self or is_moving:
|
|
return
|
|
# TEMP
|
|
_active_controller = null # TODO revert to other controller if both were touching (edge case)
|
|
_touch_state = false
|
|
emit_signal("touch_off")
|
|
|
|
|
|
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.1))
|
|
|
|
|
|
func _update_offset():
|
|
_overlay_area.translation = get_parent().translation
|
|
_overlay_area.rotation = get_parent().rotation
|
|
|
|
|
|
func _update_target():
|
|
# move _overlay_area
|
|
_overlay_area.get_parent().remove_child(_overlay_area)
|
|
tracker_nodes[get_parent().current_target].add_child(_overlay_area)
|
|
# match get_parent().target:
|
|
# "head":
|
|
# $VR/Head.add_child(_overlay_area)
|
|
# "left":
|
|
# $VR/LeftHand.add_child(_overlay_area)
|
|
# "right":
|
|
# $VR/RightHand.add_child(_overlay_area)
|
|
# "world":
|
|
# $VR.add_child(_overlay_area)
|
|
|
|
# if is_moving:
|
|
# return
|
|
|
|
_left_is_activator = get_parent().current_target != "left"
|
|
_right_is_activator = get_parent().current_target != "right"
|
|
# toggle appropriate colliders
|
|
$VR/left/OverlayActivator/Collision.disabled = !_left_is_activator
|
|
$VR/right/OverlayActivator/Collision.disabled = !_right_is_activator
|
|
|
|
|
|
func _on_RightHand_button_pressed(button: int) -> void:
|
|
if button == JOY_VR_TRIGGER and _right_is_activator:
|
|
_trigger_on(tracker_nodes.right)
|
|
|
|
|
|
func _on_RightHand_button_release(button: int) -> void:
|
|
if button == JOY_VR_TRIGGER and _active_controller == tracker_nodes.right:
|
|
_trigger_off()
|
|
|
|
|
|
func _on_LeftHand_button_pressed(button: int) -> void:
|
|
if button == JOY_VR_TRIGGER and _left_is_activator:
|
|
_trigger_on(tracker_nodes.left)
|
|
|
|
|
|
func _on_LeftHand_button_release(button: int) -> void:
|
|
if button == JOY_VR_TRIGGER and _active_controller == tracker_nodes.right:
|
|
_trigger_off()
|
|
|
|
|
|
func get_touch_state():
|
|
return _touch_state
|
|
|
|
|
|
func get_trigger_state():
|
|
return _trigger_state
|
|
|
|
|
|
func get_active_controller():
|
|
return _active_controller
|
|
|