From de86007e38819853b6973698eb464ad821cb6534 Mon Sep 17 00:00:00 2001 From: frozenreflex Date: Sun, 21 Apr 2024 20:45:23 -0500 Subject: [PATCH 1/5] Fix bindings some more, IMU as a component progress --- .../BindingGenerator.cs | 4 +- ProjectObsidian/Components/Users/ImuInfo.cs | 106 ++++++++++ .../ProtoFlux/Devices/OpenVR/ImuReader.cs | 184 ++++++++++++++++++ 3 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 ProjectObsidian/Components/Users/ImuInfo.cs create mode 100644 ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs diff --git a/ProjectObsidian.SourceGenerators/BindingGenerator.cs b/ProjectObsidian.SourceGenerators/BindingGenerator.cs index fe1b860..fea7429 100644 --- a/ProjectObsidian.SourceGenerators/BindingGenerator.cs +++ b/ProjectObsidian.SourceGenerators/BindingGenerator.cs @@ -46,7 +46,7 @@ private class OrderedCount private readonly string MethodReturnType; public string CountOverride => VariableNames.Count == 0 ? "" - : $" public override int {CountVariableName} => base.{CountVariableName} + {VariableNames.Count};"; + : $" public override int {CountVariableName} => base.{CountVariableName} + {VariableNames.Count};\n"; public void Add(string value) => VariableNames.Add(value); @@ -117,7 +117,7 @@ public OrderedCount(string countVariableName, string methodName, string methodRe private readonly OrderedCount _inputCount = new("NodeInputCount", "GetInputInternal", "ISyncRef"); private readonly OrderedCount _outputCount = new("NodeOutputCount", "GetOutputInternal", "INodeOutput"); private readonly OrderedCount _impulseCount = new("NodeImpulseCount", "GetImpulseInternal", "ISyncRef"); - private readonly OrderedCount _operationCount = new("NodeImpulseCount", "GetImpulseInternal", "INodeOperation"); + private readonly OrderedCount _operationCount = new("NodeOperationCount", "GetOperationInternal", "INodeOperation"); private readonly OrderedCount _inputListCount = new("NodeInputListCount", "GetInputListInternal", "ISyncList"); private readonly OrderedCount _outputListCount = new("NodeOutputListCount", "GetOutputListInternal", "ISyncList"); diff --git a/ProjectObsidian/Components/Users/ImuInfo.cs b/ProjectObsidian/Components/Users/ImuInfo.cs new file mode 100644 index 0000000..67e471a --- /dev/null +++ b/ProjectObsidian/Components/Users/ImuInfo.cs @@ -0,0 +1,106 @@ +using System; +using System.Runtime.InteropServices; +using Elements.Core; +using Valve.VR; + +namespace FrooxEngine; + +public enum ImuErrorCode : int +{ + None = 0, + AlreadyOpened = 1, + AlreadyClosed = 2, + UnknownException = 3, + PathIsNullOrEmpty = 4, + IOBuffer_OperationFailed = 100, + IOBuffer_InvalidHandle = 101, + IOBuffer_InvalidArgument = 102, + IOBuffer_PathExists = 103, + IOBuffer_PathDoesNotExist = 104, + IOBuffer_Permission = 105 +} + +[Category("Obsidian/Devices")] +public class ImuInfo : Component +{ + public readonly Sync Simulate; + public readonly SyncRef SimulatingUser; + public readonly Sync Path; + public readonly Sync Connected; + public readonly Sync SampleTime; + public readonly Sync VAccel; + public readonly Sync VGyro; + public readonly Sync OffScaleFlags; + private ulong _buffer; + private string _previousPath; + private bool _previousSimulating; + private static readonly int ImuSampleSize = Marshal.SizeOf(); + + ~ImuInfo() + { + CloseBuffer(); + } + + private void CloseBuffer() + { + if (_buffer == 0) return; + OpenVR.IOBuffer.Close(_buffer); + _previousPath = null; + _buffer = 0; + Connected.Value = false; + } + protected override void OnCommonUpdate() + { + base.OnCommonUpdate(); + + if (Simulate.Value && LocalUser == SimulatingUser.Target) + { + if (!LocalUser.VR_Active) CloseBuffer(); //we aren't in VR, we probably shouldn't be sampling + else if (_buffer == 0 || _previousPath != Path.Value) + { + CloseBuffer(); + ulong buffer = default; + //TODO: make this not run every frame if it fails + var errorCode = OpenVR.IOBuffer.Open(Path.Value, EIOBufferMode.Read, sizeof(ImuErrorCode), 0u, ref buffer); + UniLog.Log($"{buffer}, {errorCode.ToString()}"); + if (errorCode == EIOBufferError.IOBuffer_Success) + { + _buffer = buffer; + _previousPath = Path.Value; + } + } + if (_buffer != 0) + { + unsafe + { + var punRead = 0u; + var imuSample_t = default(ImuSample_t); + + var error = OpenVR.IOBuffer.Read(_buffer, (IntPtr)(&imuSample_t), (uint)ImuSampleSize, ref punRead); + + if (error == EIOBufferError.IOBuffer_Success && punRead == ImuSampleSize) + { + var fSampleTime = imuSample_t.fSampleTime; + var vAccel = new double3(imuSample_t.vAccel.v0, imuSample_t.vAccel.v1, imuSample_t.vAccel.v2); + var vGyro = new double3(imuSample_t.vGyro.v0, imuSample_t.vGyro.v1, imuSample_t.vGyro.v2); + var flags = (Imu_OffScaleFlags)imuSample_t.unOffScaleFlags; + + SampleTime.Value = fSampleTime; + VAccel.Value = vAccel; + VGyro.Value = vGyro; + OffScaleFlags.Value = flags; + } + } + } + } + else + { + CloseBuffer(); + } + + if (LocalUser != SimulatingUser.Target) return; + + var connectedValue = _buffer != 0; + if (connectedValue != Connected.Value) Connected.Value = connectedValue; + } +} \ No newline at end of file diff --git a/ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs b/ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs new file mode 100644 index 0000000..6bfd6a6 --- /dev/null +++ b/ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs @@ -0,0 +1,184 @@ +/* +using System; +using System.Threading; +using System.Threading.Tasks; +using Elements.Core; +using FrooxEngine.ProtoFlux; +using ProtoFlux.Core; +using ProtoFlux.Runtimes.Execution; +using Valve.VR; + +namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian; + +public enum ImuErrorCode : int +{ + None = 0, + AlreadyOpened = 1, + AlreadyClosed = 2, + UnknownException = 3, + PathIsNullOrEmpty = 4, + IOBuffer_OperationFailed = 100, + IOBuffer_InvalidHandle = 101, + IOBuffer_InvalidArgument = 102, + IOBuffer_PathExists = 103, + IOBuffer_PathDoesNotExist = 104, + IOBuffer_Permission = 105 +} + +[NodeCategory("Obsidian/Devices/OpenVR")] +public class ImuReader : AsyncActionNode +{ + public ObjectInput DevicePath; + [PossibleContinuations("OnClosed", "OnFail")] + + //public readonly Operation Close; + + public AsyncCall OnOpened; + + public Continuation OnClosed; + + public Continuation OnFail; + + public AsyncCall OnData; + + public readonly ValueOutput IsOpened; + + public readonly ValueOutput FailReason; + + [ContinuouslyChanging] + public readonly ValueOutput FSampleTime; + + [ContinuouslyChanging] + public readonly ValueOutput VAccel; + + [ContinuouslyChanging] + public readonly ValueOutput VGyro; + + [ContinuouslyChanging] + public readonly ValueOutput UnOffScaleFlags; + + private ulong _pulBuffer; + + private Thread _thread; + + protected override async Task RunAsync(FrooxEngineContext context) + { + var path = DevicePath.Evaluate(context); + if (string.IsNullOrEmpty(path)) return Fail(ImuErrorCode.PathIsNullOrEmpty, context); + + var errorCode = OpenVR.IOBuffer.Open(path, EIOBufferMode.Read, sizeof(int), 0u, ref _pulBuffer); + + if (errorCode != EIOBufferError.IOBuffer_Success) return Fail((ImuErrorCode)errorCode, context); + + await OnOpened.ExecuteAsync(context); + + _thread = new Thread((ThreadStart)delegate + { + ReadLoopAsync(context); + }); + _thread.Start(); + IsOpened.Write(value: true, context); + + return OnOpened.Target; + } + + public IOperation DoClose(FrooxEngineContext context) + { + if (_pulBuffer == 0) return Fail(ImuErrorCode.AlreadyClosed, context); + + var eIOBufferError = OpenVR.IOBuffer.Close(_pulBuffer); + if (eIOBufferError == EIOBufferError.IOBuffer_Success) + { + IsOpened.Write(value: false, context); + _pulBuffer = 0uL; + if (_thread != null) + { + _thread.Abort(); + _thread = null; + } + return OnClosed.Target; + } + + FailReason.Write((ImuErrorCode)eIOBufferError, context); + return OnClosed.Target; + } + + ~ImuReader() + { + if (_thread != null) + { + _thread.Abort(); + _thread = null; + } + if (_pulBuffer != 0) + { + OpenVR.IOBuffer.Close(_pulBuffer); + _pulBuffer = 0uL; + } + } + + private unsafe void ReadLoopAsync(FrooxEngineContext context) + { + Task.Run(delegate + { + while (true) + { + var punRead = 0u; + var imuSample_t = default(ImuSample_t); + try + { + if (OpenVR.IOBuffer.Read(_pulBuffer, (IntPtr)(&imuSample_t), (uint)sizeof(ImuSample_t), ref punRead) == EIOBufferError.IOBuffer_Success && punRead == sizeof(ImuSample_t)) + { + var fSampleTime = imuSample_t.fSampleTime; + var vAccel = new double3(imuSample_t.vAccel.v0, imuSample_t.vAccel.v1, imuSample_t.vAccel.v2); + var vGyro = new double3(imuSample_t.vGyro.v0, imuSample_t.vGyro.v1, imuSample_t.vGyro.v2); + var flags = (Imu_OffScaleFlags)imuSample_t.unOffScaleFlags; + OnData.ExecuteAsync(context); + context.World.RunSynchronously(delegate + { + FSampleTime.Write(fSampleTime, context); + VAccel.Write(vAccel, context); + VGyro.Write(vGyro, context); + UnOffScaleFlags.Write(flags, context); + }); + } + else Thread.Sleep(10); + } + catch (Exception ex) + { + break; + } + } + if (_pulBuffer != 0) + { + OpenVR.IOBuffer.Close(_pulBuffer); + _pulBuffer = 0uL; + } + context.World.RunSynchronously(delegate + { + IsOpened.Write(value: false, context); + FailReason.Write(ImuErrorCode.UnknownException, context); + }); + }); + } + + public ImuReader() + { + //Close = new Operation(this, 0); + IsOpened = new ValueOutput(this); + FailReason = new ValueOutput(this); + FSampleTime = new ValueOutput(this); + VAccel = new ValueOutput(this); + VGyro = new ValueOutput(this); + UnOffScaleFlags = new ValueOutput(this); + } + + + private IOperation Fail(ImuErrorCode error, FrooxEngineContext context) + { + IsOpened.Write(value: false, context); + FailReason.Write(error, context); + return OnFail.Target; + } +} +*/ \ No newline at end of file From 5d415931b62ee1d9f6078e2bca68ec5667214ebf Mon Sep 17 00:00:00 2001 From: frozenreflex Date: Tue, 23 Apr 2024 18:36:11 -0500 Subject: [PATCH 2/5] Fix sizeof --- ProjectObsidian/Components/Users/ImuInfo.cs | 24 +++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/ProjectObsidian/Components/Users/ImuInfo.cs b/ProjectObsidian/Components/Users/ImuInfo.cs index 67e471a..d1ddb59 100644 --- a/ProjectObsidian/Components/Users/ImuInfo.cs +++ b/ProjectObsidian/Components/Users/ImuInfo.cs @@ -5,7 +5,7 @@ namespace FrooxEngine; -public enum ImuErrorCode : int +public enum ImuErrorCode { None = 0, AlreadyOpened = 1, @@ -34,7 +34,6 @@ public class ImuInfo : Component private ulong _buffer; private string _previousPath; private bool _previousSimulating; - private static readonly int ImuSampleSize = Marshal.SizeOf(); ~ImuInfo() { @@ -59,14 +58,17 @@ protected override void OnCommonUpdate() else if (_buffer == 0 || _previousPath != Path.Value) { CloseBuffer(); - ulong buffer = default; - //TODO: make this not run every frame if it fails - var errorCode = OpenVR.IOBuffer.Open(Path.Value, EIOBufferMode.Read, sizeof(ImuErrorCode), 0u, ref buffer); - UniLog.Log($"{buffer}, {errorCode.ToString()}"); - if (errorCode == EIOBufferError.IOBuffer_Success) + unsafe { - _buffer = buffer; - _previousPath = Path.Value; + ulong buffer = default; + //TODO: make this not run every frame if it fails + var errorCode = OpenVR.IOBuffer.Open(Path.Value, EIOBufferMode.Read, (uint)sizeof(ImuSample_t), 0u, ref buffer); + UniLog.Log($"{buffer}, {errorCode.ToString()}"); + if (errorCode == EIOBufferError.IOBuffer_Success) + { + _buffer = buffer; + _previousPath = Path.Value; + } } } if (_buffer != 0) @@ -76,9 +78,9 @@ protected override void OnCommonUpdate() var punRead = 0u; var imuSample_t = default(ImuSample_t); - var error = OpenVR.IOBuffer.Read(_buffer, (IntPtr)(&imuSample_t), (uint)ImuSampleSize, ref punRead); + var error = OpenVR.IOBuffer.Read(_buffer, (IntPtr)(&imuSample_t), (uint)sizeof(ImuSample_t), ref punRead); - if (error == EIOBufferError.IOBuffer_Success && punRead == ImuSampleSize) + if (error == EIOBufferError.IOBuffer_Success && punRead == sizeof(ImuSample_t)) { var fSampleTime = imuSample_t.fSampleTime; var vAccel = new double3(imuSample_t.vAccel.v0, imuSample_t.vAccel.v1, imuSample_t.vAccel.v2); From 36b9309f7a37b95f513d30a752ff2e881f96aeb9 Mon Sep 17 00:00:00 2001 From: frozenreflex Date: Wed, 24 Apr 2024 22:12:44 -0500 Subject: [PATCH 3/5] More error checking, remove unused code --- ProjectObsidian/Components/Users/ImuInfo.cs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/ProjectObsidian/Components/Users/ImuInfo.cs b/ProjectObsidian/Components/Users/ImuInfo.cs index d1ddb59..306f084 100644 --- a/ProjectObsidian/Components/Users/ImuInfo.cs +++ b/ProjectObsidian/Components/Users/ImuInfo.cs @@ -5,21 +5,6 @@ namespace FrooxEngine; -public enum ImuErrorCode -{ - None = 0, - AlreadyOpened = 1, - AlreadyClosed = 2, - UnknownException = 3, - PathIsNullOrEmpty = 4, - IOBuffer_OperationFailed = 100, - IOBuffer_InvalidHandle = 101, - IOBuffer_InvalidArgument = 102, - IOBuffer_PathExists = 103, - IOBuffer_PathDoesNotExist = 104, - IOBuffer_Permission = 105 -} - [Category("Obsidian/Devices")] public class ImuInfo : Component { @@ -54,7 +39,7 @@ protected override void OnCommonUpdate() if (Simulate.Value && LocalUser == SimulatingUser.Target) { - if (!LocalUser.VR_Active) CloseBuffer(); //we aren't in VR, we probably shouldn't be sampling + if (!LocalUser.VR_Active || OpenVR.IOBuffer is null || string.IsNullOrEmpty(Path.Value)) CloseBuffer(); else if (_buffer == 0 || _previousPath != Path.Value) { CloseBuffer(); From c7a3887c62877594b62a66af77a190238aa5f238 Mon Sep 17 00:00:00 2001 From: frozenreflex Date: Wed, 1 May 2024 15:11:10 -0500 Subject: [PATCH 4/5] Binding safety --- .../BindingGenerator.cs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ProjectObsidian.SourceGenerators/BindingGenerator.cs b/ProjectObsidian.SourceGenerators/BindingGenerator.cs index fea7429..6c591f4 100644 --- a/ProjectObsidian.SourceGenerators/BindingGenerator.cs +++ b/ProjectObsidian.SourceGenerators/BindingGenerator.cs @@ -147,7 +147,7 @@ public string Result namespace {BindingPrefix}{_currentNameSpace}; [Category(new string[] {{""ProtoFlux/Runtimes/Execution/Nodes/{_category}""}})] -public partial class {_fullName} : {_baseType} +public partial class {_fullName} : global::FrooxEngine.ProtoFlux.Runtimes.Execution.{_baseType} {{ {Declarations} {_nodeNameOverride} @@ -203,37 +203,37 @@ public override void VisitFieldDeclaration(FieldDeclarationSyntax node) var name = node.Declaration.Variables.First().ToString(); //inputs - TypedFieldDetection(type, name, "ObjectInput", "SyncRef>", _inputCount); - TypedFieldDetection(type, name, "ObjectArgument", "SyncRef>", _inputCount); - TypedFieldDetection(type, name, "ValueInput", "SyncRef>", _inputCount); - TypedFieldDetection(type, name, "ValueArgument", "SyncRef>", _inputCount); + TypedFieldDetection(type, name, "ObjectInput", "global::FrooxEngine.SyncRef>", _inputCount); + TypedFieldDetection(type, name, "ObjectArgument", "global::FrooxEngine.SyncRef>", _inputCount); + TypedFieldDetection(type, name, "ValueInput", "global::FrooxEngine.SyncRef>", _inputCount); + TypedFieldDetection(type, name, "ValueArgument", "global::FrooxEngine.SyncRef>", _inputCount); //outputs - TypedFieldDetection(type, name, "ObjectOutput", "NodeObjectOutput<{1}>", _outputCount); - TypedFieldDetection(type, name, "ValueOutput", "NodeValueOutput<{1}>", _outputCount); + TypedFieldDetection(type, name, "ObjectOutput", "global::FrooxEngine.ProtoFlux.NodeObjectOutput<{1}>", _outputCount); + TypedFieldDetection(type, name, "ValueOutput", "global::FrooxEngine.ProtoFlux.NodeValueOutput<{1}>", _outputCount); //impulses - if (!UntypedFieldDetection(type, name, "AsyncCall", "SyncRef", _impulseCount)) - UntypedFieldDetection(type, name, "Call", "SyncRef", _impulseCount); - UntypedFieldDetection(type, name, "Continuation", "SyncRef", _impulseCount); - UntypedFieldDetection(type, name, "AsyncResumption", "SyncRef", _impulseCount); + if (!UntypedFieldDetection(type, name, "AsyncCall", "global::FrooxEngine.SyncRef", _impulseCount)) + UntypedFieldDetection(type, name, "Call", "global::FrooxEngine.SyncRef", _impulseCount); + UntypedFieldDetection(type, name, "Continuation", "global::FrooxEngine.SyncRef", _impulseCount); + UntypedFieldDetection(type, name, "AsyncResumption", "global::FrooxEngine.SyncRef", _impulseCount); //operations - UntypedFieldDetection(type, name, "Operation", "SyncNodeOperation", _operationCount); + UntypedFieldDetection(type, name, "Operation", "global::FrooxEngine.ProtoFlux.SyncNodeOperation", _operationCount); //lists //input lists - TypedFieldDetection(type, name, "ValueInputList", "SyncRefList>", _inputListCount); + TypedFieldDetection(type, name, "ValueInputList", "global::FrooxEngine.SyncRefList>", _inputListCount); //output lists - TypedFieldDetection(type, name, "ObjectInputList", "SyncRefList>", _outputListCount); + TypedFieldDetection(type, name, "ObjectInputList", "global::FrooxEngine.SyncRefList>", _outputListCount); //impulse lists - UntypedFieldDetection(type, name, "ContinuationList", "SyncRefList", _impulseListCount); + UntypedFieldDetection(type, name, "ContinuationList", "global::FrooxEngine.SyncRefList", _impulseListCount); //operation lists - UntypedFieldDetection(type, name, "SyncOperationList", "SyncList", _operationListCount); + UntypedFieldDetection(type, name, "SyncOperationList", "global::FrooxEngine.SyncList", _operationListCount); base.VisitFieldDeclaration(node); } From ee08ad1e5844924e6987579e27e00658f04bc511 Mon Sep 17 00:00:00 2001 From: frozenreflex Date: Wed, 1 May 2024 15:14:21 -0500 Subject: [PATCH 5/5] Remove unused stuff --- .../ProtoFlux/Devices/OpenVR/ImuReader.cs | 184 ------------------ 1 file changed, 184 deletions(-) delete mode 100644 ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs diff --git a/ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs b/ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs deleted file mode 100644 index 6bfd6a6..0000000 --- a/ProjectObsidian/ProtoFlux/Devices/OpenVR/ImuReader.cs +++ /dev/null @@ -1,184 +0,0 @@ -/* -using System; -using System.Threading; -using System.Threading.Tasks; -using Elements.Core; -using FrooxEngine.ProtoFlux; -using ProtoFlux.Core; -using ProtoFlux.Runtimes.Execution; -using Valve.VR; - -namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian; - -public enum ImuErrorCode : int -{ - None = 0, - AlreadyOpened = 1, - AlreadyClosed = 2, - UnknownException = 3, - PathIsNullOrEmpty = 4, - IOBuffer_OperationFailed = 100, - IOBuffer_InvalidHandle = 101, - IOBuffer_InvalidArgument = 102, - IOBuffer_PathExists = 103, - IOBuffer_PathDoesNotExist = 104, - IOBuffer_Permission = 105 -} - -[NodeCategory("Obsidian/Devices/OpenVR")] -public class ImuReader : AsyncActionNode -{ - public ObjectInput DevicePath; - [PossibleContinuations("OnClosed", "OnFail")] - - //public readonly Operation Close; - - public AsyncCall OnOpened; - - public Continuation OnClosed; - - public Continuation OnFail; - - public AsyncCall OnData; - - public readonly ValueOutput IsOpened; - - public readonly ValueOutput FailReason; - - [ContinuouslyChanging] - public readonly ValueOutput FSampleTime; - - [ContinuouslyChanging] - public readonly ValueOutput VAccel; - - [ContinuouslyChanging] - public readonly ValueOutput VGyro; - - [ContinuouslyChanging] - public readonly ValueOutput UnOffScaleFlags; - - private ulong _pulBuffer; - - private Thread _thread; - - protected override async Task RunAsync(FrooxEngineContext context) - { - var path = DevicePath.Evaluate(context); - if (string.IsNullOrEmpty(path)) return Fail(ImuErrorCode.PathIsNullOrEmpty, context); - - var errorCode = OpenVR.IOBuffer.Open(path, EIOBufferMode.Read, sizeof(int), 0u, ref _pulBuffer); - - if (errorCode != EIOBufferError.IOBuffer_Success) return Fail((ImuErrorCode)errorCode, context); - - await OnOpened.ExecuteAsync(context); - - _thread = new Thread((ThreadStart)delegate - { - ReadLoopAsync(context); - }); - _thread.Start(); - IsOpened.Write(value: true, context); - - return OnOpened.Target; - } - - public IOperation DoClose(FrooxEngineContext context) - { - if (_pulBuffer == 0) return Fail(ImuErrorCode.AlreadyClosed, context); - - var eIOBufferError = OpenVR.IOBuffer.Close(_pulBuffer); - if (eIOBufferError == EIOBufferError.IOBuffer_Success) - { - IsOpened.Write(value: false, context); - _pulBuffer = 0uL; - if (_thread != null) - { - _thread.Abort(); - _thread = null; - } - return OnClosed.Target; - } - - FailReason.Write((ImuErrorCode)eIOBufferError, context); - return OnClosed.Target; - } - - ~ImuReader() - { - if (_thread != null) - { - _thread.Abort(); - _thread = null; - } - if (_pulBuffer != 0) - { - OpenVR.IOBuffer.Close(_pulBuffer); - _pulBuffer = 0uL; - } - } - - private unsafe void ReadLoopAsync(FrooxEngineContext context) - { - Task.Run(delegate - { - while (true) - { - var punRead = 0u; - var imuSample_t = default(ImuSample_t); - try - { - if (OpenVR.IOBuffer.Read(_pulBuffer, (IntPtr)(&imuSample_t), (uint)sizeof(ImuSample_t), ref punRead) == EIOBufferError.IOBuffer_Success && punRead == sizeof(ImuSample_t)) - { - var fSampleTime = imuSample_t.fSampleTime; - var vAccel = new double3(imuSample_t.vAccel.v0, imuSample_t.vAccel.v1, imuSample_t.vAccel.v2); - var vGyro = new double3(imuSample_t.vGyro.v0, imuSample_t.vGyro.v1, imuSample_t.vGyro.v2); - var flags = (Imu_OffScaleFlags)imuSample_t.unOffScaleFlags; - OnData.ExecuteAsync(context); - context.World.RunSynchronously(delegate - { - FSampleTime.Write(fSampleTime, context); - VAccel.Write(vAccel, context); - VGyro.Write(vGyro, context); - UnOffScaleFlags.Write(flags, context); - }); - } - else Thread.Sleep(10); - } - catch (Exception ex) - { - break; - } - } - if (_pulBuffer != 0) - { - OpenVR.IOBuffer.Close(_pulBuffer); - _pulBuffer = 0uL; - } - context.World.RunSynchronously(delegate - { - IsOpened.Write(value: false, context); - FailReason.Write(ImuErrorCode.UnknownException, context); - }); - }); - } - - public ImuReader() - { - //Close = new Operation(this, 0); - IsOpened = new ValueOutput(this); - FailReason = new ValueOutput(this); - FSampleTime = new ValueOutput(this); - VAccel = new ValueOutput(this); - VGyro = new ValueOutput(this); - UnOffScaleFlags = new ValueOutput(this); - } - - - private IOperation Fail(ImuErrorCode error, FrooxEngineContext context) - { - IsOpened.Write(value: false, context); - FailReason.Write(error, context); - return OnFail.Target; - } -} -*/ \ No newline at end of file