From d342f8a8bd9b64f83eedd1143d47a40b19219e02 Mon Sep 17 00:00:00 2001 From: patrickdown Date: Sat, 30 Mar 2024 13:42:48 -0400 Subject: [PATCH] Implement API for obtaining glasses friendly name This change allows the friendly name defined in the Tilt Five control panel to be accessed. This change also removes the default_display_name option which was producing confusion because it was badly named and was misinterpreted for the the friendly name above. This was the name that was sent to the Tilt Five control panel to display with the glasses while the application was running. But really this should just be the application name and so the plugin now just sends the application name in it's place. The example apps were also amended to demo the feature. Co-authored-by: Jonathan Stevens --- example.csharp/ExampleRig.cs | 27 +++++++++++++++++++ example.csharp/ExampleRig.tscn | 11 +++++++- example.csharp/addons/tiltfive/T5Interface.cs | 15 ++++++++++- example.csharp/addons/tiltfive/T5Manager.cs | 14 ++++++---- .../addons/tiltfive/T5ManagerInterface.cs | 6 ----- .../addons/tiltfive/T5ProjectSettings.cs | 12 --------- .../addons/tiltfive/scenes/T5XRRig.cs | 8 ++++++ example.csharp/project.godot | 9 +------ example.gd/addons/tiltfive/T5Interface.gd | 9 +++++-- example.gd/addons/tiltfive/T5ManagerBase.gd | 6 ----- .../addons/tiltfive/T5ProjectSettings.gd | 9 ------- example.gd/addons/tiltfive/scenes/T5XRRig.gd | 4 +++ example.gd/main.gd | 10 ++++--- example.gd/main.tscn | 5 +++- example.gd/project.godot | 4 ++- example.gd/scenes/ExampleXRRig.gd | 16 +++++++++++ example.gd/scenes/ExampleXRRig.tscn | 11 +++++++- extension/T5Integration/Wand.h | 1 + extension/src/TiltFiveXRInterface.cpp | 12 +++++++++ extension/src/TiltFiveXRInterface.h | 2 ++ 20 files changed, 134 insertions(+), 57 deletions(-) create mode 100644 example.csharp/ExampleRig.cs create mode 100644 example.gd/scenes/ExampleXRRig.gd diff --git a/example.csharp/ExampleRig.cs b/example.csharp/ExampleRig.cs new file mode 100644 index 0000000..667ec42 --- /dev/null +++ b/example.csharp/ExampleRig.cs @@ -0,0 +1,27 @@ +using Godot; +using System; + +public partial class ExampleRig : T5XRRig +{ + Node3D pivot; + + public override void _Ready() + { + pivot = GetNode("Origin/Pivot"); + var label = GetNode("Origin/Pivot/GlassesName"); + + var timer = new Timer(); + timer.Autostart = true; + timer.WaitTime = 1.0; + AddChild(timer); + timer.Timeout += () => label.Text = GlassesName; + } + + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(double delta) + { + var pos = Camera.GlobalPosition; + if(pivot.GlobalPosition.DistanceTo(pos) < 0.01) return; + pivot.LookAt(new Vector3(pos.X, pivot.GlobalPosition.Y, pos.Z), Vector3.Up, true); + } +} diff --git a/example.csharp/ExampleRig.tscn b/example.csharp/ExampleRig.tscn index 25ff8a4..255094c 100644 --- a/example.csharp/ExampleRig.tscn +++ b/example.csharp/ExampleRig.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=8 format=3 uid="uid://ba8h6c1mtb3h0"] +[gd_scene load_steps=9 format=3 uid="uid://ba8h6c1mtb3h0"] [ext_resource type="PackedScene" uid="uid://dpbt52d0p5wjw" path="res://addons/tiltfive/scenes/T5XRRig.tscn" id="1_x7gas"] +[ext_resource type="Script" path="res://ExampleRig.cs" id="2_af07c"] [ext_resource type="PackedScene" uid="uid://b1cd3jc00rhal" path="res://addons/tiltfive/assets/T5GlassesModel.tscn" id="2_dp1ep"] [ext_resource type="Script" path="res://WandControl.cs" id="2_epf7w"] [ext_resource type="PackedScene" uid="uid://dnx42xctfl3mx" path="res://Controls.tscn" id="2_ge6xw"] @@ -13,6 +14,7 @@ albedo_color = Color(0.580392, 0.396078, 0.278431, 1) albedo_color = Color(0.0352941, 1, 0, 1) [node name="T5XRRig" instance=ExtResource("1_x7gas")] +script = ExtResource("2_af07c") [node name="Camera" parent="Origin" index="0"] cull_mask = 1048573 @@ -28,3 +30,10 @@ selected = SubResource("StandardMaterial3D_kgxv6") transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0.585525, -0.00207818, 0.223126) [node name="T5-wand" parent="Origin/Wand_1" index="1" instance=ExtResource("5_j53ao")] + +[node name="Pivot" type="Node3D" parent="Origin" index="2"] + +[node name="GlassesName" type="Label3D" parent="Origin/Pivot" index="0"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 4.46927) +pixel_size = 0.01 +text = "Name" diff --git a/example.csharp/addons/tiltfive/T5Interface.cs b/example.csharp/addons/tiltfive/T5Interface.cs index 30e1527..cdb49da 100644 --- a/example.csharp/addons/tiltfive/T5Interface.cs +++ b/example.csharp/addons/tiltfive/T5Interface.cs @@ -89,6 +89,19 @@ public override void _Ready() } } + public string GetGlassesName(string glassesID) + { + if(string.IsNullOrEmpty(glassesID) + || !xrInterface.Get("is_initialized").AsBool() + || !glassesDictionary.TryGetValue(glassesID, out var xrRigState) + || !xrRigState.available) + { + return string.Empty; + } + + return xrInterface.Call("get_glasses_name", glassesID).AsString(); + } + void StartDisplay(string glassesID, T5XRRig xrRig) { xrInterface.Call("start_display", glassesID, xrRig, xrRig.Origin); @@ -103,7 +116,7 @@ void ProcessGlasses() if(entry.Value.CanAttemptToReserve && Manager.ShouldUseGlasses(entry.Key)) { entry.Value.attemptingToReserve = true; - xrInterface.Call("reserve_glasses", entry.Key, Manager.GetUIDisplayName(entry.Key)); + xrInterface.Call("reserve_glasses", entry.Key, T5ProjectSettings.ApplicationID); } } } diff --git a/example.csharp/addons/tiltfive/T5Manager.cs b/example.csharp/addons/tiltfive/T5Manager.cs index 7c981f2..ecf4ffe 100644 --- a/example.csharp/addons/tiltfive/T5Manager.cs +++ b/example.csharp/addons/tiltfive/T5Manager.cs @@ -52,6 +52,14 @@ public override void _Ready() GetTree().Root.CallDeferred(MethodName.AddChild, rigs); } + [Obsolete("Use T5XRRig.GlassName instead")] + public string GetUIDisplayName(string glassesID) + { + return t5Interface?.GetGlassesName(glassesID) ?? ""; + } + + + #region T5ManagerInterface implementation public void ServiceStarted() { } @@ -75,11 +83,6 @@ public bool ShouldUseGlasses(string glassesID) return true; } - public string GetUIDisplayName(string glassesID) - { - return T5ProjectSettings.DefaultDisplayName; - } - public T5XRRig CreateXRRig(string glassesID) { var newRig = xrRigScene.Instantiate(); @@ -108,4 +111,5 @@ public void ReleaseXRRig(T5XRRig xrRig) public void SetGameboardType(T5XRRig rig, T5Def.GameboardType gameboard_type) { } + #endregion } diff --git a/example.csharp/addons/tiltfive/T5ManagerInterface.cs b/example.csharp/addons/tiltfive/T5ManagerInterface.cs index 08c64ec..f54b309 100644 --- a/example.csharp/addons/tiltfive/T5ManagerInterface.cs +++ b/example.csharp/addons/tiltfive/T5ManagerInterface.cs @@ -36,12 +36,6 @@ public interface T5ManagerInterface // game public bool ShouldUseGlasses(string glassesID); - // Invoked by the T5Interface to get the display name to be assigned to - // the glasses. This is the name that shows up in the Tilt Five control - // panel - public string GetUIDisplayName(string glassesID); - //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) public T5XRRig CreateXRRig(string glassesID); diff --git a/example.csharp/addons/tiltfive/T5ProjectSettings.cs b/example.csharp/addons/tiltfive/T5ProjectSettings.cs index 12c5a10..84413f8 100644 --- a/example.csharp/addons/tiltfive/T5ProjectSettings.cs +++ b/example.csharp/addons/tiltfive/T5ProjectSettings.cs @@ -27,7 +27,6 @@ static void DefineProjectSetting(String name, Variant.Type setting_type, Propert public static void setup_properties() { if (!isInitialized) { - DefineProjectSetting("xr/tilt_five/default_display_name", Variant.Type.String, PropertyHint.None, "", ""); DefineProjectSetting("xr/tilt_five/trigger_click_threshhold", Variant.Type.Float, PropertyHint.Range, "0,1,0.01", 0.3); DefineProjectSetting("xr/tilt_five/debug_logging", Variant.Type.Bool, PropertyHint.None, "", false); @@ -55,17 +54,6 @@ public static String ApplicationVersion } } - public static String DefaultDisplayName - { - get { - setup_properties(); - var disp_name = ProjectSettings.GetSettingWithOverride("xr/tilt_five/default_display_name").AsString(); - if (disp_name == null || disp_name == "") - return ApplicationID; - return disp_name; - } - } - public static float TriggerClickThreshhold { get { setup_properties(); return (float)ProjectSettings.GetSettingWithOverride("xr/tilt_five/trigger_click_threshhold").AsDouble(); } diff --git a/example.csharp/addons/tiltfive/scenes/T5XRRig.cs b/example.csharp/addons/tiltfive/scenes/T5XRRig.cs index b7448dd..c5024c6 100644 --- a/example.csharp/addons/tiltfive/scenes/T5XRRig.cs +++ b/example.csharp/addons/tiltfive/scenes/T5XRRig.cs @@ -13,6 +13,14 @@ public partial class T5XRRig : SubViewport public T5OriginCS Origin { get { return origin; } } public T5CameraCS Camera{ get { return camera; } } public T5ControllerCS Wand { get { return wand; } } + + // Returns the friendly name of the glasses defined in the Tilt Five control panel + public string GlassesName { + get { + var t5Interface = GetNode("/root/T5Interface"); + return t5Interface?.GetGlassesName(GlassesID) ?? ""; + } + } // Called when the node enters the scene tree for the first time. public override void _EnterTree() diff --git a/example.csharp/project.godot b/example.csharp/project.godot index 6fb615f..e767ba1 100644 --- a/example.csharp/project.godot +++ b/example.csharp/project.godot @@ -1,11 +1,3 @@ -; Engine configuration file. -; It's best edited using the editor UI and not directly, -; since the parameters that go here are not all obvious. -; -; Format: -; [section] ; section goes between [] -; param=value ; assign values to parameters - config_version=5 [application] @@ -14,6 +6,7 @@ config/name="T5Example.csharp" run/main_scene="res://main.tscn" config/features=PackedStringArray("4.2", "C#", "Forward Plus") config/icon="res://icon.png" +config/tags=PackedStringArray("tiltfive") [autoload] diff --git a/example.gd/addons/tiltfive/T5Interface.gd b/example.gd/addons/tiltfive/T5Interface.gd index 3f7e5df..549f61d 100644 --- a/example.gd/addons/tiltfive/T5Interface.gd +++ b/example.gd/addons/tiltfive/T5Interface.gd @@ -26,7 +26,12 @@ var t5_manager : T5ManagerBase: func get_tilt_five_xr_interface() -> TiltFiveXRInterface: return tilt_five_xr_interface - + +func get_glasses_name(glasses_id: StringName): + if tilt_five_xr_interface: + return tilt_five_xr_interface.get_glasses_name(glasses_id) + return "" + func _enter_tree(): tilt_five_xr_interface = TiltFiveXRInterface.new() if tilt_five_xr_interface: @@ -66,7 +71,7 @@ func _process_glasses(): 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)) + tilt_five_xr_interface.reserve_glasses(glasses_id, T5ProjectSettings.application_id) func _on_service_event(event_num): match event_num: diff --git a/example.gd/addons/tiltfive/T5ManagerBase.gd b/example.gd/addons/tiltfive/T5ManagerBase.gd index 1fee712..74c73b4 100644 --- a/example.gd/addons/tiltfive/T5ManagerBase.gd +++ b/example.gd/addons/tiltfive/T5ManagerBase.gd @@ -42,12 +42,6 @@ func service_incorrect_version(): ## game func should_use_glasses(glasses_id : String) -> bool: return true - -## Invoked by the T5Interface to get the display name to be assigned to -## the glasses. This is the name that shows up in the Tilt Five control -## panel -func get_glasses_display_name(glasses_id : String) -> String: - return T5ProjectSettings.default_display_name ## Invoked by the T5Interface to get an T5XRRig derived node func create_xr_rig(glasses_id : String) -> T5XRRig: diff --git a/example.gd/addons/tiltfive/T5ProjectSettings.gd b/example.gd/addons/tiltfive/T5ProjectSettings.gd index 48140e8..d897cd7 100644 --- a/example.gd/addons/tiltfive/T5ProjectSettings.gd +++ b/example.gd/addons/tiltfive/T5ProjectSettings.gd @@ -27,7 +27,6 @@ static func _define_project_setting( static func setup_properties(): if not _initialized: - _define_project_setting("xr/tilt_five/default_display_name", TYPE_STRING) _define_project_setting("xr/tilt_five/trigger_click_threshhold", TYPE_FLOAT, PROPERTY_HINT_RANGE, "0,1,0.01", 0.3) _define_project_setting("xr/tilt_five/debug_logging", TYPE_BOOL, PROPERTY_HINT_NONE, "", false) _initialized = true @@ -46,14 +45,6 @@ static var application_version : String: return "unknown" return version -static var default_display_name : String: - get: - setup_properties() - var disp_name := ProjectSettings.get_setting_with_override("xr/tilt_five/default_display_name") - if not disp_name or disp_name == "": - return T5ProjectSettings.application_id - return disp_name - static var trigger_click_threshhold : float: get: setup_properties() diff --git a/example.gd/addons/tiltfive/scenes/T5XRRig.gd b/example.gd/addons/tiltfive/scenes/T5XRRig.gd index b1a4c9e..9e84975 100644 --- a/example.gd/addons/tiltfive/scenes/T5XRRig.gd +++ b/example.gd/addons/tiltfive/scenes/T5XRRig.gd @@ -12,6 +12,10 @@ var _wand : T5Controller3D func get_glasses_id() -> StringName: return _glasses_id +## Get the friendly name of the glasses defined in the Tilt Five control panel +func get_glasses_name() -> String: + return T5Interface.get_glasses_name(_glasses_id) + ## Type of gameboard that is set up func get_gameboard_type() -> T5Def.GameboardType: return _gameboard_type diff --git a/example.gd/main.gd b/example.gd/main.gd index 880e6ec..55d86e7 100644 --- a/example.gd/main.gd +++ b/example.gd/main.gd @@ -1,7 +1,9 @@ extends Node3D -func _on_t5_manager_glasses_scene_was_added(glasses): - print("Scene ", glasses.name, " added") -func _on_t5_manager_glasses_scene_will_be_removed(glasses): - print("Scene ", glasses.name, " removed") +func _on_t5_manager_xr_rig_was_added(xr_rig): + print("Scene for glasses ", xr_rig.get_glasses_id(), " added") + + +func _on_t5_manager_xr_rig_will_be_removed(xr_rig): + print("Scene for glasses ", xr_rig.get_glasses_id(), " removed") diff --git a/example.gd/main.tscn b/example.gd/main.tscn index 50512fe..d191798 100644 --- a/example.gd/main.tscn +++ b/example.gd/main.tscn @@ -92,7 +92,7 @@ mesh = SubResource("BoxMesh_gbwc2") 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) +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 0, 1.13267) pixel_size = 0.01 text = "Backwards (Z+)" @@ -119,3 +119,6 @@ surface_material_override/0 = SubResource("StandardMaterial3D_qrhlq") [node name="SpectatorCam" type="Camera3D" parent="."] transform = Transform3D(0.670983, -0.138786, 0.728368, 0, 0.982326, 0.187176, -0.741472, -0.125592, 0.659125, 14.0459, 4.9572, 12.9908) cull_mask = 3 + +[connection signal="xr_rig_was_added" from="T5Manager" to="." method="_on_t5_manager_xr_rig_was_added"] +[connection signal="xr_rig_will_be_removed" from="T5Manager" to="." method="_on_t5_manager_xr_rig_will_be_removed"] diff --git a/example.gd/project.godot b/example.gd/project.godot index 81e86cc..cc644f6 100644 --- a/example.gd/project.godot +++ b/example.gd/project.godot @@ -11,8 +11,9 @@ config_version=5 [application] config/name="T5Example.gd" +config/tags=PackedStringArray("tiltfive") run/main_scene="res://main.tscn" -config/features=PackedStringArray("4.1") +config/features=PackedStringArray("4.2") run/max_fps=60 config/icon="res://icon.png" @@ -41,3 +42,4 @@ trigger={ [xr] shaders/enabled=true +tilt_five/debug_logging=true diff --git a/example.gd/scenes/ExampleXRRig.gd b/example.gd/scenes/ExampleXRRig.gd new file mode 100644 index 0000000..12c179b --- /dev/null +++ b/example.gd/scenes/ExampleXRRig.gd @@ -0,0 +1,16 @@ +extends T5XRRig + + +func _ready(): + var timer = Timer.new() + timer.autostart = true + timer.wait_time = 1 + add_child(timer) + timer.timeout.connect(func(): + $Origin/Pivot/GlassesName.text = get_glasses_name() + ) + +func _process(delta): + var pos : Vector3 = $Origin/Camera.global_position + if pos.distance_to($Origin/Pivot.global_position) < 0.001: return + $Origin/Pivot.look_at(Vector3(pos.x, $Origin/Pivot.global_position.y, pos.z), Vector3.UP, true) diff --git a/example.gd/scenes/ExampleXRRig.tscn b/example.gd/scenes/ExampleXRRig.tscn index b55cb6a..dd77328 100644 --- a/example.gd/scenes/ExampleXRRig.tscn +++ b/example.gd/scenes/ExampleXRRig.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=17 format=3 uid="uid://dl3mv76qkuscf"] +[gd_scene load_steps=18 format=3 uid="uid://dl3mv76qkuscf"] [ext_resource type="PackedScene" uid="uid://je0clrdu7o76" path="res://addons/tiltfive/scenes/T5XRRig.tscn" id="1_mer1r"] +[ext_resource type="Script" path="res://scenes/ExampleXRRig.gd" id="2_8v3h1"] [ext_resource type="Script" path="res://scenes/XROrigin3D.gd" id="2_ovq7h"] [ext_resource type="PackedScene" uid="uid://b1cd3jc00rhal" path="res://addons/tiltfive/assets/T5GlassesModel.tscn" id="3_dh820"] [ext_resource type="Script" path="res://scenes/pointer_control.gd" id="4_bhwvx"] @@ -32,6 +33,7 @@ albedo_color = Color(0.862745, 0, 0.0235294, 1) [sub_resource type="BoxMesh" id="BoxMesh_aaxuw"] [node name="T5Glasses" instance=ExtResource("1_mer1r")] +script = ExtResource("2_8v3h1") [node name="Origin" parent="." index="0"] script = ExtResource("2_ovq7h") @@ -80,5 +82,12 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.77558, 0) mesh = SubResource("BoxMesh_aaxuw") surface_material_override/0 = SubResource("StandardMaterial3D_iuako") +[node name="Pivot" type="Node3D" parent="Origin" index="3"] + +[node name="GlassesName" type="Label3D" parent="Origin/Pivot" index="0"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 4.52651) +pixel_size = 0.01 +text = "Name" + [connection signal="button_pressed" from="Origin/Wand_1" to="Origin/Wand_1" method="_on_button_pressed"] [connection signal="button_released" from="Origin/Wand_1" to="Origin/Wand_1" method="_on_button_released"] diff --git a/extension/T5Integration/Wand.h b/extension/T5Integration/Wand.h index dc59afd..6a4b716 100644 --- a/extension/T5Integration/Wand.h +++ b/extension/T5Integration/Wand.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include diff --git a/extension/src/TiltFiveXRInterface.cpp b/extension/src/TiltFiveXRInterface.cpp index f40d36b..041bec9 100644 --- a/extension/src/TiltFiveXRInterface.cpp +++ b/extension/src/TiltFiveXRInterface.cpp @@ -19,6 +19,7 @@ void TiltFiveXRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("release_glasses", "glasses_id"), &TiltFiveXRInterface::release_glasses); ClassDB::bind_method(D_METHOD("get_available_glasses_ids"), &TiltFiveXRInterface::get_available_glasses_ids); ClassDB::bind_method(D_METHOD("get_reserved_glasses_ids"), &TiltFiveXRInterface::get_reserved_glasses_ids); + ClassDB::bind_method(D_METHOD("get_glasses_name", "glasses_id"), &TiltFiveXRInterface::get_glasses_name); ClassDB::bind_method(D_METHOD("get_gameboard_type", "glasses_id"), &TiltFiveXRInterface::get_gameboard_type); ClassDB::bind_method(D_METHOD("get_gameboard_extents", "gameboard_type"), &TiltFiveXRInterface::get_gameboard_extents); @@ -284,6 +285,17 @@ PackedStringArray TiltFiveXRInterface::get_reserved_glasses_ids() { return reserved_list; } +String TiltFiveXRInterface::get_glasses_name(const StringName glasses_id) { + if(!t5_service) + return String(""); + + auto entry = lookup_glasses_entry(glasses_id); + ERR_FAIL_COND_V_MSG(!entry, String(""), "Glasses id was not found"); + + std::string glasses_name = t5_service->get_glasses_name(entry->idx); + return String(glasses_name.c_str()); +} + TiltFiveXRInterface::GameBoardType TiltFiveXRInterface::get_gameboard_type(const StringName glasses_id) { if (!t5_service) return NO_GAMEBOARD_SET; diff --git a/extension/src/TiltFiveXRInterface.h b/extension/src/TiltFiveXRInterface.h index 98b9ef8..19264e4 100644 --- a/extension/src/TiltFiveXRInterface.h +++ b/extension/src/TiltFiveXRInterface.h @@ -108,6 +108,8 @@ class TiltFiveXRInterface : public XRInterfaceExtension { PackedStringArray get_available_glasses_ids(); PackedStringArray get_reserved_glasses_ids(); + String get_glasses_name(const StringName glasses_id); + // Overriden from XRInterfaceExtension virtual StringName _get_name() const override; virtual uint32_t _get_capabilities() const override;