From 5c9ee20aff042640a482dbfb8becb4628fff2610 Mon Sep 17 00:00:00 2001 From: JeroMiya Date: Tue, 27 Oct 2015 18:12:22 -0400 Subject: [PATCH 1/3] Added bindings for the skeleton interface. Work in progress (some report types will be changing soon). --- ClientKit/ClientKit.csproj | 1 + ClientKit/Interface.cs | 69 +++- ClientKit/SkeletonInterface.cs | 565 +++++++++++++++++++++++++++++++++ 3 files changed, 633 insertions(+), 2 deletions(-) create mode 100644 ClientKit/SkeletonInterface.cs diff --git a/ClientKit/ClientKit.csproj b/ClientKit/ClientKit.csproj index a265c36..e2a6f3c 100644 --- a/ClientKit/ClientKit.csproj +++ b/ClientKit/ClientKit.csproj @@ -39,6 +39,7 @@ + diff --git a/ClientKit/Interface.cs b/ClientKit/Interface.cs index 98c1bd4..7085217 100644 --- a/ClientKit/Interface.cs +++ b/ClientKit/Interface.cs @@ -76,6 +76,27 @@ override protected bool ReleaseHandle() [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void NaviPositionCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref NaviPositionReport report); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SkeletonJointCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref SkeletonJointReport report); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SkeletonTrimmedCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref SkeletonTrimmedReport report); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SkeletonWholeCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref SkeletonWholeReport report); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SkeletonHandCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref SkeletonHandReport report); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SkeletonArmCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref SkeletonArmReport report); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SkeletonFootCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref SkeletonFootReport report); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void SkeletonLegCallback(IntPtr /*void*/ userdata, ref TimeValue timestamp, ref SkeletonLegReport report); + /// @brief Interface handle object. Typically acquired from a ClientContext. /// @ingroup ClientKitCPP public class Interface : IDisposable @@ -95,7 +116,7 @@ public class Interface : IDisposable //typedef struct OSVR_ClientInterfaceObject *OSVR_ClientInterface; //typedef char OSVR_ReturnCode; (0 == OSVR_RETURN_SUCCESS; 1 == OSVR_RETURN_FAILURE) - + // Callbacks [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] public extern static Byte osvrRegisterPositionCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] PositionCallback cb, IntPtr /*void**/ userdata); @@ -136,8 +157,27 @@ public class Interface : IDisposable public extern static Byte osvrRegisterNaviPositionCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] NaviPositionCallback cb, IntPtr /*void*/ userdata); [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] - public extern static Byte osvrClientGetInterface(SafeClientContextHandle ctx, string path, ref SafeClientInterfaceHandle iface); + public extern static Byte osvrRegisterSkeletonJointCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] SkeletonJointCallback cb, IntPtr /*void*/ userdata); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrRegisterSkeletonTrimmedCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] SkeletonTrimmedCallback cb, IntPtr /*void*/ userdata); + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrRegisterSkeletonWholeCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] SkeletonWholeCallback cb, IntPtr /*void*/ userdata); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrRegisterSkeletonHandCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] SkeletonHandCallback cb, IntPtr /*void*/ userdata); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrRegisterSkeletonArmCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] SkeletonArmCallback cb, IntPtr /*void*/ userdata); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrRegisterSkeletonFootCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] SkeletonFootCallback cb, IntPtr /*void*/ userdata); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrRegisterSkeletonLegCallback(SafeClientInterfaceHandle iface, [MarshalAs(UnmanagedType.FunctionPtr)] SkeletonLegCallback cb, IntPtr /*void*/ userdata); + + // state functions [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] public extern static Byte osvrGetPoseState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref Pose3 state); @@ -174,6 +214,31 @@ public class Interface : IDisposable [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] public extern static Byte osvrGetNaviPositionState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref Vec2 state); + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrGetSkeletonJointState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref SkeletonJointState state); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrGetSkeletonTrimmedState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref SkeletonTrimmedState state); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrGetSkeletonWholeState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref SkeletonWholeState state); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrGetSkeletonHandState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref SkeletonHandState state); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrGetSkeletonArmState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref SkeletonArmState state); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrGetSkeletonFootState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref SkeletonFootState state); + + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrGetSkeletonLegState(SafeClientInterfaceHandle iface, ref TimeValue timestamp, ref SkeletonLegState state); + + // other functions + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] + public extern static Byte osvrClientGetInterface(SafeClientContextHandle ctx, string path, ref SafeClientInterfaceHandle iface); + [DllImport(OSVR_CORE_DLL, CallingConvention = CallingConvention.Cdecl)] public extern static Byte osvrClientFreeInterface(IntPtr iface); diff --git a/ClientKit/SkeletonInterface.cs b/ClientKit/SkeletonInterface.cs new file mode 100644 index 0000000..add4143 --- /dev/null +++ b/ClientKit/SkeletonInterface.cs @@ -0,0 +1,565 @@ +/// Managed-OSVR binding +/// +/// +/// Copyright 2014, 2015 Sensics, Inc. and contributors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +using System; +using System.Runtime.InteropServices; +using ChannelCount = System.Int32; + +namespace OSVR.ClientKit +{ + /// + /// Defines the joints that are available a skeleton per the OSVR Skeleton Spec. + /// + public enum SkeletonJoints:uint + { + Pelvis, + Spine0, + Spine1, + Spine2, + Spine3, + Neck, + Head, + ClavicleLeft, + ArmUpperLeft, + ArmLowerLeft, + HandLowerLeft, + + // left hand + HandLeft, + ThumbProximalLeft, + ThumbMedialLeft, + ThumbDistalLeft, + + IndexProximalLeft, + IndexMedialLeft, + IndexDistalLeft, + + MiddleProximalLeft, + MiddleMedialLeft, + MiddleDistalLeft, + + RingProximalLeft, + RingMedialLeft, + RingDistalLeft, + + PinkyProximalLeft, + PinkyMedialLeft, + PinkyDistalLeft, + // end left hand + + ClavicleRight, + ArmUpperRight, + ArmLowerRight, + HandLowerRight, + + // right hand + HandRight, + ThumbProximalRight, + ThumbMedialRight, + ThumbDistalRight, + + IndexProximalRight, + IndexMedialRight, + IndexDistalRight, + + MiddleProximalRight, + MiddleMedialRight, + MiddleDistalRight, + + RingProximalRight, + RingMedialRight, + RingDistalRight, + + PinkyProximalRight, + PinkyMedialRight, + PinkyDistalRight, + // end right hand + + LegUpperLeft, + LegLowerLeft, + FootLeft, + ToesLeft, + LegUpperRight, + LegLowerRight, + FootRight, + ToesRight, + } + + ///// + ///// There are various types of skeleton reports that allow to get + ///// different skeleton joints/bones. Note, Each report can include information + ///// from one skeleton sensor due to connectedness of skeleton. Refer to the + ///// definition of each report below for a complete description of which bones are + ///// included + ///// + //public enum SkeletonReportSizes + //{ + // Head = 2, + // Arm = 19, + // Leg = 4, + // Foot = 4, + // Hand = 16, + // LOA1 = 21, + // LOA2 = 55, + //} + + /// + /// A state of a single skeleton joint (joint/bone) + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonJointState + { + /// + /// A skeleton joint ID that specifies which bone/joint it is. + /// + public SkeletonJoints joint; + + /// + /// A tracker pose state + /// + public Pose3 pose; + } + + /// + /// A state of a single skeleton joint (joint/bone). + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonJointReport + { + /// + /// A tracker sensor that corresponds to current joint. + /// + public ChannelCount sensor; + public SkeletonJointState state; + } + + /// + /// A type of skeleton state Low level of Articulation LOA1. + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonTrimmedState + { + public SkeletonJointReport[] joints; + } + + /// + /// Report for Skeleton Level of Articulation 1 (LOA1) As defined in + /// H-Anim Low Level of Articulation provides a scaled down version of skeleton + /// joints and includes the following: Head, Neck, Clavicle Left/Right + /// (Shoulders), Arm Upper Left/Right (Elbows), Arm Lower Left/Right (Elbows) + /// Hand Left/Right (Wrists), Spine 0/1/2/3 (Center spine), Pelvis, Leg Upper + /// Left/Right (Hips), Leg Lower Left/Right (Knees), Foot Left/Right + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonTrimmedReport + { + public ChannelCount sensor; + public SkeletonTrimmedState state; + } + + /// + /// A type of skeleton state Hgh level of Articulation LOA2. + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonWholeState + { + public SkeletonJointReport[] joints; + } + + /// + /// Report for Skeleton Level of Articulation 2 (LOA2) : H-Anim defines a + /// humanoid figure with 72 joints to have high Level of articulation however + /// OSVR Skeleton Interface defines a total of 55 joints/bones and it includes + /// all joints described above: Pelvis, Spine 0/1/2/3, Neck, Head, Clavicle + /// Left/Right (Shoulders), Arm Upper Left/Right (Elbows), Arm Lower + /// Left/Right(forearms), Hand Left/Right (Wrists), Left/Right Thumb + /// Proximal/Medial/Distal, Left/Right Index Proximal/Medial/Distal, Left/Right + /// Middle Proximal/Medial/Distal, Left/Right Ring Proximal/Medial/Distal, + /// Left/Right Pinky Proximal/Medial/Distal, Leg Upper Left/Right (Hips), Leg + /// Lower Left/Right (Knees), Foot Left/Right, Toes Left/Right + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonWholeReport + { + public ChannelCount sensor; + public SkeletonWholeState state; + } + + /// + /// A type of skeleton hand state. + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonHandState + { + public SkeletonJointReport[] joints; + } + + /// + /// Report for One Hand (Left or Right) + /// Each hand report includes : Hand (Wrist), Thumb/Index/Middle/Ring/Pinky + /// Proximal/Medial/Distal + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonHandReport + { + public ChannelCount sensor; + public SkeletonHandState state; + } + + /// + /// A type of skeleton arm state + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonArmState + { + public SkeletonJointReport[] joints; + } + + /// + /// Report for a single Arm (Left or Right) + /// Each hand report includes : Clavicle, Arm Upper, Arm Lower, Hand, + /// Thumb/Index/Middle/Ring/Pinky Proximal/Medial/Distal + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonArmReport + { + /// + /// A skeleton interface sensor ID + /// + public ChannelCount sensor; + + /// + /// A collection of skeleton joint reports that only contains the + /// joints for an arm. + /// + public SkeletonArmState state; + } + + /// + /// A type of skeleton foot state + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonFootState + { + public SkeletonJointReport[] joints; + } + + /// + /// Report for a single foot + /// The report includes the following joints: Foot, Toes + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonFootReport + { + /// + /// A skeleton interface sensor ID + /// + public ChannelCount sensor; + + /// + /// A collection of skeleton joint reports that only contains the + /// joints for a foot. + /// + public SkeletonFootState state; + } + + /// + /// A type of skeleton leg state + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonLegState + { + public SkeletonJointReport[] joints; + } + + /// + /// Report for a single leg + /// The report includes the following joints: Leg Lower, Leg Upper, Foot, Toes + /// + [StructLayout(LayoutKind.Sequential)] + public struct SkeletonLegReport + { + /// + /// A skeleton interface sensor ID + /// + public ChannelCount sensor; + + /// + /// A collection of skeleton joint reports that only contains the + /// above joints + /// + public SkeletonLegState state; + } + +#if NET45 + public static class SkeletonInterfaceExtensions + { + public static SkeletonJointInterface GetSkeletonJointInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonJointInterface(iface); + } + + public static SkeletonTrimmedInterface GetSkeletonJointInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonTrimmedInterface(iface); + } + + public static SkeletonWholeInterface GetSkeletonJointInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonWholeInterface(iface); + } + + public static SkeletonHandInterface GetSkeletonJointInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonHandInterface(iface); + } + + public static SkeletonArmInterface GetSkeletonJointInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonArmInterface(iface); + } + + public static SkeletonFootInterface GetSkeletonJointInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonFootInterface(iface); + } + + public static SkeletonLegInterface GetSkeletonJointInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonLegInterface(iface); + } + } +#endif + + /// + /// Interface for SkeletonJoint reports. + /// + public class SkeletonJointInterface : InterfaceBase + { +#if NET45 + [Obsolete("Use the GetSkeletonJointInterface extension method on ClientContext instead.")] +#endif + public static SkeletonJointInterface GetInterface(ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonJointInterface(iface); + } + + private SkeletonJointCallback cb; + public SkeletonJointInterface(Interface iface) : + base(iface, Interface.osvrGetSkeletonJointState) { } + + protected override void Start() + { + cb = new SkeletonJointCallback(this.InterfaceCallback); + Interface.osvrRegisterSkeletonJointCallback(iface.Handle, cb, IntPtr.Zero); + } + + protected void InterfaceCallback(IntPtr userdata, ref TimeValue timestamp, ref SkeletonJointReport report) + { + OnStateChanged(timestamp, report.sensor, report.state); + } + } + + /// + /// Interface for SkeletonTrimmed reports. + /// + public class SkeletonTrimmedInterface : InterfaceBase + { +#if NET45 + [Obsolete("Use the GetSkeletonTrimmedInterface extension method on ClientContext instead.")] +#endif + public static SkeletonTrimmedInterface GetInterface(ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonTrimmedInterface(iface); + } + + private SkeletonTrimmedCallback cb; + public SkeletonTrimmedInterface(Interface iface) : + base(iface, Interface.osvrGetSkeletonTrimmedState) { } + + protected override void Start() + { + cb = new SkeletonTrimmedCallback(this.InterfaceCallback); + Interface.osvrRegisterSkeletonTrimmedCallback(iface.Handle, cb, IntPtr.Zero); + } + + protected void InterfaceCallback(IntPtr userdata, ref TimeValue timestamp, ref SkeletonTrimmedReport report) + { + OnStateChanged(timestamp, report.sensor, report.state); + } + } + + /// + /// Interface for SkeletonWhole reports. + /// + public class SkeletonWholeInterface : InterfaceBase + { +#if NET45 + [Obsolete("Use the GetSkeletonWholeInterface extension method on ClientContext instead.")] +#endif + public static SkeletonWholeInterface GetInterface(ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonWholeInterface(iface); + } + + private SkeletonWholeCallback cb; + public SkeletonWholeInterface(Interface iface) : + base(iface, Interface.osvrGetSkeletonWholeState) { } + + protected override void Start() + { + cb = new SkeletonWholeCallback(this.InterfaceCallback); + Interface.osvrRegisterSkeletonWholeCallback(iface.Handle, cb, IntPtr.Zero); + } + + protected void InterfaceCallback(IntPtr userdata, ref TimeValue timestamp, ref SkeletonWholeReport report) + { + OnStateChanged(timestamp, report.sensor, report.state); + } + } + + /// + /// Interface for SkeletonHand reports. + /// + public class SkeletonHandInterface : InterfaceBase + { +#if NET45 + [Obsolete("Use the GetSkeletonHandInterface extension method on ClientContext instead.")] +#endif + public static SkeletonHandInterface GetInterface(ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonHandInterface(iface); + } + + private SkeletonHandCallback cb; + public SkeletonHandInterface(Interface iface) : + base(iface, Interface.osvrGetSkeletonHandState) { } + + protected override void Start() + { + cb = new SkeletonHandCallback(this.InterfaceCallback); + Interface.osvrRegisterSkeletonHandCallback(iface.Handle, cb, IntPtr.Zero); + } + + protected void InterfaceCallback(IntPtr userdata, ref TimeValue timestamp, ref SkeletonHandReport report) + { + OnStateChanged(timestamp, report.sensor, report.state); + } + } + + /// + /// Interface for SkeletonArm reports. + /// + public class SkeletonArmInterface : InterfaceBase + { +#if NET45 + [Obsolete("Use the GetSkeletonArmInterface extension method on ClientContext instead.")] +#endif + public static SkeletonArmInterface GetInterface(ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonArmInterface(iface); + } + + private SkeletonArmCallback cb; + public SkeletonArmInterface(Interface iface) : + base(iface, Interface.osvrGetSkeletonArmState) { } + + protected override void Start() + { + cb = new SkeletonArmCallback(this.InterfaceCallback); + Interface.osvrRegisterSkeletonArmCallback(iface.Handle, cb, IntPtr.Zero); + } + + protected void InterfaceCallback(IntPtr userdata, ref TimeValue timestamp, ref SkeletonArmReport report) + { + OnStateChanged(timestamp, report.sensor, report.state); + } + } + + /// + /// Interface for SkeletonFoot reports. + /// + public class SkeletonFootInterface : InterfaceBase + { +#if NET45 + [Obsolete("Use the GetSkeletonFootInterface extension method on ClientContext instead.")] +#endif + public static SkeletonFootInterface GetInterface(ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonFootInterface(iface); + } + + private SkeletonFootCallback cb; + public SkeletonFootInterface(Interface iface) : + base(iface, Interface.osvrGetSkeletonFootState) { } + + protected override void Start() + { + cb = new SkeletonFootCallback(this.InterfaceCallback); + Interface.osvrRegisterSkeletonFootCallback(iface.Handle, cb, IntPtr.Zero); + } + + protected void InterfaceCallback(IntPtr userdata, ref TimeValue timestamp, ref SkeletonFootReport report) + { + OnStateChanged(timestamp, report.sensor, report.state); + } + } + + /// + /// Interface for SkeletonLeg reports. + /// + public class SkeletonLegInterface : InterfaceBase + { +#if NET45 + [Obsolete("Use the GetSkeletonLegInterface extension method on ClientContext instead.")] +#endif + public static SkeletonLegInterface GetInterface(ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonLegInterface(iface); + } + + private SkeletonLegCallback cb; + public SkeletonLegInterface(Interface iface) : + base(iface, Interface.osvrGetSkeletonLegState) { } + + protected override void Start() + { + cb = new SkeletonLegCallback(this.InterfaceCallback); + Interface.osvrRegisterSkeletonLegCallback(iface.Handle, cb, IntPtr.Zero); + } + + protected void InterfaceCallback(IntPtr userdata, ref TimeValue timestamp, ref SkeletonLegReport report) + { + OnStateChanged(timestamp, report.sensor, report.state); + } + } +} From 827a39b989a0fc83d6aebae7e3c475666097d5d6 Mon Sep 17 00:00:00 2001 From: JeroMiya Date: Wed, 28 Oct 2015 11:08:35 -0400 Subject: [PATCH 2/3] Updated joint collection report structs with field mappings instead of arrays. This ensures that the skeleton interface does not introduce GC pressure when used. --- ClientKit/SkeletonInterface.cs | 82 +++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/ClientKit/SkeletonInterface.cs b/ClientKit/SkeletonInterface.cs index add4143..2032fec 100644 --- a/ClientKit/SkeletonInterface.cs +++ b/ClientKit/SkeletonInterface.cs @@ -37,7 +37,6 @@ public enum SkeletonJoints:uint ClavicleLeft, ArmUpperLeft, ArmLowerLeft, - HandLowerLeft, // left hand HandLeft, @@ -65,7 +64,6 @@ public enum SkeletonJoints:uint ClavicleRight, ArmUpperRight, ArmLowerRight, - HandLowerRight, // right hand HandRight, @@ -100,24 +98,6 @@ public enum SkeletonJoints:uint ToesRight, } - ///// - ///// There are various types of skeleton reports that allow to get - ///// different skeleton joints/bones. Note, Each report can include information - ///// from one skeleton sensor due to connectedness of skeleton. Refer to the - ///// definition of each report below for a complete description of which bones are - ///// included - ///// - //public enum SkeletonReportSizes - //{ - // Head = 2, - // Arm = 19, - // Leg = 4, - // Foot = 4, - // Hand = 16, - // LOA1 = 21, - // LOA2 = 55, - //} - /// /// A state of a single skeleton joint (joint/bone) /// @@ -154,7 +134,26 @@ public struct SkeletonJointReport [StructLayout(LayoutKind.Sequential)] public struct SkeletonTrimmedState { - public SkeletonJointReport[] joints; + public SkeletonJointReport pelvis; + public SkeletonJointReport spine0; + public SkeletonJointReport spine1; + public SkeletonJointReport spine2; + public SkeletonJointReport spine3; + public SkeletonJointReport neck; + public SkeletonJointReport head; + public SkeletonJointReport clavicleLeft; + public SkeletonJointReport armUpperLeft; + public SkeletonJointReport armLowerLeft; + public SkeletonJointReport handLeft; + public SkeletonJointReport handRight; + public SkeletonJointReport legUpperLeft; + public SkeletonJointReport legLowerLeft; + public SkeletonJointReport footLeft; + public SkeletonJointReport toesLeft; + public SkeletonJointReport legUpperRight; + public SkeletonJointReport legLowerRight; + public SkeletonJointReport footRight; + public SkeletonJointReport toesRight; } /// @@ -178,7 +177,17 @@ public struct SkeletonTrimmedReport [StructLayout(LayoutKind.Sequential)] public struct SkeletonWholeState { - public SkeletonJointReport[] joints; + public SkeletonJointReport pelvis; + public SkeletonJointReport spine0; + public SkeletonJointReport spine1; + public SkeletonJointReport spine2; + public SkeletonJointReport spine3; + public SkeletonJointReport neck; + public SkeletonJointReport head; + public SkeletonArmState leftArm; + public SkeletonArmState rightArm; + public SkeletonLegState leftLeg; + public SkeletonLegState rightLeg; } /// @@ -206,7 +215,22 @@ public struct SkeletonWholeReport [StructLayout(LayoutKind.Sequential)] public struct SkeletonHandState { - public SkeletonJointReport[] joints; + public SkeletonJointReport hand; + public SkeletonJointReport thumbProximal; + public SkeletonJointReport thumbMedial; + public SkeletonJointReport thumbDistal; + public SkeletonJointReport indexProximal; + public SkeletonJointReport indexMedial; + public SkeletonJointReport indexDistal; + public SkeletonJointReport middleProximal; + public SkeletonJointReport middleMedial; + public SkeletonJointReport middleDistal; + public SkeletonJointReport ringProximal; + public SkeletonJointReport ringMedial; + public SkeletonJointReport ringDistal; + public SkeletonJointReport pinkyProximal; + public SkeletonJointReport pinkyMedial; + public SkeletonJointReport pinkyDistal; } /// @@ -227,7 +251,10 @@ public struct SkeletonHandReport [StructLayout(LayoutKind.Sequential)] public struct SkeletonArmState { - public SkeletonJointReport[] joints; + public SkeletonJointReport clavicle; //OSVR_SKELETON_CLAVICLE_LEFT, + public SkeletonJointReport armUpper; //OSVR_SKELETON_ARM_UPPER_LEFT, + public SkeletonJointReport armLower; //OSVR_SKELETON_ARM_LOWER_LEFT, + public SkeletonHandState hand; } /// @@ -256,7 +283,8 @@ public struct SkeletonArmReport [StructLayout(LayoutKind.Sequential)] public struct SkeletonFootState { - public SkeletonJointReport[] joints; + public SkeletonJointReport foot; + public SkeletonJointReport toes; } /// @@ -284,7 +312,9 @@ public struct SkeletonFootReport [StructLayout(LayoutKind.Sequential)] public struct SkeletonLegState { - public SkeletonJointReport[] joints; + public SkeletonJointReport legUpper; + public SkeletonJointReport legLower; + public SkeletonFootState foot; } /// From 70dcf63883ddf12540b332f77fda88d8f1f00397 Mon Sep 17 00:00:00 2001 From: JeroMiya Date: Wed, 28 Oct 2015 11:17:24 -0400 Subject: [PATCH 3/3] Fixed .net 4.5 extension method definitions. Copy paste bug. --- ClientKit/SkeletonInterface.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ClientKit/SkeletonInterface.cs b/ClientKit/SkeletonInterface.cs index 2032fec..5d7fa00 100644 --- a/ClientKit/SkeletonInterface.cs +++ b/ClientKit/SkeletonInterface.cs @@ -345,37 +345,37 @@ public static SkeletonJointInterface GetSkeletonJointInterface(this ClientContex return new SkeletonJointInterface(iface); } - public static SkeletonTrimmedInterface GetSkeletonJointInterface(this ClientContext context, string path) + public static SkeletonTrimmedInterface GetSkeletonTrimmedInterface(this ClientContext context, string path) { var iface = context.getInterface(path); return new SkeletonTrimmedInterface(iface); } - public static SkeletonWholeInterface GetSkeletonJointInterface(this ClientContext context, string path) + public static SkeletonWholeInterface GetSkeletonWholeInterface(this ClientContext context, string path) { var iface = context.getInterface(path); return new SkeletonWholeInterface(iface); } - public static SkeletonHandInterface GetSkeletonJointInterface(this ClientContext context, string path) + public static SkeletonHandInterface GetSkeletonHandInterface(this ClientContext context, string path) { var iface = context.getInterface(path); return new SkeletonHandInterface(iface); } - public static SkeletonArmInterface GetSkeletonJointInterface(this ClientContext context, string path) + public static SkeletonArmInterface GetSkeletonArmInterface(this ClientContext context, string path) { var iface = context.getInterface(path); return new SkeletonArmInterface(iface); } - public static SkeletonFootInterface GetSkeletonJointInterface(this ClientContext context, string path) + public static SkeletonFootInterface GetSkeletonFootInterface(this ClientContext context, string path) { var iface = context.getInterface(path); return new SkeletonFootInterface(iface); } - public static SkeletonLegInterface GetSkeletonJointInterface(this ClientContext context, string path) + public static SkeletonLegInterface GetSkeletonLegInterface(this ClientContext context, string path) { var iface = context.getInterface(path); return new SkeletonLegInterface(iface);