Compare commits

...

28 commits
v0.3.0 ... main

Author SHA1 Message Date
b1098a13ec add overview doc, window placement 2022-05-08 21:35:41 +02:00
7edd005bb7 rename stuff 2022-05-08 21:26:30 +02:00
9f0b811d24 fix crash on grave key press, update gdvk 2022-03-17 21:16:04 +01:00
f892d4892b clean up keyboard 2022-01-23 18:07:52 +01:00
e6e003ca51 add more keys to se kb layout, add basic us layout, update gdvk, cleanup 2022-01-23 17:00:33 +01:00
d83deb8721 fix keyboard layout not exporting 2022-01-20 20:01:04 +01:00
8725763124 clean up keyboard 2022-01-20 17:57:21 +01:00
be9ceeef9c fix missing gdvk binaries 2022-01-20 10:34:45 +01:00
24ad04e262 toggle modifier keys and clear all pressed modifiers when normal key is pressed 2022-01-19 21:45:33 +01:00
899a3dce3d apply gaps when loading keyboard layout 2022-01-19 21:15:32 +01:00
710b418970 basic loading of keyboard layout, including key width 2022-01-19 20:57:30 +01:00
23b37778b1 add keyboard proof of concept 2022-01-19 19:47:23 +01:00
aaeed533da add GDVK plugin 2022-01-19 18:46:50 +01:00
ef744db9ae plugin: add touch support (finally) 2022-01-19 17:53:19 +01:00
2bac6afcdc overlays can no longer change path (this was a pretty useless feature) 2022-01-11 02:34:59 +01:00
08cb7dc283 cleanup 2021-10-16 19:37:39 +02:00
9eea2a7c28 remove hand/glove meshes, saving another MB in export size 2021-10-16 13:51:56 +02:00
97fd916a87 resize hand textures from openvr plugin, reducing exported size by 34MB 2021-10-16 13:43:26 +02:00
e1944bcc25 cleanup 2021-10-16 00:52:39 +02:00
20bf94d7ab add support for 2 cursors 2021-10-16 00:47:29 +02:00
dc6a9929b7 refactor touch and trigger handling to allow for touch controls 2021-10-12 14:51:22 +02:00
a073c19e9c cleanup 2021-10-12 01:57:11 +02:00
b673410e70 make triggers use physics layers and only have one set of trigger activators 2021-10-12 01:46:26 +02:00
f081a963a4 remove debug prints 2021-10-10 16:51:52 +02:00
43d3ce3e16 refactor interaction module handling, cleanup 2021-10-10 16:49:15 +02:00
a284c87792 Merge branch 'main' of https://github.com/CrispyPin/ovr-utils into main 2021-10-05 20:49:52 +02:00
b1eb8eb9d8 rename project folder to src 2021-10-05 20:49:40 +02:00
CrispyPin
588f361f52
Update README.md 2021-07-22 17:51:49 +02:00
188 changed files with 1554 additions and 2606 deletions

View file

@ -14,4 +14,3 @@ A cross-platform SteamVR overlay application that aims to have many useful tools
## Usage
At the moment all interacions are done with the trigger buttons, this will use steamvr actions and be configurable in the future.
To load in images with the `ImageViewer` overlay, they have to be in the user folder; that is `%Appdata%\Roaming\ovr-utils\` on windows or `~/.local/share/ovr-utils/` on linux.

35
docs/README.md Normal file
View file

@ -0,0 +1,35 @@
# WIP documentation
## Hierarchy
```
OverlayManager
- MyOverlayInstance
- [...]
- OverlayViewport
- Container
- MyOverlay
- [...]
- OverlayInteraction
- VR
- [colliders for vr trackers etc]
- Grabbable
- Clickable
- Touchable
```
## overlay interaction types
Each overlay instance has a OverlayInteraction node, which spawns the different interaction modules depending on what is defined in the OVERLAY_PROPERTIES.
The modules/interaction types are:
- Grabbable
- Touchable
- Clickable
These modules connect signals from different places to the interaction manager (`OverlayInteraction`)
Touchable connects collision signals to mouse inputs (potentially logic between to help prevent double presses)
Clickable connects vr button signals to mouse inputs
Grabbable connects vr button signals to grab logic, while telling the interaction manager to pause normal interaction

View file

@ -1,3 +0,0 @@
[gd_scene format=2]
[node name="Main" type="Node"]

View file

@ -1,5 +0,0 @@
The resources here are taken from: `Steam\steamapps\common\SteamVR\resources\rendermodels\vr_glove\`
To save space in the repository only the slim models are included while the texture maps have been taken from the full versions.
See `../scenes/ovr_left_hand.tscn` and `../scenes/ovr_right_hand.tscn` for implementation details

View file

@ -1,36 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/hands_albedo.png-149a10baba7906560a9f9eab8fadf1d8.s3tc.stex"
path.etc2="res://.import/hands_albedo.png-149a10baba7906560a9f9eab8fadf1d8.etc2.stex"
metadata={
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
source_file="res://addons/godot-openvr/meshes/hands_albedo.png"
dest_files=[ "res://.import/hands_albedo.png-149a10baba7906560a9f9eab8fadf1d8.s3tc.stex", "res://.import/hands_albedo.png-149a10baba7906560a9f9eab8fadf1d8.etc2.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 MiB

View file

@ -1,36 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/hands_normal.png-eab7a86e959f13e1294e8f67904a8873.s3tc.stex"
path.etc2="res://.import/hands_normal.png-eab7a86e959f13e1294e8f67904a8873.etc2.stex"
metadata={
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
source_file="res://addons/godot-openvr/meshes/hands_normal.png"
dest_files=[ "res://.import/hands_normal.png-eab7a86e959f13e1294e8f67904a8873.s3tc.stex", "res://.import/hands_normal.png-eab7a86e959f13e1294e8f67904a8873.etc2.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=1
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View file

@ -1,42 +0,0 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/godot-openvr/meshes/vr_glove_left_model_slim.glb" type="PackedScene" id=1]
[ext_resource path="res://addons/godot-openvr/meshes/models_hands_vr_glove_vmat.material" type="Material" id=2]
[ext_resource path="res://addons/godot-openvr/OpenVRPose.gdns" type="Script" id=3]
[ext_resource path="res://addons/godot-openvr/OpenVRSkeleton.gdns" type="Script" id=4]
[node name="ovr_left_hand" instance=ExtResource( 1 )]
script = ExtResource( 3 )
action = "/actions/godot/in/left_hand"
[node name="Skeleton" parent="RootNode" index="0"]
bones/5/bound_children = [ NodePath("Thumb") ]
bones/10/bound_children = [ NodePath("Index") ]
bones/15/bound_children = [ NodePath("Middle") ]
bones/20/bound_children = [ NodePath("Ring") ]
bones/25/bound_children = [ NodePath("Pinky") ]
script = ExtResource( 4 )
action = "/actions/godot/in/left_hand"
[node name="vr_glove_left_slim" parent="RootNode/Skeleton" index="0"]
material/0 = ExtResource( 2 )
[node name="Thumb" type="BoneAttachment" parent="RootNode/Skeleton" index="1"]
transform = Transform( -0.347509, 0.0284256, 0.937246, -0.13095, -0.991217, -0.0184906, 0.928488, -0.129158, 0.348178, -0.0498674, 0.056092, 0.112777 )
bone_name = "finger_thumb_l_end"
[node name="Index" type="BoneAttachment" parent="RootNode/Skeleton" index="2"]
transform = Transform( -0.717079, -0.669965, 0.19221, -0.076153, -0.19881, -0.977075, 0.69282, -0.715277, 0.0915429, -0.0345977, 0.0355404, 0.164767 )
bone_name = "finger_index_l_end"
[node name="Middle" type="BoneAttachment" parent="RootNode/Skeleton" index="3"]
transform = Transform( -0.755126, -0.650532, 0.0812012, -0.0513261, -0.064817, -0.996576, 0.653568, -0.756708, 0.0155557, -0.0321126, 0.00654218, 0.171613 )
bone_name = "finger_middle_l_end"
[node name="Ring" type="BoneAttachment" parent="RootNode/Skeleton" index="4"]
transform = Transform( -0.749612, -0.661178, -0.0304372, -0.0961052, 0.154228, -0.98335, 0.654864, -0.734206, -0.179154, -0.0346831, -0.0253934, 0.156924 )
bone_name = "finger_ring_l_end"
[node name="Pinky" type="BoneAttachment" parent="RootNode/Skeleton" index="5"]
transform = Transform( -0.615435, -0.749373, -0.244295, -0.0354297, 0.335934, -0.941219, 0.787391, -0.570604, -0.233296, -0.0270969, -0.0462902, 0.133467 )
bone_name = "finger_pinky_l_end"

View file

@ -1,42 +0,0 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/godot-openvr/meshes/vr_glove_right_model_slim.glb" type="PackedScene" id=1]
[ext_resource path="res://addons/godot-openvr/meshes/models_hands_vr_glove_vmat.material" type="Material" id=2]
[ext_resource path="res://addons/godot-openvr/OpenVRPose.gdns" type="Script" id=3]
[ext_resource path="res://addons/godot-openvr/OpenVRSkeleton.gdns" type="Script" id=4]
[node name="ovr_right_hand" instance=ExtResource( 1 )]
script = ExtResource( 3 )
action = "/actions/godot/in/right_hand"
[node name="Skeleton" parent="RootNode" index="0"]
bones/5/bound_children = [ NodePath("Thumb") ]
bones/10/bound_children = [ NodePath("Index") ]
bones/15/bound_children = [ NodePath("Middle") ]
bones/20/bound_children = [ NodePath("Ring") ]
bones/25/bound_children = [ NodePath("Pinky") ]
script = ExtResource( 4 )
action = "/actions/godot/in/right_hand"
[node name="vr_glove_right_slim" parent="RootNode/Skeleton" index="0"]
material/0 = ExtResource( 2 )
[node name="Thumb" type="BoneAttachment" parent="RootNode/Skeleton" index="1"]
transform = Transform( -0.347509, 0.0284256, 0.937246, 0.130949, 0.991217, 0.0184906, -0.928488, 0.129158, -0.348179, 0.0498674, 0.0560921, 0.112777 )
bone_name = "finger_thumb_r_end"
[node name="Index" type="BoneAttachment" parent="RootNode/Skeleton" index="2"]
transform = Transform( -0.717079, -0.669965, 0.19221, 0.0761528, 0.19881, 0.977075, -0.69282, 0.715277, -0.0915429, 0.0345977, 0.0355405, 0.164767 )
bone_name = "finger_index_r_end"
[node name="Middle" type="BoneAttachment" parent="RootNode/Skeleton" index="3"]
transform = Transform( -0.755126, -0.650532, 0.0812013, 0.0513261, 0.064817, 0.996577, -0.653568, 0.756708, -0.0155557, 0.0321126, 0.00654219, 0.171613 )
bone_name = "finger_middle_r_end"
[node name="Ring" type="BoneAttachment" parent="RootNode/Skeleton" index="4"]
transform = Transform( -0.749612, -0.661178, -0.0304372, 0.0961052, -0.154228, 0.98335, -0.654864, 0.734206, 0.179154, 0.0346831, -0.0253934, 0.156924 )
bone_name = "finger_ring_r_end"
[node name="Pinky" type="BoneAttachment" parent="RootNode/Skeleton" index="5"]
transform = Transform( -0.615435, -0.749373, -0.244295, 0.0354297, -0.335934, 0.941219, -0.787391, 0.570604, 0.233296, 0.0270969, -0.0462902, 0.133467 )
bone_name = "finger_pinky_r_end"

View file

@ -1,6 +0,0 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/overlay_cursor.gd" type="Script" id=1]
[node name="OverlayCursor" type="Node"]
script = ExtResource( 1 )

View file

@ -1,6 +0,0 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/overlay_grab.gd" type="Script" id=1]
[node name="OverlayGrab" type="Node"]
script = ExtResource( 1 )

View file

@ -1,10 +0,0 @@
[gd_scene load_steps=2 format=2]
[sub_resource type="BoxShape" id=1]
resource_local_to_scene = true
extents = Vector3( 0.2, 0.2, 0.01 )
[node name="OverlayArea" type="Area"]
[node name="CollisionShape" type="CollisionShape" parent="."]
shape = SubResource( 1 )

View file

@ -1,70 +0,0 @@
extends Node
var cursor_node = preload("res://addons/openvr_overlay/interaction/Cursor.tscn").instance()
onready var viewport: Viewport = get_node("../../OverlayViewport")
onready var _i = get_parent()
var curr_pos: Vector2
var prev_pos := Vector2(-1000, 1000)
func _ready() -> void:
viewport.add_child(cursor_node)
get_parent().connect("trigger_on", self, "_trigger_on")
get_parent().connect("trigger_off", self, "_trigger_off")
func _process(_delta: float) -> void:
curr_pos = get_canvas_pos()
_update_cursor()
_send_move_event()
prev_pos = curr_pos
#get canvas position of active controller
func get_canvas_pos() -> Vector2:
if not _i.active_controller:
return Vector2(-1000, 1000) # offscreen
var controller_local_pos = _i._overlay_area.global_transform.xform_inv(\
_i.tracker_nodes[_i.active_controller].translation)
var pos = Vector2(controller_local_pos.x, controller_local_pos.y)
var overlay_size = Vector2(2048, 2048)
# scale to pixels
pos *= overlay_size.x
pos /= _i.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_move_event():
var event = InputEventMouseMotion.new()
event.position = prev_pos
event.relative = curr_pos - prev_pos
event.speed = event.relative
viewport.input(event)
func _send_click_event(state: bool):
var click_event = InputEventMouseButton.new()
click_event.position = curr_pos
click_event.pressed = state
click_event.button_index = 1
viewport.input(click_event)
func _trigger_on():
_send_click_event(true)
func _trigger_off():
_send_click_event(false)

View file

@ -1,126 +0,0 @@
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
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 _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
onready var tracker_nodes = {
"head": $VR/head,
"left": $VR/left,
"right": $VR/right,
"world": $VR
}
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")
get_parent().connect("width_changed", self, "_update_width")
get_parent().connect("offset_changed", self, "_update_offset")
get_parent().connect("target_changed", self, "_update_target")
OverlayManager.connect("grab_mode_changed", self, "update_selection")
_update_width()
_update_offset()
_update_target()
func _trigger_on(controller):
if touch_state:
active_controller = controller
trigger_state = true
emit_signal("trigger_on")
func _trigger_off():
trigger_state = false
emit_signal("trigger_off")
func _on_OverlayArea_entered(body: Node) -> void:
if body.get_node("../../..") != self or pause_triggers or !get_parent().overlay_visible:
return
touch_state = true
active_controller = body.get_parent().name
update_selection()
emit_signal("touch_on")
func _on_OverlayArea_exited(body: Node) -> void:
if body.get_node("../../..") != self or pause_triggers or !get_parent().overlay_visible:
return
# TODO revert to other controller if both were touching (edge case)
active_controller = ""
touch_state = false
update_selection()
emit_signal("touch_off")
func update_selection():
var sel = touch_state and (Settings.s.grab_mode or grab_mode)
get_parent().get_node("OverlayViewport/Selected").visible = sel
func set_grab_mode(state: bool) -> void:
grab_mode = state
update_selection()
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))
func _update_offset():
_overlay_area.translation = get_parent().translation
_overlay_area.rotation = get_parent().rotation
func _update_target():
# reparent _overlay_area
_overlay_area.get_parent().remove_child(_overlay_area)
tracker_nodes[get_parent().current_target].add_child(_overlay_area)
_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("right")
func _on_RightHand_button_release(button: int) -> void:
if button == JOY_VR_TRIGGER and active_controller == "right":
_trigger_off()
func _on_LeftHand_button_pressed(button: int) -> void:
if button == JOY_VR_TRIGGER and _left_is_activator:
_trigger_on("left")
func _on_LeftHand_button_release(button: int) -> void:
if button == JOY_VR_TRIGGER and active_controller == "left":
_trigger_off()

6
src/Main.tscn Normal file
View file

@ -0,0 +1,6 @@
[gd_scene format=2]
[node name="Main" type="Node"]
__meta__ = {
"_editor_description_": "Everything is loaded using autoloads so this scene is just a dummy"
}

View file

@ -8,6 +8,5 @@
script = ExtResource( 4 )
[node name="MainOverlay" parent="." instance=ExtResource( 2 )]
add_cursor = true
[node name="OverlaySettingsSync" parent="MainOverlay" instance=ExtResource( 3 )]

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/gdvk/gdvk.gdns" type="Script" id=1]
[node name="GDVK" type="Node"]
script = ExtResource( 1 )

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 MiB

After

Width:  |  Height:  |  Size: 19 MiB

Binary file not shown.

View file

@ -0,0 +1,17 @@
[general]
singleton=false
load_once=true
symbol_prefix="gdvk_"
reloadable=true
[entry]
X11.64="res://addons/gdvk/bin/x11/libgdvk.so"
Windows.64="res://addons/gdvk/bin/win64/libgdvk.dll"
[dependencies]
X11.64=[ ]
Windows.64=[ ]
OSX.64=[ ]

View file

@ -0,0 +1,8 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://addons/gdvk/gdvk.gdnlib" type="GDNativeLibrary" id=1]
[resource]
resource_name = "gdvk"
class_name = "GDVK"
library = ExtResource( 1 )

View file

@ -0,0 +1,10 @@
tool
extends EditorPlugin
func _enter_tree() -> void:
add_autoload_singleton("GDVK", "res://addons/gdvk/GDVK.tscn")
func _exit_tree() -> void:
remove_autoload_singleton("GDVK")

View file

@ -0,0 +1,9 @@
[plugin]
name="GDVK"
description="Godot virtual keyboard plugin
see https://github.com/CrispyPin/gdvk"
author="CrispyPin"
version="0.1.0"
script="gdvk_plugin.gd"

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -1,6 +1,7 @@
[gd_scene load_steps=5 format=2]
[gd_scene load_steps=6 format=2]
[ext_resource path="res://addons/openvr_overlay/overlay_instance.gd" type="Script" id=1]
[ext_resource path="res://addons/openvr_overlay/OverlayInteraction.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/godot-openvr/OpenVROverlay.gdns" type="Script" id=3]
[sub_resource type="StyleBoxFlat" id=1]
@ -21,7 +22,6 @@ script = ExtResource( 1 )
[node name="OverlayViewport" type="Viewport" parent="."]
size = Vector2( 2048, 2048 )
transparent_bg = true
handle_input_locally = false
hdr = false
disable_3d = true
usage = 0
@ -64,3 +64,5 @@ texture = SubResource( 2 )
expand = true
stretch_mode = 5
flip_v = true
[node name="OverlayInteraction" parent="." instance=ExtResource( 2 )]

View file

@ -1,7 +1,7 @@
[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/OverlayActivator.tscn" type="PackedScene" id=6]
[ext_resource path="res://addons/openvr_overlay/interaction/OverlayArea.tscn" type="PackedScene" id=2]
[node name="OverlayInteraction" type="Node"]
script = ExtResource( 1 )
@ -10,16 +10,14 @@ script = ExtResource( 1 )
[node name="left" type="ARVRController" parent="VR"]
[node name="OverlayActivator" parent="VR/left" instance=ExtResource( 6 )]
[node name="right" type="ARVRController" parent="VR"]
controller_id = 2
[node name="OverlayActivator" parent="VR/right" instance=ExtResource( 6 )]
[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

@ -0,0 +1,25 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/HandCollider.tscn" type="PackedScene" id=1]
[node name="OverlayInteractionRoot" type="Node"]
[node name="VR" type="ARVROrigin" parent="."]
[node name="left" type="ARVRController" parent="VR"]
[node name="HandCollider" parent="VR/left" groups=[
"left",
] instance=ExtResource( 1 )]
collision_layer = 20
[node name="right" type="ARVRController" parent="VR"]
controller_id = 2
[node name="HandCollider" parent="VR/right" groups=[
"right",
] instance=ExtResource( 1 )]
collision_layer = 10
[node name="head" type="ARVRCamera" parent="VR"]
visible = false

View file

@ -4,7 +4,10 @@
margin = 0.001
radius = 0.01
[node name="OverlayActivator" type="StaticBody"]
[node name="HandCollider" type="Area"]
monitoring = false
collision_layer = 30
collision_mask = 0
[node name="Collision" type="CollisionShape" parent="."]
shape = SubResource( 1 )

View file

@ -0,0 +1,27 @@
[gd_scene load_steps=3 format=2]
[sub_resource type="BoxShape" id=1]
resource_local_to_scene = true
extents = Vector3( 0.2, 0.2, 0.1 )
[sub_resource type="BoxShape" id=2]
resource_local_to_scene = true
extents = Vector3( 0.2, 0.2, 0.01 )
[node name="OverlayArea" type="Spatial"]
[node name="AreaNear" type="Area" parent="."]
monitorable = false
collision_layer = 0
collision_mask = 6
[node name="CollisionShape" type="CollisionShape" parent="AreaNear"]
shape = SubResource( 1 )
[node name="AreaTouch" type="Area" parent="."]
monitorable = false
collision_layer = 0
collision_mask = 24
[node name="CollisionShape" type="CollisionShape" parent="AreaTouch"]
shape = SubResource( 2 )

View file

Before

Width:  |  Height:  |  Size: 90 B

After

Width:  |  Height:  |  Size: 90 B

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/mod/clickable.gd" type="Script" id=1]
[node name="Clickable" type="Node"]
script = ExtResource( 1 )

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/mod/grabbable.gd" type="Script" id=1]
[node name="Grabbable" type="Node"]
script = ExtResource( 1 )

View file

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/openvr_overlay/interaction/mod/clickable.gd" type="Script" id=1]
[node name="Touchable" type="Node"]
script = ExtResource( 1 )
is_touch = true

View file

@ -0,0 +1,109 @@
extends Node
export var is_touch := false
onready var viewport: Viewport = get_node("../../OverlayViewport")
onready var _i = get_parent()
var cursor_pos := {
"right": Vector2(),
"left": Vector2(),
}
var prev_pos := {
"right": Vector2(),
"left": Vector2(),
}
var click := {
"right": false,
"left": false,
}
var active_side := ""
var cursor_nodes := {
"right": preload("res://addons/openvr_overlay/interaction/Cursor.tscn").instance(),
"left": preload("res://addons/openvr_overlay/interaction/Cursor.tscn").instance(),
}
func _ready() -> void:
viewport.add_child(cursor_nodes.right)
viewport.add_child(cursor_nodes.left)
if is_touch:
get_parent().connect("touch_on", self, "_trigger_on")
get_parent().connect("touch_off", self, "_trigger_off")
else:
get_parent().connect("trigger_on", self, "_trigger_on")
get_parent().connect("trigger_off", self, "_trigger_off")
func _process(delta: float) -> void:
cursor_pos.right = get_canvas_pos("right")
cursor_pos.left = get_canvas_pos("left")
_update_cursors()
# _send_move_event()
prev_pos = cursor_pos.duplicate(true)
# get canvas position of controller
func get_canvas_pos(controller) -> Vector2:
var controller_local_pos = _i._overlay_area.global_transform.xform_inv(\
_i.tracker_nodes[controller].translation)
var pos = Vector2(controller_local_pos.x, controller_local_pos.y)
var overlay_size = Vector2(2048, 2048)
# scale to pixels
pos *= overlay_size.x
pos /= _i.get_parent().width_meters
# adjust to center
pos.y *= -1
pos += overlay_size * 0.5
return pos
func _update_cursors():
cursor_nodes.right.visible = _i.state.right.near
cursor_nodes.left.visible = _i.state.left.near
cursor_nodes.right.rect_position = cursor_pos.right
cursor_nodes.left.rect_position = cursor_pos.left
func _send_move_event():
if not active_side:
return# only send move events while a cursor is held down
var event = InputEventMouseMotion.new()
event.position = prev_pos[active_side]
event.relative = cursor_pos[active_side] - prev_pos[active_side]
event.speed = event.relative
viewport.input(event)
func _send_click_event(state: bool, controller: String):
if click[controller] == state:
return # already in that state
click[controller] = state
_update_active_side()
var click_event = InputEventMouseButton.new()
click_event.position = cursor_pos[controller]
click_event.pressed = state
click_event.button_index = 1
viewport.input(click_event)
# print("SENT EVENT ", click_event.position, " -- ", click_event.pressed)
func _trigger_on(controller):
if click.right or click.left:
return
_send_click_event(true, controller)
func _trigger_off(controller):
_send_click_event(false, controller)
func _update_active_side() -> void:
if click.right:
active_side = "right"
elif click.left:
active_side = "left"
else:
active_side = ""

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

@ -0,0 +1,188 @@
extends Node
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
# reference to the area node thats used for touch
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 (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,
"left": $VR/left,
"right": $VR/right,
"world": $VR
}
func _ready() -> void:
_overlay_area = $OverlayArea
_overlay_area.get_node("AreaNear"). connect("area_entered", self, "_on_Near_entered")
_overlay_area.get_node("AreaNear"). connect("area_exited", self, "_on_Near_exited")
_overlay_area.get_node("AreaTouch").connect("area_entered", self, "_on_Touch_entered")
_overlay_area.get_node("AreaTouch").connect("area_exited", self, "_on_Touch_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")
OverlayManager.connect("grab_mode_changed", self, "update_selection")
call_deferred("_update_width")
call_deferred("_update_offset")
call_deferred("_update_target")
func _trigger_on(controller):
if state[controller].near:
state[controller].trigger = true
# print("TRIGGER ON ", controller)
emit_signal("trigger_on", controller)
func _trigger_off(controller):
state[controller].trigger = false
# print("TRIGGER OFF ", controller)
emit_signal("trigger_off", controller)
func _on_Near_entered(body: Node) -> void:
if pause_triggers or !get_parent().overlay_visible:
return
var hand = body.get_groups()[0]
state[hand].near = true
update_selection()
# print("NEAR ON ", hand)
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
# print("NEAR OFF ", hand)
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()
# print("TOUCH ON ", hand)
emit_signal("touch_on", hand)
func _on_Touch_exited(body: Node) -> void:
if pause_triggers or !get_parent().overlay_visible:
return
var hand = body.get_groups()[0]
state[hand].touch = false
update_selection()
# print("TOUCH OFF ", hand)
emit_signal("touch_off", hand)
func update_selection():
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
func set_grab_mode(state: bool) -> void:
grab_mode = state
update_selection()
func _update_width():
var ratio = OverlayInit.ovr_interface.get_render_targetsize()
var extents = get_parent().width_meters * 0.5
_overlay_area.get_node("AreaNear/CollisionShape").shape.set_extents(
Vector3(extents, extents * ratio.y/ratio.x, 0.1))
_overlay_area.get_node("AreaTouch/CollisionShape").shape.set_extents(
Vector3(extents, extents * ratio.y/ratio.x, 0.01))
func _update_offset():
_overlay_area.translation = get_parent().translation
_overlay_area.rotation = get_parent().rotation
func _update_target():
var t = get_parent().current_target
# reparent _overlay_area
_overlay_area.get_parent().remove_child(_overlay_area)
tracker_nodes[t].add_child(_overlay_area)
state.right.active = t != "right"
state.left.active = t != "left"
# make area only detect colliders of a different 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
_overlay_area.get_node("AreaNear").collision_mask = int(t!="right")*8 # detect right hand
_overlay_area.get_node("AreaNear").collision_mask += int(t!="left")*16 # detect left hand
# called by overlay_instance after properties are loaded and before overlay scene enters the tree
func spawn_modules():
if get_parent().get_property("grabbable"):
var module = preload("res://addons/openvr_overlay/interaction/mod/Grabbable.tscn")
add_child(module.instance())
if get_parent().get_property("clickable"):
var module = preload("res://addons/openvr_overlay/interaction/mod/Clickable.tscn")
add_child(module.instance())
if get_parent().get_property("touchable"):
var module = preload("res://addons/openvr_overlay/interaction/mod/Touchable.tscn")
add_child(module.instance())
func _on_RightHand_button_pressed(button: int) -> void:
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 state.right.trigger:
_trigger_off("right")
func _on_LeftHand_button_pressed(button: int) -> void:
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 state.left.trigger:
_trigger_off("left")

View file

@ -4,7 +4,9 @@ extends EditorPlugin
func _enter_tree() -> void:
add_autoload_singleton("OverlayInit", "res://addons/openvr_overlay/overlay_init.gd")
add_autoload_singleton("OverlayInteractionRoot", "res://addons/openvr_overlay/OverlayInteractionRoot.tscn")
func _exit_tree() -> void:
remove_autoload_singleton("OverlayInit")
remove_autoload_singleton("OverlayInteractionRoot")

View file

@ -1,5 +1,14 @@
extends Node
const OVERLAY_PROPERTIES_DEFAULT = {
"allow_delete": true,
"allow_hide": true,
"clickable": false,
"touchable": false,
"grabbable": true,
}
var ovr_interface: ARVRInterface
var ovr_config := preload("res://addons/godot-openvr/OpenVRConfig.gdns").new()
@ -11,9 +20,7 @@ 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_application_type(2) # Set to OVERLAY MODE
ovr_config.set_tracking_universe(1) # Set to SEATED MODE = 0, STANDING MODE = 1, RAW MODE = 2
# Find the OpenVR interface and initialise it
@ -23,9 +30,14 @@ func _init() -> void:
func _ready() -> void:
OS.window_size = Vector2(16, 16)
OS.window_position = Vector2(32, 32)
OS.window_minimized = true
ARVRServer.connect("tracker_added", self, "_tracker_added")
ARVRServer.connect("tracker_removed", self, "_tracker_removed")
update_hand_ids()
#Input.set_use_accumulated_input(true)
func _tracker_added(tracker_name: String, type: int, id: int):

View file

@ -1,6 +1,6 @@
extends Spatial
signal path_changed
#signal path_changed
signal overlay_visible_changed
signal width_changed
signal alpha_changed
@ -12,9 +12,8 @@ const TARGETS = ["head", "left", "right", "world"]
export (String, "head", "left", "right", "world") var target = "left" setget set_target
export var width_meters := 0.4 setget set_width_in_meters
export var alpha := 1.0 setget set_alpha
export var add_grabbing := true # add grabbing module
export var add_cursor := false # add cursor module
export var alpha := 1.0 setget set_alpha
var _tracker_id := 0
var _offsets:Dictionary = {
@ -29,15 +28,17 @@ var current_target: String = "world" setget _set_current_target
var fallback = ["left", "right", "head"] # TODO setget that updates tracking (not important)
var interaction_handler: Node
var overlay_visible := true setget set_overlay_visible
var path := "res://special_overlays/MainOverlay.tscn" setget set_path
var path : String = "res://special_overlays/MainOverlay.tscn"# setget set_path
var path_invalid := false
var OVERLAY_PROPERTIES: Dictionary
var OVERLAY_PROPERTIES: Dictionary # defined in overlay root script (optional)
onready var container = $OverlayViewport/Container
var overlay_scene: Node
func _ready() -> void:
container = $OverlayViewport/Container
load_overlay()
current_target = target
ARVRServer.connect("tracker_added", self, "_tracker_changed")
@ -46,25 +47,27 @@ func _ready() -> void:
$VROverlayViewport.size = OverlayInit.ovr_interface.get_render_targetsize()
set_notify_transform(true)
if add_cursor or add_grabbing:
interaction_handler = load("res://addons/openvr_overlay/OverlayInteraction.tscn").instance()
add_child(interaction_handler)
if add_cursor:
add_cursor()
if add_grabbing:
add_grab()
update_tracker_id()
call_deferred("update_offset")
func load_overlay() -> void:
path_invalid = false
func add_cursor():
interaction_handler.add_child(load("res://addons/openvr_overlay/OverlayCursor.tscn").instance())
var packed_overlay = load(path)
if not packed_overlay:
path_invalid = true
overlay_scene = load("res://special_overlays/UnknownType.tscn").instance()
else:
overlay_scene = packed_overlay.instance()
if overlay_scene.get("OVERLAY_PROPERTIES") != null:
OVERLAY_PROPERTIES = overlay_scene.OVERLAY_PROPERTIES
func add_grab():
interaction_handler.add_child(load("res://addons/openvr_overlay/OverlayGrab.tscn").instance())
$OverlayInteraction.spawn_modules()
if container.get_child_count() > 0:
container.get_child(0).queue_free()
container.add_child(overlay_scene)
func update_tracker_id():
_tracker_id = -1
@ -78,7 +81,7 @@ func update_tracker_id():
if _tracker_id == -1:
# could not find controller, fallback
print("Missing controller ", current_target, " ", target, " ", fallback, " - ", name)
# print("Missing controller ", current_target, " ", target, " ", fallback, " - ", name)
_tracker_id = 63 # highest tracker id (unused, at origin)
@ -146,27 +149,6 @@ func set_width_in_meters(width: float) -> void:
emit_signal("width_changed")
func set_path(new: String) -> void:
path = new
path_invalid = false
var packed_overlay = load(path)
if not packed_overlay:
path_invalid = true
overlay_scene = load("res://special_overlays/UnknownType.tscn").instance()
else:
overlay_scene = packed_overlay.instance()
if container.get_child_count() > 0:
container.get_child(0).queue_free()
container.add_child(overlay_scene)
if overlay_scene.get("OVERLAY_PROPERTIES") != null:
OVERLAY_PROPERTIES = overlay_scene.OVERLAY_PROPERTIES
emit_signal("path_changed")
func set_alpha(val: float):
alpha = val
$VROverlayViewport/TextureRect.modulate.a = val
@ -184,3 +166,10 @@ func reset_offset() -> void:
func _notification(what: int) -> void:
if what == NOTIFICATION_TRANSFORM_CHANGED:
emit_signal("offset_changed")
func get_property(p_name: String):
if OVERLAY_PROPERTIES.has(p_name):
return OVERLAY_PROPERTIES[p_name]
return OverlayInit.OVERLAY_PROPERTIES_DEFAULT[p_name]

View file

@ -5,7 +5,7 @@ platform="Linux/X11"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
include_filter="*.json"
exclude_filter=""
export_path="../builds/linux/ovr-utils.x86_64"
script_export_mode=1

Some files were not shown because too many files have changed in this diff Show more