diff --git a/.gitignore b/.gitignore index b279381..51f4e69 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ build .vscode .vs +*.sln +*.csproj + # Binaries *.o *.os diff --git a/SConstruct b/SConstruct index 3fa320d..91efbd8 100644 --- a/SConstruct +++ b/SConstruct @@ -39,7 +39,9 @@ if env['platform'] == 'windows': f1 = env.Command('example.gd/addons/tiltfive/bin/libgdtiltfive{}{}'.format(env['suffix'], env['SHLIBSUFFIX']), library, Copy('$TARGET', '$SOURCE') ) f2 = env.Command('example.gd/addons/tiltfive/bin/TiltFiveNative.dll', tilt_five_library_path + '/TiltFiveNative.dll', Copy('$TARGET', '$SOURCE') ) +f3 = env.Command('example.csharp/addons/tiltfive/bin/libgdtiltfive{}{}'.format(env['suffix'], env['SHLIBSUFFIX']), library, Copy('$TARGET', '$SOURCE') ) +f4 = env.Command('example.csharp/addons/tiltfive/bin/TiltFiveNative.dll', tilt_five_library_path + '/TiltFiveNative.dll', Copy('$TARGET', '$SOURCE') ) -env.Alias('example', [f1, f2]) +env.Alias('example', [f1, f2, f3, f4]) Default(library) diff --git a/example.csharp/Controls.tscn b/example.csharp/Controls.tscn new file mode 100644 index 0000000..f393380 --- /dev/null +++ b/example.csharp/Controls.tscn @@ -0,0 +1,50 @@ +[gd_scene load_steps=4 format=3 uid="uid://dnx42xctfl3mx"] + +[sub_resource type="CapsuleMesh" id="4"] + +[sub_resource type="BoxMesh" id="BoxMesh_dc5d6"] + +[sub_resource type="SphereMesh" id="3"] + +[node name="Controls" type="Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0748157, -0.00207818, 0.009782) + +[node name="Trigger" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, -0.000888377, -0.0415742, -0.0168045) +mesh = SubResource("4") + +[node name="TriggerClick" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, -0.000888377, -0.00848173, -0.0840266) +mesh = SubResource("BoxMesh_dc5d6") + +[node name="Three" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, 0, 0, 0) +mesh = SubResource("3") + +[node name="One" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, -0.02, 0, 0.05) +mesh = SubResource("3") + +[node name="Two" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, 0.02, 0, 0.05) +mesh = SubResource("3") + +[node name="T5" type="MeshInstance3D" parent="."] +transform = Transform3D(-4.37114e-10, -0.01, 0, 0.01, -4.37114e-10, 0, 0, 0, 0.01, 0, 0, 0.08) +mesh = SubResource("4") + +[node name="X" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, 0, 0, 0.15) +mesh = SubResource("3") + +[node name="B" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, 0, 0, 0.21) +mesh = SubResource("3") + +[node name="Y" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, 0.03, 0, 0.18) +mesh = SubResource("3") + +[node name="A" type="MeshInstance3D" parent="."] +transform = Transform3D(0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01, -0.03, 0, 0.18) +mesh = SubResource("3") diff --git a/example.csharp/ExampleRig.tscn b/example.csharp/ExampleRig.tscn new file mode 100644 index 0000000..25ff8a4 --- /dev/null +++ b/example.csharp/ExampleRig.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=8 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="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"] +[ext_resource type="PackedScene" uid="uid://fipea8dbocg4" path="res://addons/tiltfive/assets/T5WandModel.tscn" id="5_j53ao"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tnkdi"] +albedo_color = Color(0.580392, 0.396078, 0.278431, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kgxv6"] +albedo_color = Color(0.0352941, 1, 0, 1) + +[node name="T5XRRig" instance=ExtResource("1_x7gas")] + +[node name="Camera" parent="Origin" index="0"] +cull_mask = 1048573 + +[node name="T5-glasses" parent="Origin/Camera" index="0" instance=ExtResource("2_dp1ep")] + +[node name="Wand_1" parent="Origin" index="1"] +script = ExtResource("2_epf7w") +unselected = SubResource("StandardMaterial3D_tnkdi") +selected = SubResource("StandardMaterial3D_kgxv6") + +[node name="Controls" parent="Origin/Wand_1" index="0" instance=ExtResource("2_ge6xw")] +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")] diff --git a/example.csharp/WandControl.cs b/example.csharp/WandControl.cs new file mode 100644 index 0000000..9d6b182 --- /dev/null +++ b/example.csharp/WandControl.cs @@ -0,0 +1,119 @@ +using Godot; +using System; +using System.Collections.Generic; +using System.Threading; + +public partial class WandControl : T5ControllerCS +{ + static Dictionary buttons = new() + { + {"button_a", "Controls/A" }, + {"button_b", "Controls/B" }, + {"button_x", "Controls/X" }, + {"button_y", "Controls/Y" }, + {"button_1", "Controls/One" }, + {"button_2", "Controls/Two" }, + {"button_3", "Controls/Three" }, + {"button_t5", "Controls/T5" }, + { "trigger_click", "Controls/TriggerClick" } + + }; + + [Export] + public Material unselected; + + [Export] + public Material selected; + + Vector3 triggerPos; + Vector3 stickPos; + + public override void _EnterTree() + { + base._EnterTree(); + + Connect("button_pressed", Callable.From(OnButtonPressed)); + Connect("button_released", Callable.From(OnButtonReleased)); + } + + public override void _ExitTree() + { + Disconnect("button_pressed", Callable.From(OnButtonPressed)); + Disconnect("button_released", Callable.From(OnButtonReleased)); + + base._ExitTree(); + } + + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + base._Ready(); + + foreach (var entry in buttons) + { + var node = GetNodeOrNull(entry.Value); + if (node != null) + node.MaterialOverride = unselected; + } + var triggerNode = GetNodeOrNull("Controls/Trigger"); + if (triggerNode != null) + { + triggerNode.MaterialOverride = unselected; + triggerPos = triggerNode.Transform.Origin; + } + var stickNode = GetNodeOrNull("Controls/Three"); + if (stickNode != null) + { + stickNode.MaterialOverride = unselected; + stickPos = stickNode.Transform.Origin; + } + } + + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(double delta) + { + base._Process(delta); + + var triggerNode = GetNodeOrNull("Controls/Trigger"); + if(triggerNode != null) + { + var triggerValue = GetFloat("trigger") * 0.03f; + var transform = triggerNode.Transform; + transform.Origin = triggerPos + new Vector3(0, 0, triggerValue); + triggerNode.Transform = transform; + } + + var stickNode = GetNodeOrNull("Controls/Three"); + if (stickNode != null) + { + var stickValue = GetVector2("stick") * 0.03f; + var transform = stickNode.Transform; + transform.Origin = stickPos + new Vector3(stickValue.X, 0, -stickValue.Y); + stickNode.Transform = transform; + } + } + + public void OnButtonPressed(StringName name) + { + if(buttons.TryGetValue(name, out var button)) + { + var node = GetNodeOrNull(button); + if (node != null) node.MaterialOverride = selected; + } + if(name == "button_1") { + TriggerHapticPulse(1,100); + } + else if(name == "button_2") { + TriggerHapticPulse(1,50); + } + } + + public void OnButtonReleased(StringName name) + { + if (buttons.TryGetValue(name, out var button)) + { + var node = GetNodeOrNull(button); + if (node != null) node.MaterialOverride = unselected; + } + } +} diff --git a/example.csharp/addons/tiltfive/T5Interface.cs b/example.csharp/addons/tiltfive/T5Interface.cs new file mode 100644 index 0000000..eed0147 --- /dev/null +++ b/example.csharp/addons/tiltfive/T5Interface.cs @@ -0,0 +1,254 @@ +using Godot; +using System; +using System.Collections.Generic; + +public partial class T5Interface : Node +{ + enum ServiceEventType + { + E_SERVICE_STOPPED = 1, + E_SERVICE_RUNNING = 2, + E_SERVICE_T5_UNAVAILABLE = 3, + E_SERVICE_T5_INCOMPATIBLE_VERSION = 4 + } + + enum GlassesEventType + { + E_GLASSES_ADDED = 1, + E_GLASSES_LOST = 2, + E_GLASSES_AVAILABLE = 3, + E_GLASSES_UNAVAILABLE = 4, + E_GLASSES_RESERVED = 5, + E_GLASSES_DROPPED = 6, + E_GLASSES_TRACKING = 7, + E_GLASSES_NOT_TRACKING = 8, + E_GLASSES_STOPPED_ON_ERROR = 9 + } + + public enum GameboardType + { + Unknown = 1, + LE = 2, + XE = 3, + XE_Raised = 4 + } + + // State of a set of glasses. + class XRRigState { + public bool available = false; + public bool attemptingToReserve = false; + public bool reserved = false; + + public T5XRRig rig; + public GameboardType gameboardType; + + public bool CanAttemptToReserve { get { return available && !attemptingToReserve && !reserved; } } + } + + XRInterface xrInterface; + Dictionary glassesDictionary = new(); + + public T5ManagerInterface Manager { get; set; } + + public override void _EnterTree() + { + base._EnterTree(); + + xrInterface = ClassDB.Instantiate("TiltFiveXRInterface").As(); + + xrInterface.Set("application_id", T5ProjectSettings.ApplicationID); + xrInterface.Set("application_version", T5ProjectSettings.ApplicationVersion); + xrInterface.Set("trigger_click_threshold", T5ProjectSettings.TriggerClickThreshhold); + + XRServer.AddInterface(xrInterface as XRInterface); + + xrInterface.Connect("glasses_event", Callable.From(_OnGlassesEvent)); + xrInterface.Connect("service_event", Callable.From(_OnServiceEvent)); + } + + public override void _ExitTree() + { + xrInterface.Disconnect("service_event", Callable.From(_OnServiceEvent)); + xrInterface.Disconnect("glasses_event", Callable.From(_OnGlassesEvent)); + + if (xrInterface.Get("is_initialized").AsBool()) + { + xrInterface.Call("uninitialize"); + } + XRServer.RemoveInterface(xrInterface as XRInterface); + + base._ExitTree(); + } + + public override void _Ready() + { + base._Ready(); + + if(Manager == null) + { + GD.PrintErr("T5Interface does not have a manager set."); + return; + } + + if(!xrInterface.IsInitialized()) + { + xrInterface.Initialize(); + } + } + + void StartDisplay(string glassesID, T5XRRig xrRig) { + + xrInterface.Call("start_display", glassesID, xrRig, xrRig.Origin); + xrRig.Camera.Tracker = $"/user/{glassesID}/head"; + xrRig.Wand.Tracker = $"/user/{glassesID}/wand_1"; + } + + void ProcessGlasses() + { + foreach(var entry in glassesDictionary) + { + if(entry.Value.CanAttemptToReserve && Manager.ShouldUseGlasses(entry.Key)) + { + entry.Value.attemptingToReserve = true; + xrInterface.Call("reserve_glasses", entry.Key, Manager.GetUIDisplayName(entry.Key)); + } + } + } + + void _OnGlassesEvent(String glassesID, int eventNum) + { + XRRigState xrRigState; + if(!glassesDictionary.TryGetValue(glassesID, out xrRigState)) + { + xrRigState = new XRRigState(); + glassesDictionary.Add(glassesID, xrRigState); + } + + switch ((GlassesEventType)eventNum) + { + case GlassesEventType.E_GLASSES_ADDED: + { + GD.Print(glassesID, " E_GLASSES_ADDED"); + break; + } + case GlassesEventType.E_GLASSES_LOST: + { + GD.Print(glassesID, " E_GLASSES_LOST"); + break; + } + case GlassesEventType.E_GLASSES_AVAILABLE: + { + GD.Print(glassesID, " E_GLASSES_AVAILABLE"); + xrRigState.available = true; + ProcessGlasses(); + break; + } + case GlassesEventType.E_GLASSES_UNAVAILABLE: + { + GD.Print(glassesID, " E_GLASSES_UNAVAILABLE"); + xrRigState.available = false; + if(xrRigState.attemptingToReserve) + { + xrRigState.attemptingToReserve = false; + ProcessGlasses(); + } + break; + } + case GlassesEventType.E_GLASSES_RESERVED: + { + GD.Print(glassesID, " E_GLASSES_RESERVED"); + + xrRigState.reserved = true; + xrRigState.attemptingToReserve = false; + + var xrRig = Manager.CreateXRRig(glassesID); + + // instance our scene + if(xrRig != null) + { + xrRig.GlassesID = glassesID; + xrRigState.rig = xrRig; + StartDisplay(glassesID, xrRig); + } + else + { + xrInterface.Call("release_glasses", glassesID); + } + break; + } + case GlassesEventType.E_GLASSES_DROPPED: + { + GD.Print(glassesID, " E_DROPPED"); + + xrRigState.reserved = false; + xrRigState.attemptingToReserve = false; + + var xrRig = xrRigState.rig; + + if(xrRig != null) { + xrInterface.Call("stop_display", glassesID); + xrRigState.rig = null; + Manager.ReleaseXRRig(xrRig); + + } + break; + } + case GlassesEventType.E_GLASSES_TRACKING: + { + GD.Print(glassesID, " E_GLASSES_TRACKING"); + var gbt = xrInterface.Call("get_gameboard_type", glassesID).As(); + if(xrRigState.gameboardType != gbt) + { + xrRigState.gameboardType = gbt; + if(xrRigState.rig != null) + { + xrRigState.rig.GameboardType = gbt; + xrRigState.rig.GameboardSize = xrInterface.Call("get_gameboard_extents", (int)gbt).AsAabb(); + Manager.SetGameboardType(xrRigState.rig, gbt); + } + } + break; + } + case GlassesEventType.E_GLASSES_NOT_TRACKING: + { + GD.Print(glassesID, " E_GLASSES_NOT_TRACKING"); + break; + } + default: + { + GD.PrintErr(glassesID, " unknown event"); + break; + } + } + + } + + void _OnServiceEvent(int eventNum) + { + switch((ServiceEventType)eventNum) + { + case ServiceEventType.E_SERVICE_STOPPED: + { + Manager.ServiceStopped(); + break; + } + case ServiceEventType.E_SERVICE_RUNNING: + { + Manager.ServiceStarted(); + break; + } + case ServiceEventType.E_SERVICE_T5_UNAVAILABLE: + { + Manager.ServiceUnavailable(); + break; + } + case ServiceEventType.E_SERVICE_T5_INCOMPATIBLE_VERSION: + { + Manager.ServiceIncorrectVersion(); + break; + } + } + } + + +} diff --git a/example.csharp/addons/tiltfive/T5Manager.cs b/example.csharp/addons/tiltfive/T5Manager.cs new file mode 100644 index 0000000..f3d1f81 --- /dev/null +++ b/example.csharp/addons/tiltfive/T5Manager.cs @@ -0,0 +1,111 @@ +using Godot; +using System; + +[GlobalClass] +public partial class T5Manager : Node, T5ManagerInterface +{ + [Signal] + public delegate void XRRigWasAddedEventHandler(T5XRRig rig); + + [Signal] + public delegate void XRRigWillBeRemovedEventHandler(T5XRRig rig); + + [Export] + public PackedScene xrRigScene; + + [Export] + public Node3D startLocation; + + Node3D rigs; + + T5Interface t5Interface; + + public override void _EnterTree() + { + base._EnterTree(); + + if (xrRigScene == null) + { + xrRigScene = (PackedScene)ResourceLoader.Load("res://addons/tiltfive/scenes/T5XRRig.tscn"); + } + + t5Interface = GetNode("/root/T5Interface"); + if (t5Interface != null) + { + t5Interface.Manager = this; + } + } + + public override void _ExitTree() + { + if(t5Interface != null) + { + t5Interface.Manager = null; + } + base._ExitTree(); + } + + public override void _Ready() + { + rigs = new Node3D(); + rigs.Name = "T5XRRigs"; + GetTree().Root.CallDeferred(MethodName.AddChild, rigs); + } + + public void ServiceStarted() + { + } + + public void ServiceStopped() + { + } + + public void ServiceUnavailable() + { + GD.PrintErr("Tilt Five Service is unavailable"); + } + + public void ServiceIncorrectVersion() + { + GD.PrintErr("Tilt Five Service version is incompatible"); + } + + public bool ShouldUseGlasses(string glassesID) + { + return true; + } + + public string GetUIDisplayName(string glassesID) + { + return T5ProjectSettings.DefaultDisplayName; + } + + public T5XRRig CreateXRRig(string glassesID) + { + var newRig = xrRigScene.Instantiate(); + newRig.Name = glassesID; + rigs.AddChild(newRig); + if(startLocation != null) + { + var origin = newRig.Origin; + origin.Transform = startLocation.Transform; + if(startLocation.IsClass("T5Gameboard")) { + var contentScale = startLocation.Get("content_scale").As(); + origin.Set("gameboard_scale", contentScale); + } + } + EmitSignal(SignalName.XRRigWasAdded, newRig); + return newRig; + } + + public void ReleaseXRRig(T5XRRig xrRig) + { + EmitSignal(SignalName.XRRigWillBeRemoved, xrRig); + rigs.RemoveChild(xrRig); + xrRig.QueueFree(); + } + + public void SetGameboardType(T5XRRig rig, T5Interface.GameboardType gameboard_type) + { + } +} diff --git a/example.csharp/addons/tiltfive/T5ManagerInterface.cs b/example.csharp/addons/tiltfive/T5ManagerInterface.cs new file mode 100644 index 0000000..7ba50d5 --- /dev/null +++ b/example.csharp/addons/tiltfive/T5ManagerInterface.cs @@ -0,0 +1,55 @@ +// Interface for all T5Managers. Should not be used directly. +// +// Classes derived from T5ManagerBase implement these voidtions +// to customize the process of connecting the XR rigs in the scene +// to the Tilt Five glasses hardware that is found. +// +// These voidtions must be overridden +// +// 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. + +public interface T5ManagerInterface +{ + + // Invoked by T5Interface when the Tilt Five service has started + public void ServiceStarted(); + + // Invoked by T5Interface when the Tilt Five service has stopped + public void ServiceStopped(); + + // Invoked by T5Interface when the Tilt Five service is not available + // The driver might not be installed + public void ServiceUnavailable(); + + // Invoked by T5Interface when the Tilt Five service installed does + // not meet the minimum version requirements + public void ServiceIncorrectVersion(); + + // Invoked by the T5Interface to find out if the glasses should be used in + // 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); + + // Invoked by the T5Interface if the Tilt Five glasses become unavailable + public void ReleaseXRRig(T5XRRig xrRig); + + // Invoked by the T5Interface to set the gameboard type the Tilt Five glasses detected + public void SetGameboardType(T5XRRig rig, T5Interface.GameboardType gameboard_type); +} + diff --git a/example.csharp/addons/tiltfive/T5ProjectSettings.cs b/example.csharp/addons/tiltfive/T5ProjectSettings.cs new file mode 100644 index 0000000..eda671d --- /dev/null +++ b/example.csharp/addons/tiltfive/T5ProjectSettings.cs @@ -0,0 +1,59 @@ +using Godot; +using System; + + +public static class T5ProjectSettings +{ + static bool isInitialized = false; + + static void DefineProjectSetting(String name, Variant.Type setting_type, PropertyHint hint, String hintString, Variant defaultValue) + { + if(!ProjectSettings.HasSetting(name)) + { + ProjectSettings.SetSetting(name, defaultValue); + } + + var propertyInfo = new Godot.Collections.Dictionary(); + + propertyInfo["name"] = name; + propertyInfo["type"] = (int)setting_type; + propertyInfo["hint"] = (int)hint; + propertyInfo["hint_string"] = hintString; + + ProjectSettings.AddPropertyInfo(propertyInfo); + ProjectSettings.SetAsBasic(name, true); + ProjectSettings.SetInitialValue(name, defaultValue); + } + + public static void setup_properties() { + if (!isInitialized) { + DefineProjectSetting("xr/tilt_five/application_id", Variant.Type.String, PropertyHint.None, "", "my.game.com"); + DefineProjectSetting("xr/tilt_five/application_version", Variant.Type.String, PropertyHint.None, "", "0.1.0"); + DefineProjectSetting("xr/tilt_five/default_display_name", Variant.Type.String, PropertyHint.None, "", "Game: Player One"); + DefineProjectSetting("xr/tilt_five/trigger_click_threshhold", Variant.Type.Float, PropertyHint.Range, "0,1,0.01", 0.3); + + isInitialized = true; + } + } + + public static String ApplicationID + { + get { setup_properties(); return ProjectSettings.GetSettingWithOverride("xr/tilt_five/application_id").AsString(); } + } + + public static String ApplicationVersion + { + get { setup_properties(); return ProjectSettings.GetSettingWithOverride("xr/tilt_five/application_version").AsString(); } + } + + public static String DefaultDisplayName + { + get { setup_properties(); return ProjectSettings.GetSettingWithOverride("xr/tilt_five/default_display_name").AsString(); } + } + + 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/assets/AutoScale.cs b/example.csharp/addons/tiltfive/assets/AutoScale.cs new file mode 100644 index 0000000..2d9910c --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/AutoScale.cs @@ -0,0 +1,38 @@ +using Godot; +using System; + +public partial class AutoScale : Node3D +{ + T5OriginCS origin; + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + base._Ready(); + + var parent = GetParent(); + while(parent != null && !parent.IsClass("T5Origin3D")) + parent = parent.GetParent(); + + if(parent != null) + { + + origin = parent as T5OriginCS; + float scale = origin.GameboardScale; + Scale = new Vector3(scale, scale, scale); + origin.Connect("gameboard_scale_changed", Callable.From(OnGameboardScaleChanged)); + } + } + + public override void _ExitTree() + { + if(origin != null) + origin.Disconnect("gameboard_scale_changed", Callable.From(OnGameboardScaleChanged)); + origin = null; + base._ExitTree(); + } + + public void OnGameboardScaleChanged(float scale) + { + Scale = new Vector3(scale, scale, scale); + } +} diff --git a/example.csharp/addons/tiltfive/assets/T5-glasses.glb b/example.csharp/addons/tiltfive/assets/T5-glasses.glb new file mode 100644 index 0000000..58aa551 Binary files /dev/null and b/example.csharp/addons/tiltfive/assets/T5-glasses.glb differ diff --git a/example.csharp/addons/tiltfive/assets/T5-glasses.glb.import b/example.csharp/addons/tiltfive/assets/T5-glasses.glb.import new file mode 100644 index 0000000..722a6ee --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/T5-glasses.glb.import @@ -0,0 +1,32 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://c44ott7hdtkjs" +path="res://.godot/imported/T5-glasses.glb-6d0d56d53da01ab25c5e0d7abeb3b195.scn" + +[deps] + +source_file="res://addons/tiltfive/assets/T5-glasses.glb" +dest_files=["res://.godot/imported/T5-glasses.glb-6d0d56d53da01ab25c5e0d7abeb3b195.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={} +gltf/embedded_image_handling=1 diff --git a/example.csharp/addons/tiltfive/assets/T5-wand.glb b/example.csharp/addons/tiltfive/assets/T5-wand.glb new file mode 100644 index 0000000..2414c57 Binary files /dev/null and b/example.csharp/addons/tiltfive/assets/T5-wand.glb differ diff --git a/example.csharp/addons/tiltfive/assets/T5-wand.glb.import b/example.csharp/addons/tiltfive/assets/T5-wand.glb.import new file mode 100644 index 0000000..d1de8b3 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/T5-wand.glb.import @@ -0,0 +1,43 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bggv3rg34lcs6" +path="res://.godot/imported/T5-wand.glb-63815c4ecd00240c691007ffae3a6ad5.scn" + +[deps] + +source_file="res://addons/tiltfive/assets/T5-wand.glb" +dest_files=["res://.godot/imported/T5-wand.glb-63815c4ecd00240c691007ffae3a6ad5.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=0.5 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={ +"materials": { +"Black": { +"use_external/enabled": true, +"use_external/path": "res://addons/tiltfive/assets/materials/Black.tres" +}, +"White": { +"use_external/enabled": true, +"use_external/path": "res://addons/tiltfive/assets/materials/White.tres" +} +} +} +gltf/embedded_image_handling=1 diff --git a/example.csharp/addons/tiltfive/assets/T5GlassesModel.tscn b/example.csharp/addons/tiltfive/assets/T5GlassesModel.tscn new file mode 100644 index 0000000..fbef794 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/T5GlassesModel.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://b1cd3jc00rhal"] + +[ext_resource type="PackedScene" uid="uid://c44ott7hdtkjs" path="res://addons/tiltfive/assets/T5-glasses.glb" id="1_22or3"] +[ext_resource type="Script" path="res://addons/tiltfive/assets/AutoScale.cs" id="2_mghk4"] + +[node name="T5-glasses" instance=ExtResource("1_22or3")] +script = ExtResource("2_mghk4") + +[node name="Cube" parent="." index="0"] +layers = 2 diff --git a/example.csharp/addons/tiltfive/assets/T5WandModel.tscn b/example.csharp/addons/tiltfive/assets/T5WandModel.tscn new file mode 100644 index 0000000..7bf98bc --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/T5WandModel.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://fipea8dbocg4"] + +[ext_resource type="PackedScene" uid="uid://bggv3rg34lcs6" path="res://addons/tiltfive/assets/T5-wand.glb" id="1_rqv18"] +[ext_resource type="Script" path="res://addons/tiltfive/assets/AutoScale.cs" id="2_m6gly"] + +[node name="T5-wand" instance=ExtResource("1_rqv18")] +script = ExtResource("2_m6gly") + +[node name="Roundcube_001" parent="." index="0"] +layers = 2 diff --git a/example.csharp/addons/tiltfive/assets/T5_border.glb b/example.csharp/addons/tiltfive/assets/T5_border.glb new file mode 100644 index 0000000..f630e65 Binary files /dev/null and b/example.csharp/addons/tiltfive/assets/T5_border.glb differ diff --git a/example.csharp/addons/tiltfive/assets/T5_border.glb.import b/example.csharp/addons/tiltfive/assets/T5_border.glb.import new file mode 100644 index 0000000..ec70317 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/T5_border.glb.import @@ -0,0 +1,39 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://s3wiiyeuos30" +path="res://.godot/imported/T5_border.glb-c296b67b5e5121f576eaa5a4e3abd8d7.scn" + +[deps] + +source_file="res://addons/tiltfive/assets/T5_border.glb" +dest_files=["res://.godot/imported/T5_border.glb-c296b67b5e5121f576eaa5a4e3abd8d7.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={ +"materials": { +"Boarder Material": { +"use_external/enabled": true, +"use_external/path": "res://addons/tiltfive/assets/materials/T5BorderMat.tres" +} +} +} +gltf/embedded_image_handling=0 diff --git a/example.csharp/addons/tiltfive/assets/T5_border_XE.glb b/example.csharp/addons/tiltfive/assets/T5_border_XE.glb new file mode 100644 index 0000000..f10e074 Binary files /dev/null and b/example.csharp/addons/tiltfive/assets/T5_border_XE.glb differ diff --git a/example.csharp/addons/tiltfive/assets/T5_border_XE.glb.import b/example.csharp/addons/tiltfive/assets/T5_border_XE.glb.import new file mode 100644 index 0000000..285d74f --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/T5_border_XE.glb.import @@ -0,0 +1,39 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bvi54sixhguyl" +path="res://.godot/imported/T5_border_XE.glb-8ae44d3d0d11e4f9febaa25582a4baec.scn" + +[deps] + +source_file="res://addons/tiltfive/assets/T5_border_XE.glb" +dest_files=["res://.godot/imported/T5_border_XE.glb-8ae44d3d0d11e4f9febaa25582a4baec.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={ +"materials": { +"Border Material": { +"use_external/enabled": true, +"use_external/path": "res://addons/tiltfive/assets/materials/T5BorderMat.tres" +} +} +} +gltf/embedded_image_handling=0 diff --git a/example.csharp/addons/tiltfive/assets/T5_border_XE_raised.glb b/example.csharp/addons/tiltfive/assets/T5_border_XE_raised.glb new file mode 100644 index 0000000..9f8392d Binary files /dev/null and b/example.csharp/addons/tiltfive/assets/T5_border_XE_raised.glb differ diff --git a/example.csharp/addons/tiltfive/assets/T5_border_XE_raised.glb.import b/example.csharp/addons/tiltfive/assets/T5_border_XE_raised.glb.import new file mode 100644 index 0000000..25a8715 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/T5_border_XE_raised.glb.import @@ -0,0 +1,39 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://cnjvy4x25r3ae" +path="res://.godot/imported/T5_border_XE_raised.glb-b835c3500317b519c096a0e5b7317a31.scn" + +[deps] + +source_file="res://addons/tiltfive/assets/T5_border_XE_raised.glb" +dest_files=["res://.godot/imported/T5_border_XE_raised.glb-b835c3500317b519c096a0e5b7317a31.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={ +"materials": { +"Border Material": { +"use_external/enabled": true, +"use_external/path": "res://addons/tiltfive/assets/materials/T5BorderMat.tres" +} +} +} +gltf/embedded_image_handling=0 diff --git a/example.csharp/addons/tiltfive/assets/board.svg b/example.csharp/addons/tiltfive/assets/board.svg new file mode 100644 index 0000000..98a3139 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/board.svg @@ -0,0 +1,50 @@ + + + + + + + + + + diff --git a/example.csharp/addons/tiltfive/assets/board.svg.import b/example.csharp/addons/tiltfive/assets/board.svg.import new file mode 100644 index 0000000..131f8eb --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/board.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1k4sti7mydwh" +path="res://.godot/imported/board.svg-ece10245621dedc440b30e3a84647ba9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/tiltfive/assets/board.svg" +dest_files=["res://.godot/imported/board.svg-ece10245621dedc440b30e3a84647ba9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/example.csharp/addons/tiltfive/assets/glasses.svg b/example.csharp/addons/tiltfive/assets/glasses.svg new file mode 100644 index 0000000..d127c68 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/glasses.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + diff --git a/example.csharp/addons/tiltfive/assets/glasses.svg.import b/example.csharp/addons/tiltfive/assets/glasses.svg.import new file mode 100644 index 0000000..fd92c68 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/glasses.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://63xpi03wffd8" +path="res://.godot/imported/glasses.svg-065e492e0e832aaa5619ccaad95c9012.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/tiltfive/assets/glasses.svg" +dest_files=["res://.godot/imported/glasses.svg-065e492e0e832aaa5619ccaad95c9012.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/example.csharp/addons/tiltfive/assets/materials/Black.tres b/example.csharp/addons/tiltfive/assets/materials/Black.tres new file mode 100644 index 0000000..68eb947 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/materials/Black.tres @@ -0,0 +1,6 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://di5e6v7te1n6w"] + +[resource] +resource_name = "Black" +albedo_color = Color(0.00392157, 0.00392157, 0.00392157, 1) +roughness = 0.693214 diff --git a/example.csharp/addons/tiltfive/assets/materials/T5BorderMat.tres b/example.csharp/addons/tiltfive/assets/materials/T5BorderMat.tres new file mode 100644 index 0000000..9cdce6d --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/materials/T5BorderMat.tres @@ -0,0 +1,6 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://df4vk6rpxs784"] + +[ext_resource type="Texture2D" uid="uid://b42436tkvdjtj" path="res://addons/tiltfive/assets/materials/T5_border_tex.png" id="1_d1o3y"] + +[resource] +albedo_texture = ExtResource("1_d1o3y") diff --git a/example.csharp/addons/tiltfive/assets/materials/T5_border_tex.png b/example.csharp/addons/tiltfive/assets/materials/T5_border_tex.png new file mode 100644 index 0000000..9e2ff18 Binary files /dev/null and b/example.csharp/addons/tiltfive/assets/materials/T5_border_tex.png differ diff --git a/example.csharp/addons/tiltfive/assets/materials/T5_border_tex.png.import b/example.csharp/addons/tiltfive/assets/materials/T5_border_tex.png.import new file mode 100644 index 0000000..9a22f78 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/materials/T5_border_tex.png.import @@ -0,0 +1,36 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b42436tkvdjtj" +path.s3tc="res://.godot/imported/T5_border_tex.png-f817ec4f59697917c96dd8c9cdc0b494.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} +generator_parameters={} + +[deps] + +source_file="res://addons/tiltfive/assets/materials/T5_border_tex.png" +dest_files=["res://.godot/imported/T5_border_tex.png-f817ec4f59697917c96dd8c9cdc0b494.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/example.csharp/addons/tiltfive/assets/materials/White.tres b/example.csharp/addons/tiltfive/assets/materials/White.tres new file mode 100644 index 0000000..5f922b6 --- /dev/null +++ b/example.csharp/addons/tiltfive/assets/materials/White.tres @@ -0,0 +1,6 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://rb4v56b7v6vr"] + +[resource] +resource_name = "White" +albedo_color = Color(0.905882, 0.905882, 0.905882, 1) +roughness = 0.693214 diff --git a/example.csharp/addons/tiltfive/plugin.cfg b/example.csharp/addons/tiltfive/plugin.cfg new file mode 100644 index 0000000..3d8028a --- /dev/null +++ b/example.csharp/addons/tiltfive/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="tiltfive" +description="A plugin for interfacing with the Tilt Five AR glasses" +author="Patrick Down" +version="1.0.0" +script="plugin.cs" diff --git a/example.csharp/addons/tiltfive/plugin.cs b/example.csharp/addons/tiltfive/plugin.cs new file mode 100644 index 0000000..8839ab2 --- /dev/null +++ b/example.csharp/addons/tiltfive/plugin.cs @@ -0,0 +1,43 @@ +#if TOOLS +using Godot; +using System; + +[Tool] +public partial class plugin : EditorPlugin +{ + static bool isInitialized = false; + + private void Setup() + { + if (!isInitialized) + { + AddAutoloadSingleton("T5Interface", "res://addons/tiltfive/T5Interface.cs"); + isInitialized = true; + } + + } + + public override void _EnterTree() + { + T5ProjectSettings.setup_properties(); + Setup(); + + } + + public override void _EnablePlugin() + { + base._EnablePlugin(); + Setup(); + } + + public override void _DisablePlugin() + { + base._EnablePlugin(); + if(isInitialized) + { + RemoveAutoloadSingleton("T5Interface"); + isInitialized = false; + } + } +} +#endif diff --git a/example.csharp/addons/tiltfive/scenes/T5CameraCS.cs b/example.csharp/addons/tiltfive/scenes/T5CameraCS.cs new file mode 100644 index 0000000..19569b7 --- /dev/null +++ b/example.csharp/addons/tiltfive/scenes/T5CameraCS.cs @@ -0,0 +1,30 @@ +using Godot; +using System; + +public partial class T5CameraCS : Camera3D +{ + + public StringName Tracker { + get { + return Get("tracker").As(); + } + set { + Set("tracker", value); + } + } + + public bool getIsActive() + { + return Call("get_is_active").AsBool(); + } + + public bool getHasTrackingData() + { + return Call("get_has_tracking_data").AsBool(); + } + + public XRPose getPose() + { + return Call("get_pose").As(); + } +} diff --git a/example.csharp/addons/tiltfive/scenes/T5ControllerCS.cs b/example.csharp/addons/tiltfive/scenes/T5ControllerCS.cs new file mode 100644 index 0000000..d193560 --- /dev/null +++ b/example.csharp/addons/tiltfive/scenes/T5ControllerCS.cs @@ -0,0 +1,32 @@ +using Godot; +using System; + +[Tool] +public partial class T5ControllerCS : T5NodeCS +{ + + public void TriggerHapticPulse(float amplitude, int duration) + { + Call("trigger_haptic_pulse", amplitude, duration); + } + + public bool IsButtonPressed(StringName name) + { + return Call("is_button_pressed", name).AsBool(); + } + + public Variant GetInput(StringName name) + { + return Call("get_input", name); + } + + public float GetFloat(StringName name) + { + return Call("get_float", name).As(); + } + + public Vector2 GetVector2(StringName name) + { + return Call("get_vector2", name).As(); + } +} diff --git a/example.csharp/addons/tiltfive/scenes/T5NodeCS.cs b/example.csharp/addons/tiltfive/scenes/T5NodeCS.cs new file mode 100644 index 0000000..e9c7a80 --- /dev/null +++ b/example.csharp/addons/tiltfive/scenes/T5NodeCS.cs @@ -0,0 +1,29 @@ +using Godot; +using System; + +public partial class T5NodeCS : Node3D +{ + public StringName Tracker { + get { + return Get("tracker").As(); + } + set { + Set("tracker", value); + } + } + + public bool getIsActive() + { + return Call("get_is_active").AsBool(); + } + + public bool getHasTrackingData() + { + return Call("get_has_tracking_data").AsBool(); + } + + public XRPose getPose() + { + return Call("get_pose").As(); + } +} diff --git a/example.csharp/addons/tiltfive/scenes/T5OriginCS.cs b/example.csharp/addons/tiltfive/scenes/T5OriginCS.cs new file mode 100644 index 0000000..c1a0c36 --- /dev/null +++ b/example.csharp/addons/tiltfive/scenes/T5OriginCS.cs @@ -0,0 +1,17 @@ +using Godot; +using System; + +public partial class T5OriginCS : Node3D +{ + public float GameboardScale + { + get + { + return Get("gameboard_scale").As(); + } + set + { + Set("gameboard_scale", value); + } + } +} diff --git a/example.csharp/addons/tiltfive/scenes/T5XRRig.cs b/example.csharp/addons/tiltfive/scenes/T5XRRig.cs new file mode 100644 index 0000000..c119d2a --- /dev/null +++ b/example.csharp/addons/tiltfive/scenes/T5XRRig.cs @@ -0,0 +1,32 @@ +using Godot; +using System; + +public partial class T5XRRig : SubViewport +{ + T5OriginCS origin; + T5CameraCS camera; + T5ControllerCS wand; + + public string GlassesID { get; set; } + public T5Interface.GameboardType GameboardType { get; set; } + public Aabb GameboardSize { get; set; } + public T5OriginCS Origin { get { return origin; } } + public T5CameraCS Camera{ get { return camera; } } + public T5ControllerCS Wand { get { return wand; } } + + // Called when the node enters the scene tree for the first time. + public override void _EnterTree() + { + base._EnterTree(); + + origin = GetNode("Origin"); + camera = GetNode("Origin/Camera"); + wand = GetNode("Origin/Wand_1"); + } + + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(double delta) + { + if(wand != null) wand.Visible = wand.getHasTrackingData(); + } +} diff --git a/example.csharp/addons/tiltfive/scenes/T5XRRig.tscn b/example.csharp/addons/tiltfive/scenes/T5XRRig.tscn new file mode 100644 index 0000000..82dcd91 --- /dev/null +++ b/example.csharp/addons/tiltfive/scenes/T5XRRig.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=5 format=3 uid="uid://dpbt52d0p5wjw"] + +[ext_resource type="Script" path="res://addons/tiltfive/scenes/T5XRRig.cs" id="1_rshxt"] +[ext_resource type="Script" path="res://addons/tiltfive/scenes/T5OriginCS.cs" id="2_jxn4b"] +[ext_resource type="Script" path="res://addons/tiltfive/scenes/T5CameraCS.cs" id="3_iaov5"] +[ext_resource type="Script" path="res://addons/tiltfive/scenes/T5ControllerCS.cs" id="3_olh3w"] + +[node name="T5XRRig" type="SubViewport"] +script = ExtResource("1_rshxt") + +[node name="Origin" type="T5Origin3D" parent="."] +script = ExtResource("2_jxn4b") + +[node name="Camera" type="T5Camera3D" parent="Origin"] +script = ExtResource("3_iaov5") + +[node name="Wand_1" type="T5Controller3D" parent="Origin"] +script = ExtResource("3_olh3w") diff --git a/example.csharp/addons/tiltfive/tiltfive.gdextension b/example.csharp/addons/tiltfive/tiltfive.gdextension new file mode 100644 index 0000000..96362ae --- /dev/null +++ b/example.csharp/addons/tiltfive/tiltfive.gdextension @@ -0,0 +1,22 @@ +[configuration] + +entry_symbol = "tiltfive_library_init" +compatibility_minimum = "4.1.2" + +[icons] +T5Gameboard = "res://addons/tiltfive/assets/board.svg" + +[libraries] + +windows.x86_64.debug = "res://addons/tiltfive/bin/libgdtiltfive.windows.template_debug.x86_64.dll" +windows.x86_64.release = "res://addons/tiltfive/bin/libgdtiltfive.windows.template_release.x86_64.dll" + +[dependencies] + +windows.x86_64.debug = { + "res://addons/tiltfive/bin/TiltFiveNative.dll" : "" +} +windows.x86_64.release = { + "res://addons/tiltfive/bin/TiltFiveNative.dll" : "" +} + diff --git a/example.csharp/icon.png b/example.csharp/icon.png new file mode 100644 index 0000000..8eb0859 Binary files /dev/null and b/example.csharp/icon.png differ diff --git a/example.csharp/icon.png.import b/example.csharp/icon.png.import new file mode 100644 index 0000000..b4f8c0e --- /dev/null +++ b/example.csharp/icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://byjyoxvrx6b0g" +path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/example.csharp/main.tscn b/example.csharp/main.tscn new file mode 100644 index 0000000..f83e535 --- /dev/null +++ b/example.csharp/main.tscn @@ -0,0 +1,74 @@ +[gd_scene load_steps=10 format=3 uid="uid://cc7yui6nxllyl"] + +[ext_resource type="Script" path="res://addons/tiltfive/T5Manager.cs" id="1_e8x2j"] +[ext_resource type="PackedScene" uid="uid://ba8h6c1mtb3h0" path="res://ExampleRig.tscn" id="2_vyjmk"] + +[sub_resource type="BoxMesh" id="BoxMesh_r54is"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_v64xu"] +albedo_color = Color(1, 0, 0, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ldtrq"] +albedo_color = Color(0.957524, 0.204212, 0, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3igwb"] +albedo_color = Color(5.0056e-06, 0.999087, 0.127906, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_lunuq"] +albedo_color = Color(0, 1, 0.584314, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ufftv"] +albedo_color = Color(0.0313726, 0, 1, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bbl8k"] +albedo_color = Color(0.45098, 0, 1, 1) + +[node name="Main" type="Node3D"] + +[node name="T5Manager" type="Node3D" parent="." node_paths=PackedStringArray("startLocation")] +script = ExtResource("1_e8x2j") +xrRigScene = ExtResource("2_vyjmk") +startLocation = NodePath("../T5Gameboard") + +[node name="T5Gameboard" type="T5Gameboard" parent="."] +content_scale = 16.0 + +[node name="Center" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_r54is") + +[node name="Positive X" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.32374, 0, 0) +mesh = SubResource("BoxMesh_r54is") +surface_material_override/0 = SubResource("StandardMaterial3D_v64xu") + +[node name="Negative X" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.2, 0, 0) +mesh = SubResource("BoxMesh_r54is") +surface_material_override/0 = SubResource("StandardMaterial3D_ldtrq") + +[node name="Positive Y" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0) +mesh = SubResource("BoxMesh_r54is") +surface_material_override/0 = SubResource("StandardMaterial3D_3igwb") + +[node name="Negative Y" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.2, 0) +mesh = SubResource("BoxMesh_r54is") +surface_material_override/0 = SubResource("StandardMaterial3D_lunuq") + +[node name="Positive Z" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.2) +mesh = SubResource("BoxMesh_r54is") +surface_material_override/0 = SubResource("StandardMaterial3D_ufftv") + +[node name="Positive Z2" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.2) +mesh = SubResource("BoxMesh_r54is") +surface_material_override/0 = SubResource("StandardMaterial3D_bbl8k") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.99099, 0.062492, 0.118462, -0.133934, 0.462383, 0.876506, 0, -0.884475, 0.466587, -5.18588, 2.90804, 2.01052) + +[node name="SpectatorCamera" type="Camera3D" parent="."] +transform = Transform3D(0.518176, -0.550674, 0.654409, -7.45058e-09, 0.765146, 0.643857, -0.855274, -0.333631, 0.396481, 8.04684, 5.20446, 5.82711) +cull_mask = 3 diff --git a/example.csharp/project.godot b/example.csharp/project.godot new file mode 100644 index 0000000..68a5fc7 --- /dev/null +++ b/example.csharp/project.godot @@ -0,0 +1,32 @@ +; 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] + +config/name="T5Example.csharp" +run/main_scene="res://main.tscn" +config/features=PackedStringArray("4.2", "Forward Plus") +config/icon="res://icon.png" + +[autoload] + +T5Interface="*res://addons/tiltfive/T5Interface.cs" + +[dotnet] + +project/assembly_name="example.csharp" + +[editor_plugins] + +enabled=PackedStringArray("res://addons/tiltfive/plugin.cfg") + +[xr] + +shaders/enabled=true diff --git a/example.gd/project.godot b/example.gd/project.godot index a59171d..3c486ef 100644 --- a/example.gd/project.godot +++ b/example.gd/project.godot @@ -1,16 +1,8 @@ -; 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] -config/name="TiltFiveGodot4" +config/name="T5Example.gd" run/main_scene="res://main.tscn" config/features=PackedStringArray("4.1") run/max_fps=60 diff --git a/extension/src/T5Origin3D.cpp b/extension/src/T5Origin3D.cpp index addbe79..fac12d0 100644 --- a/extension/src/T5Origin3D.cpp +++ b/extension/src/T5Origin3D.cpp @@ -2,6 +2,7 @@ #include using godot::ClassDB; +using godot::MethodInfo; using godot::PropertyInfo; using godot::D_METHOD; using godot::Variant; @@ -13,6 +14,9 @@ void T5Origin3D::_bind_methods() { // Properties. ClassDB::add_property("T5Origin3D", PropertyInfo(Variant::FLOAT, "gameboard_scale"), "set_gameboard_scale", "get_gameboard_scale"); + + // Signals + ADD_SIGNAL(MethodInfo("gameboard_scale_changed", PropertyInfo(Variant::FLOAT, "scale"))); } @@ -22,4 +26,5 @@ real_t T5Origin3D::get_gameboard_scale() { void T5Origin3D::set_gameboard_scale(real_t scale) { _scale = scale; + emit_signal("gameboard_scale_changed", _scale); }