From daa59c9fbb89739ce2de46be87805f901d04658a Mon Sep 17 00:00:00 2001 From: art0007i Date: Wed, 24 Jan 2024 14:10:52 +0100 Subject: [PATCH 1/3] add vive battery node --- .../Bindings/Devices/ViveTrackerBattery.cs | 95 +++++++++++++++++++ ProtoFlux/Devices/ViveTrackerBattery.cs | 54 +++++++++++ UserComponents/ViveTrackerProxy.cs | 39 ++++++++ 3 files changed, 188 insertions(+) create mode 100644 ProtoFlux/Bindings/Devices/ViveTrackerBattery.cs create mode 100644 ProtoFlux/Devices/ViveTrackerBattery.cs create mode 100644 UserComponents/ViveTrackerProxy.cs diff --git a/ProtoFlux/Bindings/Devices/ViveTrackerBattery.cs b/ProtoFlux/Bindings/Devices/ViveTrackerBattery.cs new file mode 100644 index 0000000..1341291 --- /dev/null +++ b/ProtoFlux/Bindings/Devices/ViveTrackerBattery.cs @@ -0,0 +1,95 @@ +using System; +using FrooxEngine; +using FrooxEngine.ProtoFlux; +using FrooxEngine.ProtoFlux.Runtimes.Execution; +using ProtoFlux.Core; + + +[Category(new string[] { "ProtoFlux/Runtimes/Execution/Nodes/Devices" })] +public class ViveTrackerBattery : VoidNode +{ + public readonly SyncRef> User; + + public readonly SyncRef> BodyNode; + + public readonly NodeValueOutput IsActive; + + public readonly NodeValueOutput BatteryLevel; + + public readonly NodeValueOutput IsBatteryCharging; + + public override Type NodeType => typeof(ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Input.ViveTrackerBattery); + + public ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Input.ViveTrackerBattery TypedNodeInstance { get; private set; } + + public override INode NodeInstance => TypedNodeInstance; + + public override int NodeInputCount => base.NodeInputCount + 2; + + public override int NodeOutputCount => base.NodeOutputCount + 3; + + public override N Instantiate() + { + if (TypedNodeInstance != null) + { + throw new InvalidOperationException("Node has already been instantiated"); + } + ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Input.ViveTrackerBattery viveTrackerBattery = (TypedNodeInstance = new ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Input.ViveTrackerBattery()); + return viveTrackerBattery as N; + } + + protected override void AssociateInstanceInternal(INode node) + { + if (node is ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Input.ViveTrackerBattery typedNodeInstance) + { + TypedNodeInstance = typedNodeInstance; + return; + } + throw new ArgumentException("Node instance is not of type " + typeof(ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Input.ViveTrackerBattery)); + } + + public override void ClearInstance() + { + TypedNodeInstance = null; + } + + protected override ISyncRef GetInputInternal(ref int index) + { + ISyncRef inputInternal = base.GetInputInternal(ref index); + if (inputInternal != null) + { + return inputInternal; + } + switch (index) + { + case 0: + return User; + case 1: + return BodyNode; + default: + index -= 2; + return null; + } + } + + protected override INodeOutput GetOutputInternal(ref int index) + { + INodeOutput outputInternal = base.GetOutputInternal(ref index); + if (outputInternal != null) + { + return outputInternal; + } + switch (index) + { + case 0: + return IsActive; + case 1: + return BatteryLevel; + case 2: + return IsBatteryCharging; + default: + index -= 3; + return null; + } + } +} \ No newline at end of file diff --git a/ProtoFlux/Devices/ViveTrackerBattery.cs b/ProtoFlux/Devices/ViveTrackerBattery.cs new file mode 100644 index 0000000..2fedb3a --- /dev/null +++ b/ProtoFlux/Devices/ViveTrackerBattery.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FrooxEngine.ProtoFlux; +using FrooxEngine; +using ProtoFlux.Core; +using ProtoFlux.Runtimes.Execution; +using Obsidian; + + +namespace ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Input; +[NodeCategory("Devices")] +public class ViveTrackerBattery : VoidNode +{ + public ObjectArgument User; + public ValueArgument BodyNode; + + [ContinuouslyChanging] + public readonly ValueOutput IsActive; + + [ContinuouslyChanging] + public readonly ValueOutput BatteryLevel; + + [ContinuouslyChanging] + public readonly ValueOutput IsBatteryCharging; + + protected override void ComputeOutputs(FrooxEngineContext context) + { + User user = 0.ReadObject(context); + if (user != null && user.IsRemoved) + { + user = null; + } + var node = 1.ReadValue(context); + var trackerDevice = user?.GetComponent(p => p.TrackerBodyNode == node); + if (trackerDevice == null && user != null) + { + trackerDevice = user.AttachComponent(); + trackerDevice.TrackerBodyNode.Value = node; + } + IsActive.Write(trackerDevice?.IsTrackerActive.Value ?? false, context); + BatteryLevel.Write(trackerDevice?.BatteryLevel.Target?.Value ?? (-1f), context); + IsBatteryCharging.Write((trackerDevice?.BatteryCharging.Target?.Value).GetValueOrDefault(), context); + } + + public ViveTrackerBattery() + { + IsActive = new ValueOutput(this); + BatteryLevel = new ValueOutput(this); + IsBatteryCharging = new ValueOutput(this); + } +} diff --git a/UserComponents/ViveTrackerProxy.cs b/UserComponents/ViveTrackerProxy.cs new file mode 100644 index 0000000..85b4b4e --- /dev/null +++ b/UserComponents/ViveTrackerProxy.cs @@ -0,0 +1,39 @@ +using System.Linq; +using FrooxEngine; + +namespace Obsidian; + +public class ViveTrackerProxy : UserComponent +{ + public readonly Sync TrackerBodyNode; + + public readonly Sync IsTrackerActive; + + public readonly SyncRef> BatteryLevel; + + public readonly SyncRef> BatteryCharging; + + private ViveTracker _currentTracker; + + protected override void OnCommonUpdate() + { + if (base.User.IsLocalUser) + { + ViveTracker device = InputInterface.GetDevices().FirstOrDefault(t => t.CorrespondingBodyNode == TrackerBodyNode.Value); + if (device != _currentTracker) + { + TrackerBodyNode.Value = device?.CorrespondingBodyNode ?? BodyNode.NONE; + BatteryLevel.Target = device?.BatteryLevel.GetStream(base.World); + BatteryCharging.Target = device?.BatteryCharging.GetStream(base.World); + IsTrackerActive.Value = device != null; + _currentTracker = device; + } + } + } + + protected override void OnDispose() + { + base.OnDispose(); + _currentTracker = null; + } +} From 784661148e8b05aff1b0f2c7289d9a2107199381 Mon Sep 17 00:00:00 2001 From: art0007i Date: Wed, 24 Jan 2024 14:14:43 +0100 Subject: [PATCH 2/3] remove that broken node --- .../OpenVR/Tracker/TrackerBatteryBase.cs | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 ProtoFlux/Hardware/OpenVR/Tracker/TrackerBatteryBase.cs diff --git a/ProtoFlux/Hardware/OpenVR/Tracker/TrackerBatteryBase.cs b/ProtoFlux/Hardware/OpenVR/Tracker/TrackerBatteryBase.cs deleted file mode 100644 index 3f5816d..0000000 --- a/ProtoFlux/Hardware/OpenVR/Tracker/TrackerBatteryBase.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using FrooxEngine; -using FrooxEngine.ProtoFlux; -using ProtoFlux.Core; -using ProtoFlux.Runtimes.Execution; - -namespace Obsidian -{ - public abstract class TrackerBatteryBase : VoidNode - { - public ObjectArgument User; - public readonly ValueOutput BatteryLevel; - public readonly ValueOutput IsBatteryCharging; - - private ViveTracker _lastTracker; - private SyncRef> _batteryLevelStream; - private SyncRef> _batteryChargingStream; - - protected abstract ViveTracker GetViveTracker(); - - protected override void ComputeOutputs(FrooxEngineContext context) - { - User user = 0.ReadObject(context); - if (user != null && user.IsRemoved) - { - user = null; - } - ViveTracker device = GetViveTracker(); - if (device != _lastTracker) - { - _batteryLevelStream.Target = device?.BatteryLevel.GetStream(context.World); - _batteryChargingStream.Target = device?.BatteryCharging.GetStream(context.World); - _lastTracker = device; - } - - BatteryLevel.Write(_batteryLevelStream.Target?.Value ?? -1f, context); - IsBatteryCharging.Write(_batteryChargingStream.Target?.Value ?? false, context); - } - - public TrackerBatteryBase() - { - BatteryLevel = new ValueOutput(this); - IsBatteryCharging = new ValueOutput(this); - } - } -} From 3ab330dc4f4b6a8a9b01b3a082b7711ceda681ad Mon Sep 17 00:00:00 2001 From: art0007i Date: Wed, 24 Jan 2024 14:19:32 +0100 Subject: [PATCH 3/3] move binding to correct folder --- {ProtoFlux/Bindings => Bindings}/Devices/ViveTrackerBattery.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {ProtoFlux/Bindings => Bindings}/Devices/ViveTrackerBattery.cs (100%) diff --git a/ProtoFlux/Bindings/Devices/ViveTrackerBattery.cs b/Bindings/Devices/ViveTrackerBattery.cs similarity index 100% rename from ProtoFlux/Bindings/Devices/ViveTrackerBattery.cs rename to Bindings/Devices/ViveTrackerBattery.cs