From bc924100477e4c30894de30b70c55d39d9d4a0b5 Mon Sep 17 00:00:00 2001 From: Parick Down Date: Sun, 26 Nov 2023 16:40:16 -0500 Subject: [PATCH] Update gdscript plugin XRRig to be in line to csharp changes Added to T5XRRig: var glasses_id : StringName var gameboard_type := T5Def.GameboardType.Unknown var gameboard_size := AABB() var origin : T5Origin3D var camera : T5Camera3D var wand : T5Controller3D Updated T5 interface to use these Added T5Def to hold gameboard type and wand control names --- example.gd/addons/tiltfive/T5Def.gd | 21 ++++ example.gd/addons/tiltfive/T5Interface.gd | 103 +++++++----------- example.gd/addons/tiltfive/T5Manager.gd | 48 ++++---- example.gd/addons/tiltfive/T5ManagerBase.gd | 36 +----- .../addons/tiltfive/assets/auto_scale.gd | 7 +- example.gd/addons/tiltfive/scenes/T5XRRig.gd | 31 ++++-- example.gd/main.tscn | 2 +- example.gd/scenes/pointer_control.gd | 95 +++++----------- 8 files changed, 143 insertions(+), 200 deletions(-) create mode 100644 example.gd/addons/tiltfive/T5Def.gd diff --git a/example.gd/addons/tiltfive/T5Def.gd b/example.gd/addons/tiltfive/T5Def.gd new file mode 100644 index 0000000..6704aad --- /dev/null +++ b/example.gd/addons/tiltfive/T5Def.gd @@ -0,0 +1,21 @@ +class_name T5Def extends Object + +enum GameboardType { + LE = TiltFiveXRInterface.LE_GAMEBOARD, + XE = TiltFiveXRInterface.XE_GAMEBOARD, + XE_Raised = TiltFiveXRInterface.XE_RAISED_GAMEBOARD, + Unknown = TiltFiveXRInterface.NO_GAMEBOARD_SET +} + +const WAND_BUTTON_A := &"button_a" +const WAND_BUTTON_B := &"button_b" +const WAND_BUTTON_X := &"button_x" +const WAND_BUTTON_Y := &"button_y" +const WAND_BUTTON_1 := &"button_1" +const WAND_BUTTON_2 := &"button_2" +const WAND_BUTTON_STICK := &"button_3" +const WAND_BUTTON_T5 := &"button_t5" +const WAND_BUTTON_TRIGGER := &"trigger_click" + # Axis +const WAND_ANALOG_STICK := &"stick" +const WAND_ANALOG_TRIGGER := &"trigger" diff --git a/example.gd/addons/tiltfive/T5Interface.gd b/example.gd/addons/tiltfive/T5Interface.gd index c7ee77c..45bc777 100644 --- a/example.gd/addons/tiltfive/T5Interface.gd +++ b/example.gd/addons/tiltfive/T5Interface.gd @@ -1,37 +1,22 @@ extends Node - -## This script should be configured as an autoload script. -## It will instantiate the TileFive interface and register -## it with the XRServer. -## -## It also registers various project settings the user can -## setup. +## It will instantiate the TileFive interface and register it with the XRServer. ## -## Note that the TiltFive interface is also registed when -## in editor. This will allow the Godot editor to request -## action information from the interface. +## This script should be configured be automatically added as an autoload script +## when the plugin is enabled. This const T5ManagerBase = preload("res://addons/tiltfive/T5ManagerBase.gd") -enum GameboardType { - LE = TiltFiveXRInterface.LE_GAMEBOARD, - XE = TiltFiveXRInterface.XE_GAMEBOARD, - XE_Raised = TiltFiveXRInterface.XE_RAISED_GAMEBOARD, - Unknown = TiltFiveXRInterface.NO_GAMEBOARD_SET -} - # State of a set of glasses. -class GlassesState: +class XRRigState: var available := false var attempting_to_reserve := false var reserved := false - var glasses_scene : Node - var gameboard_type := GameboardType.Unknown + var xr_rig : T5XRRig func can_attempt_to_reserve(): return available and (not attempting_to_reserve) and (not reserved) -# Dictionary maps glasses_id -> GlassesState -var glasses_dict: Dictionary +# Dictionary maps glasses_id -> XRRigState +var id_to_state: Dictionary var tilt_five_xr_interface: TiltFiveXRInterface @@ -48,7 +33,6 @@ func get_setting_or_default(name : String, default): val = default return val -# Called when the manager is loaded and added to our scene func _enter_tree(): tilt_five_xr_interface = TiltFiveXRInterface.new(); if tilt_five_xr_interface: @@ -77,23 +61,16 @@ func _ready(): if !tilt_five_xr_interface.is_initialized(): tilt_five_xr_interface.initialize() -func _start_display(glasses_id : StringName, glasses_scene : Node): - var viewport := t5_manager.get_glasses_scene_viewport(glasses_scene) - var xr_origin := t5_manager.get_glasses_scene_origin(glasses_scene) - tilt_five_xr_interface.start_display(glasses_id, viewport, xr_origin) - var t5_camera := t5_manager.get_glasses_scene_camera(glasses_scene) - if t5_camera: - t5_camera.tracker = "/user/%s/head" % glasses_id - for idx in range(4): - var controller = t5_manager.get_glasses_scene_wand(glasses_scene, idx) - if not controller: break - controller.tracker = "/user/%s/wand_%d" % [glasses_id, idx + 1] +func _start_display(glasses_id : StringName, xr_rig : T5XRRig): + tilt_five_xr_interface.start_display(glasses_id, xr_rig, xr_rig.origin) + xr_rig.camera.tracker = "/user/%s/head" % glasses_id + xr_rig.wand.tracker = "/user/%s/wand_1" % glasses_id func _process_glasses(): - for glasses_id in glasses_dict: - var glasses_state = glasses_dict.get(glasses_id) as GlassesState - if glasses_state.can_attempt_to_reserve() and t5_manager.should_use_glasses(glasses_id): - glasses_state.attempting_to_reserve = true + for glasses_id in id_to_state: + var xr_rig_state = id_to_state.get(glasses_id) as XRRigState + if xr_rig_state.can_attempt_to_reserve() and t5_manager.should_use_glasses(glasses_id): + xr_rig_state.attempting_to_reserve = true tilt_five_xr_interface.reserve_glasses(glasses_id, t5_manager.get_glasses_display_name(glasses_id)) func _on_service_event(event_num): @@ -108,54 +85,54 @@ func _on_service_event(event_num): t5_manager.service_incorrect_version() func _on_glasses_event(glasses_id, event_num): - var glasses_state = glasses_dict.get(glasses_id) as GlassesState - if not glasses_state: - glasses_state = GlassesState.new() - glasses_dict[glasses_id] = glasses_state + var xr_rig_state = id_to_state.get(glasses_id) as XRRigState + if not xr_rig_state: + xr_rig_state = XRRigState.new() + id_to_state[glasses_id] = xr_rig_state match event_num: TiltFiveXRInterface.E_GLASSES_AVAILABLE: print_verbose(glasses_id, " E_AVAILABLE") - glasses_state.available = true + xr_rig_state.available = true _process_glasses() TiltFiveXRInterface.E_GLASSES_UNAVAILABLE: print_verbose(glasses_id, " E_UNAVAILABLE") - glasses_state.available = false - if glasses_state.attempting_to_reserve: - glasses_state.attempting_to_reserve = false + xr_rig_state.available = false + if xr_rig_state.attempting_to_reserve: + xr_rig_state.attempting_to_reserve = false _process_glasses() TiltFiveXRInterface.E_GLASSES_RESERVED: print_verbose(glasses_id, " E_RESERVED") - glasses_state.reserved = true - glasses_state.attempting_to_reserve = false + xr_rig_state.reserved = true + xr_rig_state.attempting_to_reserve = false - var glasses_scene = t5_manager.create_glasses_scene(glasses_id) - # instance our scene - if glasses_scene: - glasses_state.glasses_scene = glasses_scene - _start_display(glasses_id, glasses_scene) + var xr_rig = t5_manager.create_xr_rig(glasses_id) + if xr_rig: + xr_rig_state.xr_rig = xr_rig + _start_display(glasses_id, xr_rig) else: tilt_five_xr_interface.release_glasses(glasses_id) TiltFiveXRInterface.E_GLASSES_DROPPED: print_verbose(glasses_id, " E_DROPPED") - glasses_state.reserved = false + xr_rig_state.reserved = false - var glasses_scene = glasses_state.glasses_scene - if glasses_scene: + var xr_rig = xr_rig_state.xr_rig + if xr_rig: tilt_five_xr_interface.stop_display(glasses_id) - glasses_state.glasses_scene = null - t5_manager.release_glasses_scene(glasses_scene) + xr_rig_state.xr_rig = null + t5_manager.release_xr_rig(xr_rig) TiltFiveXRInterface.E_GLASSES_TRACKING: var gbt = tilt_five_xr_interface.get_gameboard_type(glasses_id) - if glasses_state.gameboard_type != gbt: - glasses_state.gameboard_type = gbt - if glasses_state.glasses_scene: - t5_manager.set_glasses_scene_gameboard_type(glasses_state.glasses_scene, glasses_state.gameboard_type) - print_verbose(glasses_id, " E_TRACKING, Gameboard size = ", tilt_five_xr_interface.get_gameboard_extents(gbt)) + var xr_rig = xr_rig_state.xr_rig + if xr_rig and xr_rig.gameboard_type != gbt: + xr_rig.gameboard_type = gbt + xr_rig.gameboard_size = tilt_five_xr_interface.get_gameboard_extents(gbt) + t5_manager.set_gameboard_type(xr_rig, gbt) + print_verbose(glasses_id, " E_TRACKING, Gameboard size = ", ) TiltFiveXRInterface.E_GLASSES_NOT_TRACKING: print_verbose(glasses_id, " E_NOT_TRACKING") diff --git a/example.gd/addons/tiltfive/T5Manager.gd b/example.gd/addons/tiltfive/T5Manager.gd index 262998a..a27a98a 100644 --- a/example.gd/addons/tiltfive/T5Manager.gd +++ b/example.gd/addons/tiltfive/T5Manager.gd @@ -10,16 +10,20 @@ class_name T5Manager extends "res://addons/tiltfive/T5ManagerBase.gd" ## This should be persistent. ## Signal when the glasses scene is added to the main scene +## This signal is depreciated please use xr_rig_was_added signal glasses_scene_was_added(glasses : T5XRRig) ## Signal when the glasses scene is removed from the main scene +## This signal is depreciated please use xr_rig_will_be_removed signal glasses_scene_will_be_removed(glasses : T5XRRig) -const xr_origin_node := ^"Origin" -const xr_camera_node := ^"Origin/Camera" -const wand_node_list := [^"Origin/Wand_1", ^"Origin/Wand_2"] +## Signal when the T5XRRig scene is added to the main scene +signal xr_rig_was_added(xr_rig : T5XRRig) -## [PackedScene] that will instanced for a pair of Tilt Five glasses. Defaults to T5XRRig.tscn +## Signal when the T5XRRig scene is removed to the main scene +signal xr_rig_will_be_removed(xr_rig : T5XRRig) + +## [PackedScene] inherited from T5XRRig.tcsn. @export var glasses_scene : PackedScene = preload("res://addons/tiltfive/scenes/T5XRRig.tscn") ## A [T5Gameboard] node in the scene that will be used to set the location and content scale of the @@ -34,32 +38,20 @@ func _ready(): glasses_node.name = "TiltFiveGlasses" get_parent().add_child.call_deferred(glasses_node) -func create_glasses_scene(glasses_id : String) -> Node: - var gview = glasses_scene.instantiate() - glasses_node.add_child(gview) +func create_xr_rig(glasses_id : String) -> T5XRRig: + var xr_rig = glasses_scene.instantiate() as T5XRRig + glasses_node.add_child(xr_rig) if start_location: - var origin := get_glasses_scene_origin(gview) + var origin := xr_rig.origin as T5Origin3D origin.transform = start_location.transform origin.gameboard_scale = start_location.content_scale - glasses_scene_was_added.emit(gview) - return gview - -func release_glasses_scene(glasses_scene : Node) -> void: - glasses_scene_will_be_removed.emit(glasses_scene) - glasses_node.remove_child(glasses_scene) - glasses_scene.queue_free() - -func get_glasses_scene_viewport(glasses_scene : Node) -> SubViewport: - return glasses_scene as SubViewport - -func get_glasses_scene_origin(glasses_scene : Node) -> T5Origin3D: - return glasses_scene.get_node(xr_origin_node) - -func get_glasses_scene_camera(glasses_scene : Node) -> Camera3D: - return glasses_scene.get_node(xr_camera_node) + glasses_scene_was_added.emit(xr_rig) + xr_rig_was_added.emit(xr_rig) + return xr_rig -func get_glasses_scene_wand(glasses_scene : Node, wand_num : int) -> T5Controller3D: - if wand_num < wand_node_list.size(): - return glasses_scene.get_node_or_null(wand_node_list[wand_num]) as T5Controller3D - return null +func release_xr_rig(xr_rig : T5XRRig) -> void: + glasses_scene_will_be_removed.emit(xr_rig) + xr_rig_will_be_removed.emit(xr_rig) + glasses_node.remove_child(xr_rig) + xr_rig.queue_free() diff --git a/example.gd/addons/tiltfive/T5ManagerBase.gd b/example.gd/addons/tiltfive/T5ManagerBase.gd index 275e3de..1fee712 100644 --- a/example.gd/addons/tiltfive/T5ManagerBase.gd +++ b/example.gd/addons/tiltfive/T5ManagerBase.gd @@ -9,10 +9,6 @@ extends Node ## ## create_glasses_scene ## release_glasses_scene -## get_glasses_scene_viewport -## get_glasses_scene_origin -## get_glasses_scene_camera -## get_glasses_scene_wand ## ## The derived node should be persistent. @@ -53,39 +49,17 @@ func should_use_glasses(glasses_id : String) -> bool: func get_glasses_display_name(glasses_id : String) -> String: return T5ProjectSettings.default_display_name -## Invoked by the T5Interface to get the XR rig scene to be associated with -## tilt five glasses. This scene should contain a SubViewport -> T5Origin -> Camera3D and T5Controller3D(s) -func create_glasses_scene(glasses_id : String) -> Node: - push_error("create_glasses_scene not implemented in T5ManagerBase derived class") +## Invoked by the T5Interface to get an T5XRRig derived node +func create_xr_rig(glasses_id : String) -> T5XRRig: + push_error("create_xr_rig not implemented in T5ManagerBase derived class") return null ## Invoked by the T5Interface if the Tilt Five glasses become unavailable -func release_glasses_scene(glasses_scene : Node) -> void: +func release_xr_rig(xr_rig : T5XRRig) -> void: push_error("release_glasses_scene not implemented in T5ManagerBase derived class") -## Invoked by the T5Interface to get the SubViewport of the XR rig -func get_glasses_scene_viewport(glasses_scene : Node) -> SubViewport: - push_error("get_glasses_scene_viewport not implemented in T5ManagerBase derived class") - return null - -## Invoked by the T5Interface to get the T5Origin3D of the XR rig -func get_glasses_scene_origin(glasses_scene : Node) -> T5Origin3D: - push_error("get_glasses_scene_origin not implemented in T5ManagerBase derived class") - return null - -## Invoked by the T5Interface to get the Camera3D of the XR rig -func get_glasses_scene_camera(glasses_scene : Node) -> Camera3D: - push_error("get_glasses_scene_camera not implemented in T5ManagerBase derived class") - return null - -## Invoked by the T5Interface to get a T5Controller3D from the XR rig. Although the default rig -## has only one wand two may be paired to a headset. -func get_glasses_scene_wand(glasses_scene : Node, wand_num : int) -> T5Controller3D: - push_error("get_glasses_scene_wand not implemented in T5ManagerBase derived class") - return null - ## Invoked by the T5Interface to set the gameboard type the Tilt Fiave glasses detected -func set_glasses_scene_gameboard_type(glasses_scene : Node, gameboard_type : T5Interface.GameboardType) -> void: +func set_gameboard_type(xr_rig : T5XRRig, gameboard_type : T5Def.GameboardType) -> void: pass diff --git a/example.gd/addons/tiltfive/assets/auto_scale.gd b/example.gd/addons/tiltfive/assets/auto_scale.gd index 7ebb34e..1ccbb52 100644 --- a/example.gd/addons/tiltfive/assets/auto_scale.gd +++ b/example.gd/addons/tiltfive/assets/auto_scale.gd @@ -1,4 +1,6 @@ extends Node3D +## This node can be placed on content added to the T5XRRig to scale it +## by the T5Origin3D gameboard_scale var origin : T5Origin3D var gameboard_scale : float = 1.0 @@ -9,17 +11,14 @@ func _find_origin(): if parent is T5Origin3D: origin = parent return - parent = parent.get_parent() - # Called when the node enters the scene tree for the first time. func _ready(): _find_origin() - # Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta): +func _process(_delta): if origin and origin.gameboard_scale != gameboard_scale: gameboard_scale = origin.gameboard_scale scale = Vector3(gameboard_scale, gameboard_scale, gameboard_scale) diff --git a/example.gd/addons/tiltfive/scenes/T5XRRig.gd b/example.gd/addons/tiltfive/scenes/T5XRRig.gd index 17b15e0..bbde4c1 100644 --- a/example.gd/addons/tiltfive/scenes/T5XRRig.gd +++ b/example.gd/addons/tiltfive/scenes/T5XRRig.gd @@ -1,11 +1,28 @@ class_name T5XRRig extends SubViewport +## represents a scene with all the components needed for Tilt Five tracked glasses and wand -@onready var wand = $Origin/Wand_1 +## An ID attached to a pair of Tilt Five glasses +var glasses_id : StringName + +## Type of gameboard that is set up +var gameboard_type := T5Def.GameboardType.Unknown + +## size of the gameboard in meters. Raised XE gameboards can have a height +var gameboard_size := AABB() + +## the node that relates the center of the gameboard to world coordinates +var origin : T5Origin3D + +## the tracked camera +var camera : T5Camera3D + +## the tracked wand controller +var wand : T5Controller3D + +func _enter_tree(): + origin = $Origin + camera = $Origin/Camera + wand = $Origin/Wand_1 func _process(_delta): - if wand: - var wand_pose : XRPose = wand.get_pose() - if wand_pose: - wand.visible = wand_pose.tracking_confidence != XRPose.XR_TRACKING_CONFIDENCE_NONE - else: - wand.visible = false + if wand: wand.visible = wand.get_has_tracking_data() diff --git a/example.gd/main.tscn b/example.gd/main.tscn index cf921a2..50512fe 100644 --- a/example.gd/main.tscn +++ b/example.gd/main.tscn @@ -94,7 +94,7 @@ surface_material_override/0 = SubResource("StandardMaterial3D_dji1h") [node name="Label3D" type="Label3D" parent="Boxes/Positive Z"] transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 0, 1.08084) pixel_size = 0.01 -text = "Forward (Z+)" +text = "Backwards (Z+)" [node name="Negative Z" type="MeshInstance3D" parent="Boxes"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.5) diff --git a/example.gd/scenes/pointer_control.gd b/example.gd/scenes/pointer_control.gd index e2dd993..411b000 100644 --- a/example.gd/scenes/pointer_control.gd +++ b/example.gd/scenes/pointer_control.gd @@ -9,84 +9,47 @@ var unselected_mat : Material var stick_pos = Vector3() var trigger_pos = Vector3() -const WAND_BUTTON_A := "button_a" -const WAND_BUTTON_B := "button_b" -const WAND_BUTTON_X := "button_x" -const WAND_BUTTON_Y := "button_y" -const WAND_BUTTON_1 := "button_1" -const WAND_BUTTON_2 := "button_2" -const WAND_BUTTON_STICK := "button_3" -const WAND_BUTTON_T5 := "button_t5" -const WAND_BUTTON_TRIGGER := "trigger_click" - # Axis -const WAND_ANALOG_STICK := "stick" -const WAND_ANALOG_TRIGGER := "trigger" +var button_dict = { + T5Def.WAND_BUTTON_A : ^"Controls/A", + T5Def.WAND_BUTTON_B : ^"Controls/B", + T5Def.WAND_BUTTON_X : ^"Controls/X", + T5Def.WAND_BUTTON_Y : ^"Controls/Y", + T5Def.WAND_BUTTON_1 : ^"Controls/One", + T5Def.WAND_BUTTON_2 : ^"Controls/Two", + T5Def.WAND_BUTTON_STICK : ^"Controls/Three", + T5Def.WAND_BUTTON_T5 : ^"Controls/T5", + T5Def.WAND_BUTTON_TRIGGER : ^"Controls/TriggerClick" +} # Called when the node enters the scene tree for the first time. func _ready(): stick_pos = $Controls/Three.transform.origin trigger_pos = $Controls/Trigger.transform.origin - $Controls/A.material_override = unselected_mat - $Controls/B.material_override = unselected_mat - $Controls/X.material_override = unselected_mat - $Controls/Y.material_override = unselected_mat - $Controls/One.material_override = unselected_mat - $Controls/Two.material_override = unselected_mat - $Controls/Three.material_override = unselected_mat - $Controls/T5.material_override = unselected_mat $Controls/Trigger.material_override = unselected_mat - $Controls/TriggerClick.material_override = unselected_mat - + for key in button_dict.keys(): + var ctrl = get_node_or_null(button_dict[key]) + button_dict[key] = ctrl + if ctrl: + ctrl.material_override = unselected_mat # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(_delta): - var trigger = get_float(WAND_ANALOG_TRIGGER) * 0.03 + var trigger = get_float(T5Def.WAND_ANALOG_TRIGGER) * 0.03 $Controls/Trigger.transform.origin = trigger_pos + Vector3(0, 0, trigger) - var axis = get_vector2(WAND_ANALOG_STICK) * 0.03 + var axis = get_vector2(T5Def.WAND_ANALOG_STICK) * 0.03 $Controls/Three.transform.origin = stick_pos + Vector3(axis.x, 0, -axis.y) - func _on_button_pressed(button): - match button: - WAND_BUTTON_A: - $Controls/A.material_override = selected_mat - WAND_BUTTON_B: - $Controls/B.material_override = selected_mat - WAND_BUTTON_X: - $Controls/X.material_override = selected_mat - WAND_BUTTON_Y: - $Controls/Y.material_override = selected_mat - WAND_BUTTON_1: - trigger_haptic_pulse(1,100) - $Controls/One.material_override = selected_mat - WAND_BUTTON_2: - trigger_haptic_pulse(1,50) - $Controls/Two.material_override = selected_mat - WAND_BUTTON_STICK: - $Controls/Three.material_override = selected_mat - WAND_BUTTON_T5: - $Controls/T5.material_override = selected_mat - WAND_BUTTON_TRIGGER: - $Controls/TriggerClick.material_override = selected_mat - + var ctrl = button_dict.get(button) + if ctrl: + ctrl.material_override = selected_mat + if button == T5Def.WAND_BUTTON_1: + trigger_haptic_pulse(1, 100) + elif button == T5Def.WAND_BUTTON_2: + trigger_haptic_pulse(1, 50) func _on_button_released(button): - match button: - WAND_BUTTON_A: - $Controls/A.material_override = unselected_mat - WAND_BUTTON_B: - $Controls/B.material_override = unselected_mat - WAND_BUTTON_X: - $Controls/X.material_override = unselected_mat - WAND_BUTTON_Y: - $Controls/Y.material_override = unselected_mat - WAND_BUTTON_1: - $Controls/One.material_override = unselected_mat - WAND_BUTTON_2: - $Controls/Two.material_override = unselected_mat - WAND_BUTTON_STICK: - $Controls/Three.material_override = unselected_mat - WAND_BUTTON_T5: - $Controls/T5.material_override = unselected_mat - WAND_BUTTON_TRIGGER: - $Controls/TriggerClick.material_override = unselected_mat + var ctrl = button_dict.get(button) + if ctrl: + ctrl.material_override = unselected_mat +