From f8e497b6874b4107f25d57b2adab7ff5e88f4254 Mon Sep 17 00:00:00 2001 From: xLinka Date: Sat, 4 May 2024 12:14:03 +0100 Subject: [PATCH] refactor and imunode based on component --- .../ProtoFlux/Avatar/AvatarRootSlot.cs | 29 ----- .../ProtoFlux/Devices/ImuDataNode .cs | 112 ++++++++++++++++++ .../ProtoFlux/Users/Avatar/AvatarRootSlot.cs | 17 ++- 3 files changed, 124 insertions(+), 34 deletions(-) delete mode 100644 ProjectObsidian/ProtoFlux/Avatar/AvatarRootSlot.cs create mode 100644 ProjectObsidian/ProtoFlux/Devices/ImuDataNode .cs diff --git a/ProjectObsidian/ProtoFlux/Avatar/AvatarRootSlot.cs b/ProjectObsidian/ProtoFlux/Avatar/AvatarRootSlot.cs deleted file mode 100644 index 34d810f..0000000 --- a/ProjectObsidian/ProtoFlux/Avatar/AvatarRootSlot.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using FrooxEngine; -using FrooxEngine.CommonAvatar; -using ProtoFlux.Core; -using ProtoFlux.Runtimes.Execution; - -namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Users.Avatar -{ - [ContinuouslyChanging] - [NodeCategory("Obsidian/Avatar")] - public class AvatarRootSlot : ObjectFunctionNode - { - public readonly ObjectInput User; - - protected override Slot Compute(ExecutionContext context) - { - User user = User.Evaluate(context); - if (user == null) return null; - - Slot slot = user.Root.Slot; - List list = Pool.BorrowList(); - slot.GetFirstDirectComponentsInChildren(list); - Slot avatarRoot = list.FirstOrDefault()?.Slot; - Pool.Return(ref list); - - return avatarRoot; - } - } -} diff --git a/ProjectObsidian/ProtoFlux/Devices/ImuDataNode .cs b/ProjectObsidian/ProtoFlux/Devices/ImuDataNode .cs new file mode 100644 index 0000000..9c27179 --- /dev/null +++ b/ProjectObsidian/ProtoFlux/Devices/ImuDataNode .cs @@ -0,0 +1,112 @@ +using System; +using System.Runtime.InteropServices; +using FrooxEngine; +using FrooxEngine.ProtoFlux; +using ProtoFlux.Core; +using Valve.VR; +using ProtoFlux.Runtimes.Execution; +using Elements.Core; +using System.Threading.Tasks; + + + +namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Devices +{ + [NodeCategory("Obsidian/Devices")] + public class ImuDataNode : AsyncActionNode + { + public ObjectInput SimulatingUser; + public ObjectInput Path; + public ValueInput Simulate; + + public ValueOutput SampleTime; + public ValueOutput VAccel; + public ValueOutput VGyro; + public ValueOutput OffScaleFlags; + + public AsyncCall OnSimulationStart; + public Continuation OnDataUpdated; + public Continuation OnError; + + private ulong _buffer; + private string _previousPath; + + public ImuDataNode() + { + SampleTime = new ValueOutput(this); + VAccel = new ValueOutput(this); + VGyro = new ValueOutput(this); + OffScaleFlags = new ValueOutput(this); + } + + protected override async Task RunAsync(FrooxEngineContext context) + { + User user = SimulatingUser.Evaluate(context); + bool simulate = Simulate.Evaluate(context); + string path = Path.Evaluate(context); + + if (!simulate || user != context.LocalUser || string.IsNullOrEmpty(path)) + { + CloseBuffer(); + return OnError.Target; + } + + await OnSimulationStart.ExecuteAsync(context); + + if (_buffer == 0 || _previousPath != path) + { + CloseBuffer(); + if (!OpenBuffer(path)) + { + return OnError.Target; + } + } + + ReadImuData(context); + return OnDataUpdated.Target; + } + + private bool OpenBuffer(string path) + { + unsafe + { + ulong buffer = default; + var errorCode = OpenVR.IOBuffer.Open(path, EIOBufferMode.Read, (uint)sizeof(ImuSample_t), 0u, ref buffer); + if (errorCode == EIOBufferError.IOBuffer_Success) + { + _buffer = buffer; + _previousPath = path; + return true; + } + return false; + } + } + + private void ReadImuData(FrooxEngineContext context) + { + unsafe + { + var punRead = 0u; + var imuSample_t = default(ImuSample_t); + var error = OpenVR.IOBuffer.Read(_buffer, (IntPtr)(&imuSample_t), (uint)sizeof(ImuSample_t), ref punRead); + + if (error == EIOBufferError.IOBuffer_Success && punRead == sizeof(ImuSample_t)) + { + // Writing each IMU data point with context to ensure correct synchronization and data handling + SampleTime.Write(imuSample_t.fSampleTime, context); + VAccel.Write(new double3(imuSample_t.vAccel.v0, imuSample_t.vAccel.v1, imuSample_t.vAccel.v2), context); + VGyro.Write(new double3(imuSample_t.vGyro.v0, imuSample_t.vGyro.v1, imuSample_t.vGyro.v2), context); + OffScaleFlags.Write((Imu_OffScaleFlags)imuSample_t.unOffScaleFlags, context); + } + } + } + + private void CloseBuffer() + { + if (_buffer == 0) return; + OpenVR.IOBuffer.Close(_buffer); + _buffer = 0; + } + } + +} diff --git a/ProjectObsidian/ProtoFlux/Users/Avatar/AvatarRootSlot.cs b/ProjectObsidian/ProtoFlux/Users/Avatar/AvatarRootSlot.cs index e186e32..3b885bf 100644 --- a/ProjectObsidian/ProtoFlux/Users/Avatar/AvatarRootSlot.cs +++ b/ProjectObsidian/ProtoFlux/Users/Avatar/AvatarRootSlot.cs @@ -1,13 +1,15 @@ using System.Collections.Generic; +using System.Linq; +using Elements.Core; using FrooxEngine; using FrooxEngine.CommonAvatar; using ProtoFlux.Core; using ProtoFlux.Runtimes.Execution; -namespace ProtoFlux.Users.Avatar +namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Users.Avatar { [ContinuouslyChanging] - [NodeCategory("ProtoFlux/Obsidian/Avatar")] + [NodeCategory("Obsidian/Avatar")] public class AvatarRootSlot : ObjectFunctionNode { public readonly ObjectInput User; @@ -15,10 +17,15 @@ public class AvatarRootSlot : ObjectFunctionNode protected override Slot Compute(ExecutionContext context) { User user = User.Evaluate(context); + if (user == null) return null; + Slot slot = user.Root.Slot; - List list = new List(); + List list = Pool.BorrowList(); slot.GetFirstDirectComponentsInChildren(list); - return user == null || list.Count == 0 ? null : list[0].Slot; + Slot avatarRoot = list.FirstOrDefault()?.Slot; + Pool.Return(ref list); + + return avatarRoot; } } -} \ No newline at end of file +}