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;