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..5d7fa00 --- /dev/null +++ b/ClientKit/SkeletonInterface.cs @@ -0,0 +1,595 @@ +/// 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, + + // left hand + HandLeft, + ThumbProximalLeft, + ThumbMedialLeft, + ThumbDistalLeft, + + IndexProximalLeft, + IndexMedialLeft, + IndexDistalLeft, + + MiddleProximalLeft, + MiddleMedialLeft, + MiddleDistalLeft, + + RingProximalLeft, + RingMedialLeft, + RingDistalLeft, + + PinkyProximalLeft, + PinkyMedialLeft, + PinkyDistalLeft, + // end left hand + + ClavicleRight, + ArmUpperRight, + ArmLowerRight, + + // 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, + } + + /// + /// 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 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; + } + + /// + /// 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 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; + } + + /// + /// 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 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; + } + + /// + /// 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 clavicle; //OSVR_SKELETON_CLAVICLE_LEFT, + public SkeletonJointReport armUpper; //OSVR_SKELETON_ARM_UPPER_LEFT, + public SkeletonJointReport armLower; //OSVR_SKELETON_ARM_LOWER_LEFT, + public SkeletonHandState hand; + } + + /// + /// 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 foot; + public SkeletonJointReport toes; + } + + /// + /// 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 legUpper; + public SkeletonJointReport legLower; + public SkeletonFootState foot; + } + + /// + /// 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 GetSkeletonTrimmedInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonTrimmedInterface(iface); + } + + public static SkeletonWholeInterface GetSkeletonWholeInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonWholeInterface(iface); + } + + public static SkeletonHandInterface GetSkeletonHandInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonHandInterface(iface); + } + + public static SkeletonArmInterface GetSkeletonArmInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonArmInterface(iface); + } + + public static SkeletonFootInterface GetSkeletonFootInterface(this ClientContext context, string path) + { + var iface = context.getInterface(path); + return new SkeletonFootInterface(iface); + } + + public static SkeletonLegInterface GetSkeletonLegInterface(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); + } + } +}