From 98ff21d133c86f31b72e5aa4efe13d87f2b8b6a6 Mon Sep 17 00:00:00 2001 From: Elias Holzer Date: Tue, 19 Sep 2023 17:16:35 +0200 Subject: [PATCH] Makes package .NET 6.0 compatible The Microsoft.Kinect.dll shipped by the Kinect installer has a dependency on https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.eventing.eventprovider?view=netframework-4.8.1 which is no longer supported in .NET Core (see https://github.com/dotnet/runtime/issues/30335). By decompiling the original dlls, re-targeting them to .net6.0 and slightly adapting the logging code to the new APIs (https://learn.microsoft.com/en-us/dotnet/core/diagnostics/eventsource-getting-started) the sensor works correctly again. --- .gitignore | 351 +++- VL.Devices.Kinect.HDE.vl | 164 +- VL.Devices.Kinect.vl | 1510 ++++++++--------- deployment/VL.Devices.Kinect.nuspec | 12 +- .../Microsoft.Kinect.Toolkit.FaceTracking.dll | Bin 33792 -> 0 bytes lib/net472/Microsoft.Kinect.Toolkit.dll | Bin 56320 -> 0 bytes ...soft.Kinect.Toolkit.FaceTracking.deps.json | 36 + .../Microsoft.Kinect.Toolkit.FaceTracking.dll | Bin 0 -> 35328 bytes .../Microsoft.Kinect.Toolkit.deps.json | 36 + .../Microsoft.Kinect.Toolkit.dll | Bin 0 -> 36352 bytes lib/net6.0-windows/Microsoft.Kinect.deps.json | 23 + lib/net6.0-windows/Microsoft.Kinect.dll | Bin 0 -> 155136 bytes .../win-x64/native}/FaceTrackData.dll | Bin .../win-x64/native}/FaceTrackLib.dll | Bin .../AnimationUnit.cs | 18 + .../CameraConfig.cs | 65 + .../EnumIndexableCollection`2.cs | 39 + .../ErrorCode.cs | 26 + .../FaceModel.cs | 190 +++ .../FaceTrackFrame.cs | 168 ++ .../FaceTracker.cs | 349 ++++ .../FaceTrackingImageFormat.cs | 24 + .../FaceTrackingRegisterDepthToColor.cs | 21 + .../FaceTrackingSensorData.cs | 16 + .../FaceTriangle.cs | 53 + .../FeaturePoint.cs | 83 + .../FtInterop.cs | 13 + .../HeadPoints.cs | 22 + .../IFTFaceTracker.cs | 64 + .../IFTImage.cs | 57 + .../IFTModel.cs | 54 + .../IFTResult.cs | 34 + .../Image.cs | 149 ++ ...crosoft.Kinect.Toolkit.FaceTracking.csproj | 19 + .../NativeMethods.cs | 20 + .../OperationMode.cs | 15 + .../Point.cs | 37 + .../PointF.cs | 46 + .../Rect.cs | 47 + .../SensorData.cs | 32 + .../Vector3DF.cs | 50 + src/Microsoft.Kinect.Toolkit/CallbackLock.cs | 34 + src/Microsoft.Kinect.Toolkit/ChooserStatus.cs | 25 + .../ContextEventWrapper`1.cs | 180 ++ .../ContextSynchronizationMethod.cs | 14 + .../KinectChangedEventArgs.cs | 23 + .../KinectSensorChooser.cs | 219 +++ .../KinectSensorChooserUI.xaml.cs | 306 ++++ .../KinectSensorChooserUIViewModel.cs | 209 +++ .../LockExitEventHandler.cs | 10 + .../Microsoft.Kinect.Toolkit.csproj | 19 + .../Properties/Resources.cs | 86 + .../Properties/Resources.resx | 177 ++ .../Properties/Settings.cs | 21 + src/Microsoft.Kinect.Toolkit/RelayCommand.cs | 59 + .../RelayCommand`1.cs | 76 + .../ThreadSafeCollection`1.cs | 183 ++ .../kinectsensorchooserui.xaml | 479 ++++++ .../AllFramesReadyEventArgs.cs | 51 + src/Microsoft.Kinect/AutoLock.cs | 75 + .../BacklightCompensationMode.cs | 16 + .../BeamAngleChangedEventArgs.cs | 19 + src/Microsoft.Kinect/BeamAngleMode.cs | 15 + src/Microsoft.Kinect/BoneOrientation.cs | 85 + .../BoneOrientationCollection.cs | 76 + src/Microsoft.Kinect/BoneRotation.cs | 15 + src/Microsoft.Kinect/ColorCameraSettings.cs | 302 ++++ src/Microsoft.Kinect/ColorImageFormat.cs | 20 + src/Microsoft.Kinect/ColorImageFrame.cs | 92 + .../ColorImageFrameReadyEventArgs.cs | 55 + src/Microsoft.Kinect/ColorImagePoint.cs | 28 + src/Microsoft.Kinect/ColorImageStream.cs | 229 +++ src/Microsoft.Kinect/ContextEventHandler`1.cs | 182 ++ src/Microsoft.Kinect/CoordinateMapper.cs | 274 +++ src/Microsoft.Kinect/DMO_MEDIA_TYPE.cs | 55 + .../DMO_OUTPUT_DATA_BUFFER.cs | 20 + src/Microsoft.Kinect/DataPool`4.cs | 16 + src/Microsoft.Kinect/DataPool`5.cs | 114 ++ src/Microsoft.Kinect/DepthImageFormat.cs | 16 + src/Microsoft.Kinect/DepthImageFrame.cs | 151 ++ .../DepthImageFrameReadyEventArgs.cs | 55 + src/Microsoft.Kinect/DepthImagePixel.cs | 29 + src/Microsoft.Kinect/DepthImagePoint.cs | 51 + src/Microsoft.Kinect/DepthImageStream.cs | 245 +++ src/Microsoft.Kinect/DepthRange.cs | 14 + src/Microsoft.Kinect/DmoAudioWrapper.cs | 43 + src/Microsoft.Kinect/EchoCancellationMode.cs | 15 + src/Microsoft.Kinect/EventDescriptor.cs | 30 + .../EventProviderVersionTwo.cs | 536 ++++++ src/Microsoft.Kinect/FrameEdges.cs | 20 + src/Microsoft.Kinect/IDepthFilter.cs | 15 + src/Microsoft.Kinect/IMediaBuffer.cs | 24 + src/Microsoft.Kinect/IMediaObject.cs | 72 + src/Microsoft.Kinect/INativeAudioWrapper.cs | 25 + src/Microsoft.Kinect/INuiAudioBeam.cs | 23 + src/Microsoft.Kinect/IPropertyStore.cs | 26 + src/Microsoft.Kinect/Identifiers.cs | 14 + src/Microsoft.Kinect/ImageFrame.cs | 69 + src/Microsoft.Kinect/ImageFrameFlags.cs | 17 + src/Microsoft.Kinect/ImageResolution.cs | 17 + src/Microsoft.Kinect/ImageStream.cs | 234 +++ src/Microsoft.Kinect/ImageStreamFlags.cs | 19 + src/Microsoft.Kinect/ImageType.cs | 19 + .../InternalStatusChangedEventArgs.cs | 19 + src/Microsoft.Kinect/Interop/INuiAudioBeam.cs | 29 + .../Interop/INuiColorCameraSettings.cs | 215 +++ .../Interop/INuiCoordinateMapper.cs | 100 ++ ...iCoordinateMapperParametersChangedEvent.cs | 21 + .../Interop/INuiDepthFilter.cs | 27 + .../Interop/INuiFrameTexture.cs | 35 + src/Microsoft.Kinect/Interop/INuiSensor.cs | 186 ++ .../Interop/_LARGE_INTEGER.cs | 16 + src/Microsoft.Kinect/Interop/_Matrix4.cs | 31 + .../_NUI_BACKLIGHT_COMPENSATION_MODE.cs | 16 + .../Interop/_NUI_COLOR_IMAGE_POINT.cs | 17 + .../Interop/_NUI_DEPTH_IMAGE_PIXEL.cs | 17 + .../Interop/_NUI_DEPTH_IMAGE_POINT.cs | 19 + .../Interop/_NUI_IMAGE_FRAME.cs | 23 + .../Interop/_NUI_IMAGE_RESOLUTION.cs | 17 + .../Interop/_NUI_IMAGE_TYPE.cs | 19 + .../Interop/_NUI_IMAGE_VIEW_AREA.cs | 18 + .../Interop/_NUI_LOCKED_RECT.cs | 19 + .../Interop/_NUI_POWER_LINE_FREQUENCY.cs | 15 + .../Interop/_NUI_SKELETON_BONE_ORIENTATION.cs | 19 + .../Interop/_NUI_SKELETON_BONE_ROTATION.cs | 17 + .../Interop/_NUI_SKELETON_DATA.cs | 25 + .../Interop/_NUI_SKELETON_FRAME.cs | 22 + .../Interop/_NUI_SKELETON_POSITION_INDEX.cs | 33 + .../_NUI_SKELETON_POSITION_TRACKING_STATE.cs | 15 + .../Interop/_NUI_SKELETON_TRACKING_STATE.cs | 15 + .../Interop/_NUI_SURFACE_DESC.cs | 17 + .../_NUI_TRANSFORM_SMOOTH_PARAMETERS.cs | 20 + src/Microsoft.Kinect/Interop/_Vector4.cs | 19 + src/Microsoft.Kinect/Interop/tagRECT.cs | 19 + src/Microsoft.Kinect/Joint.cs | 32 + src/Microsoft.Kinect/JointCollection.cs | 47 + src/Microsoft.Kinect/JointTrackingState.cs | 15 + src/Microsoft.Kinect/JointType.cs | 32 + src/Microsoft.Kinect/KinectAudioSource.cs | 425 +++++ src/Microsoft.Kinect/KinectAudioStream.cs | 475 ++++++ src/Microsoft.Kinect/KinectEtwProvider.cs | 527 ++++++ src/Microsoft.Kinect/KinectExceptionHelper.cs | 49 + src/Microsoft.Kinect/KinectSensor.cs | 881 ++++++++++ .../KinectSensorCollection.cs | 165 ++ src/Microsoft.Kinect/KinectStatus.cs | 22 + src/Microsoft.Kinect/Matrix4.cs | 83 + src/Microsoft.Kinect/MicrophoneArrayDevice.cs | 22 + src/Microsoft.Kinect/Microsoft.Kinect.csproj | 17 + src/Microsoft.Kinect/Microsoft.Kinect.sln | 33 + src/Microsoft.Kinect/NativeMethods.cs | 77 + src/Microsoft.Kinect/NuiAudioBeam.cs | 23 + .../NuiColorCameraSettings.cs | 289 ++++ src/Microsoft.Kinect/NuiCoordinateMapper.cs | 122 ++ src/Microsoft.Kinect/NuiDepthFilter.cs | 44 + src/Microsoft.Kinect/NuiSensor.cs | 260 +++ src/Microsoft.Kinect/NuiSensorProperty.cs | 14 + src/Microsoft.Kinect/PROPERTYKEY.cs | 16 + src/Microsoft.Kinect/PowerLineFrequency.cs | 15 + .../ReaderWriterLockSlimExtensionMethods.cs | 19 + src/Microsoft.Kinect/Resources.cs | 118 ++ src/Microsoft.Kinect/Resources.resx | 231 +++ src/Microsoft.Kinect/Skeleton.cs | 163 ++ src/Microsoft.Kinect/SkeletonFrame.cs | 108 ++ .../SkeletonFrameReadyEventArgs.cs | 55 + src/Microsoft.Kinect/SkeletonPoint.cs | 34 + src/Microsoft.Kinect/SkeletonStream.cs | 271 +++ src/Microsoft.Kinect/SkeletonTrackingMode.cs | 14 + src/Microsoft.Kinect/SkeletonTrackingState.cs | 15 + .../SoundSourceAngleChangedEventArgs.cs | 21 + src/Microsoft.Kinect/SpeakerDevice.cs | 22 + src/Microsoft.Kinect/StaticMediaBuffer.cs | 47 + .../StatusChangedEventArgs.cs | 21 + src/Microsoft.Kinect/ThreadSafeList`1.cs | 183 ++ .../TransformSmoothParameters.cs | 46 + src/Microsoft.Kinect/Vector4.cs | 39 + src/Microsoft.Kinect/WAVEFORMATEX.cs | 19 + src/README.md | 1 + 177 files changed, 14804 insertions(+), 869 deletions(-) delete mode 100644 lib/net472/Microsoft.Kinect.Toolkit.FaceTracking.dll delete mode 100644 lib/net472/Microsoft.Kinect.Toolkit.dll create mode 100644 lib/net6.0-windows/Microsoft.Kinect.Toolkit.FaceTracking.deps.json create mode 100644 lib/net6.0-windows/Microsoft.Kinect.Toolkit.FaceTracking.dll create mode 100644 lib/net6.0-windows/Microsoft.Kinect.Toolkit.deps.json create mode 100644 lib/net6.0-windows/Microsoft.Kinect.Toolkit.dll create mode 100644 lib/net6.0-windows/Microsoft.Kinect.deps.json create mode 100644 lib/net6.0-windows/Microsoft.Kinect.dll rename {lib-native/x64 => runtimes/win-x64/native}/FaceTrackData.dll (100%) rename {lib-native/x64 => runtimes/win-x64/native}/FaceTrackLib.dll (100%) create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/AnimationUnit.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/CameraConfig.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/EnumIndexableCollection`2.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/ErrorCode.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FaceModel.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackFrame.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTracker.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingImageFormat.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingRegisterDepthToColor.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingSensorData.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTriangle.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FeaturePoint.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/FtInterop.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/HeadPoints.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/IFTFaceTracker.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/IFTImage.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/IFTModel.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/IFTResult.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/Image.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/Microsoft.Kinect.Toolkit.FaceTracking.csproj create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/NativeMethods.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/OperationMode.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/Point.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/PointF.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/Rect.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/SensorData.cs create mode 100644 src/Microsoft.Kinect.Toolkit.FaceTracking/Vector3DF.cs create mode 100644 src/Microsoft.Kinect.Toolkit/CallbackLock.cs create mode 100644 src/Microsoft.Kinect.Toolkit/ChooserStatus.cs create mode 100644 src/Microsoft.Kinect.Toolkit/ContextEventWrapper`1.cs create mode 100644 src/Microsoft.Kinect.Toolkit/ContextSynchronizationMethod.cs create mode 100644 src/Microsoft.Kinect.Toolkit/KinectChangedEventArgs.cs create mode 100644 src/Microsoft.Kinect.Toolkit/KinectSensorChooser.cs create mode 100644 src/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs create mode 100644 src/Microsoft.Kinect.Toolkit/KinectSensorChooserUIViewModel.cs create mode 100644 src/Microsoft.Kinect.Toolkit/LockExitEventHandler.cs create mode 100644 src/Microsoft.Kinect.Toolkit/Microsoft.Kinect.Toolkit.csproj create mode 100644 src/Microsoft.Kinect.Toolkit/Properties/Resources.cs create mode 100644 src/Microsoft.Kinect.Toolkit/Properties/Resources.resx create mode 100644 src/Microsoft.Kinect.Toolkit/Properties/Settings.cs create mode 100644 src/Microsoft.Kinect.Toolkit/RelayCommand.cs create mode 100644 src/Microsoft.Kinect.Toolkit/RelayCommand`1.cs create mode 100644 src/Microsoft.Kinect.Toolkit/ThreadSafeCollection`1.cs create mode 100644 src/Microsoft.Kinect.Toolkit/kinectsensorchooserui.xaml create mode 100644 src/Microsoft.Kinect/AllFramesReadyEventArgs.cs create mode 100644 src/Microsoft.Kinect/AutoLock.cs create mode 100644 src/Microsoft.Kinect/BacklightCompensationMode.cs create mode 100644 src/Microsoft.Kinect/BeamAngleChangedEventArgs.cs create mode 100644 src/Microsoft.Kinect/BeamAngleMode.cs create mode 100644 src/Microsoft.Kinect/BoneOrientation.cs create mode 100644 src/Microsoft.Kinect/BoneOrientationCollection.cs create mode 100644 src/Microsoft.Kinect/BoneRotation.cs create mode 100644 src/Microsoft.Kinect/ColorCameraSettings.cs create mode 100644 src/Microsoft.Kinect/ColorImageFormat.cs create mode 100644 src/Microsoft.Kinect/ColorImageFrame.cs create mode 100644 src/Microsoft.Kinect/ColorImageFrameReadyEventArgs.cs create mode 100644 src/Microsoft.Kinect/ColorImagePoint.cs create mode 100644 src/Microsoft.Kinect/ColorImageStream.cs create mode 100644 src/Microsoft.Kinect/ContextEventHandler`1.cs create mode 100644 src/Microsoft.Kinect/CoordinateMapper.cs create mode 100644 src/Microsoft.Kinect/DMO_MEDIA_TYPE.cs create mode 100644 src/Microsoft.Kinect/DMO_OUTPUT_DATA_BUFFER.cs create mode 100644 src/Microsoft.Kinect/DataPool`4.cs create mode 100644 src/Microsoft.Kinect/DataPool`5.cs create mode 100644 src/Microsoft.Kinect/DepthImageFormat.cs create mode 100644 src/Microsoft.Kinect/DepthImageFrame.cs create mode 100644 src/Microsoft.Kinect/DepthImageFrameReadyEventArgs.cs create mode 100644 src/Microsoft.Kinect/DepthImagePixel.cs create mode 100644 src/Microsoft.Kinect/DepthImagePoint.cs create mode 100644 src/Microsoft.Kinect/DepthImageStream.cs create mode 100644 src/Microsoft.Kinect/DepthRange.cs create mode 100644 src/Microsoft.Kinect/DmoAudioWrapper.cs create mode 100644 src/Microsoft.Kinect/EchoCancellationMode.cs create mode 100644 src/Microsoft.Kinect/EventDescriptor.cs create mode 100644 src/Microsoft.Kinect/EventProviderVersionTwo.cs create mode 100644 src/Microsoft.Kinect/FrameEdges.cs create mode 100644 src/Microsoft.Kinect/IDepthFilter.cs create mode 100644 src/Microsoft.Kinect/IMediaBuffer.cs create mode 100644 src/Microsoft.Kinect/IMediaObject.cs create mode 100644 src/Microsoft.Kinect/INativeAudioWrapper.cs create mode 100644 src/Microsoft.Kinect/INuiAudioBeam.cs create mode 100644 src/Microsoft.Kinect/IPropertyStore.cs create mode 100644 src/Microsoft.Kinect/Identifiers.cs create mode 100644 src/Microsoft.Kinect/ImageFrame.cs create mode 100644 src/Microsoft.Kinect/ImageFrameFlags.cs create mode 100644 src/Microsoft.Kinect/ImageResolution.cs create mode 100644 src/Microsoft.Kinect/ImageStream.cs create mode 100644 src/Microsoft.Kinect/ImageStreamFlags.cs create mode 100644 src/Microsoft.Kinect/ImageType.cs create mode 100644 src/Microsoft.Kinect/InternalStatusChangedEventArgs.cs create mode 100644 src/Microsoft.Kinect/Interop/INuiAudioBeam.cs create mode 100644 src/Microsoft.Kinect/Interop/INuiColorCameraSettings.cs create mode 100644 src/Microsoft.Kinect/Interop/INuiCoordinateMapper.cs create mode 100644 src/Microsoft.Kinect/Interop/INuiCoordinateMapperParametersChangedEvent.cs create mode 100644 src/Microsoft.Kinect/Interop/INuiDepthFilter.cs create mode 100644 src/Microsoft.Kinect/Interop/INuiFrameTexture.cs create mode 100644 src/Microsoft.Kinect/Interop/INuiSensor.cs create mode 100644 src/Microsoft.Kinect/Interop/_LARGE_INTEGER.cs create mode 100644 src/Microsoft.Kinect/Interop/_Matrix4.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_BACKLIGHT_COMPENSATION_MODE.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_COLOR_IMAGE_POINT.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_PIXEL.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_POINT.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_IMAGE_FRAME.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_IMAGE_RESOLUTION.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_IMAGE_TYPE.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_IMAGE_VIEW_AREA.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_LOCKED_RECT.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_POWER_LINE_FREQUENCY.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ORIENTATION.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ROTATION.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SKELETON_DATA.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SKELETON_FRAME.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_INDEX.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_TRACKING_STATE.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SKELETON_TRACKING_STATE.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_SURFACE_DESC.cs create mode 100644 src/Microsoft.Kinect/Interop/_NUI_TRANSFORM_SMOOTH_PARAMETERS.cs create mode 100644 src/Microsoft.Kinect/Interop/_Vector4.cs create mode 100644 src/Microsoft.Kinect/Interop/tagRECT.cs create mode 100644 src/Microsoft.Kinect/Joint.cs create mode 100644 src/Microsoft.Kinect/JointCollection.cs create mode 100644 src/Microsoft.Kinect/JointTrackingState.cs create mode 100644 src/Microsoft.Kinect/JointType.cs create mode 100644 src/Microsoft.Kinect/KinectAudioSource.cs create mode 100644 src/Microsoft.Kinect/KinectAudioStream.cs create mode 100644 src/Microsoft.Kinect/KinectEtwProvider.cs create mode 100644 src/Microsoft.Kinect/KinectExceptionHelper.cs create mode 100644 src/Microsoft.Kinect/KinectSensor.cs create mode 100644 src/Microsoft.Kinect/KinectSensorCollection.cs create mode 100644 src/Microsoft.Kinect/KinectStatus.cs create mode 100644 src/Microsoft.Kinect/Matrix4.cs create mode 100644 src/Microsoft.Kinect/MicrophoneArrayDevice.cs create mode 100644 src/Microsoft.Kinect/Microsoft.Kinect.csproj create mode 100644 src/Microsoft.Kinect/Microsoft.Kinect.sln create mode 100644 src/Microsoft.Kinect/NativeMethods.cs create mode 100644 src/Microsoft.Kinect/NuiAudioBeam.cs create mode 100644 src/Microsoft.Kinect/NuiColorCameraSettings.cs create mode 100644 src/Microsoft.Kinect/NuiCoordinateMapper.cs create mode 100644 src/Microsoft.Kinect/NuiDepthFilter.cs create mode 100644 src/Microsoft.Kinect/NuiSensor.cs create mode 100644 src/Microsoft.Kinect/NuiSensorProperty.cs create mode 100644 src/Microsoft.Kinect/PROPERTYKEY.cs create mode 100644 src/Microsoft.Kinect/PowerLineFrequency.cs create mode 100644 src/Microsoft.Kinect/ReaderWriterLockSlimExtensionMethods.cs create mode 100644 src/Microsoft.Kinect/Resources.cs create mode 100644 src/Microsoft.Kinect/Resources.resx create mode 100644 src/Microsoft.Kinect/Skeleton.cs create mode 100644 src/Microsoft.Kinect/SkeletonFrame.cs create mode 100644 src/Microsoft.Kinect/SkeletonFrameReadyEventArgs.cs create mode 100644 src/Microsoft.Kinect/SkeletonPoint.cs create mode 100644 src/Microsoft.Kinect/SkeletonStream.cs create mode 100644 src/Microsoft.Kinect/SkeletonTrackingMode.cs create mode 100644 src/Microsoft.Kinect/SkeletonTrackingState.cs create mode 100644 src/Microsoft.Kinect/SoundSourceAngleChangedEventArgs.cs create mode 100644 src/Microsoft.Kinect/SpeakerDevice.cs create mode 100644 src/Microsoft.Kinect/StaticMediaBuffer.cs create mode 100644 src/Microsoft.Kinect/StatusChangedEventArgs.cs create mode 100644 src/Microsoft.Kinect/ThreadSafeList`1.cs create mode 100644 src/Microsoft.Kinect/TransformSmoothParameters.cs create mode 100644 src/Microsoft.Kinect/Vector4.cs create mode 100644 src/Microsoft.Kinect/WAVEFORMATEX.cs create mode 100644 src/README.md diff --git a/.gitignore b/.gitignore index 340d758..2f1229f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,350 @@ -.vl/* -help/Kinect/.vl/* +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch *.pdb -.vs/* +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages *.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ \ No newline at end of file diff --git a/VL.Devices.Kinect.HDE.vl b/VL.Devices.Kinect.HDE.vl index f3fcccc..420d179 100644 --- a/VL.Devices.Kinect.HDE.vl +++ b/VL.Devices.Kinect.HDE.vl @@ -1,6 +1,6 @@  - - + + - + - + @@ -142,7 +126,7 @@ - + @@ -170,10 +154,10 @@ - + - + @@ -187,7 +171,7 @@ - + @@ -195,31 +179,19 @@ - - - - - - - - - + - - - - - + @@ -233,6 +205,18 @@ + + + + + + + + + + + + - + - + @@ -32,7 +32,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -56,7 +56,7 @@ - + @@ -64,7 +64,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -118,7 +118,7 @@ - + @@ -130,7 +130,7 @@ - + @@ -145,7 +145,7 @@ - + @@ -153,7 +153,7 @@ - + @@ -163,7 +163,7 @@ - + @@ -171,7 +171,7 @@ - + @@ -181,7 +181,7 @@ - + @@ -192,7 +192,7 @@ - + @@ -200,14 +200,14 @@ - + - + @@ -220,7 +220,7 @@ - + @@ -232,63 +232,63 @@ - + - + - + - + - + - + - + - + - + @@ -300,7 +300,7 @@ - + @@ -313,7 +313,7 @@ - + @@ -327,7 +327,7 @@ - + @@ -339,7 +339,7 @@ - + @@ -351,7 +351,7 @@ - + @@ -361,7 +361,7 @@ - + @@ -372,7 +372,7 @@ - + @@ -392,7 +392,7 @@ - + @@ -406,7 +406,7 @@ - + @@ -417,7 +417,7 @@ - + @@ -426,7 +426,7 @@ - + @@ -438,7 +438,7 @@ - + @@ -448,7 +448,7 @@ - + @@ -457,7 +457,7 @@ - + @@ -466,14 +466,14 @@ - + - + @@ -482,7 +482,7 @@ - + @@ -496,7 +496,7 @@ - + @@ -505,7 +505,7 @@ - + @@ -516,7 +516,7 @@ - + @@ -527,7 +527,7 @@ - + @@ -538,7 +538,7 @@ - + @@ -551,30 +551,12 @@ - - - - - - - - - - - - - - - - - - @@ -598,20 +580,8 @@ - - - - - - - - - - - - @@ -696,6 +666,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -705,7 +705,7 @@ --> - + @@ -714,14 +714,14 @@ - + - + @@ -731,7 +731,7 @@ - + @@ -741,7 +741,7 @@ - + @@ -752,7 +752,7 @@ - + @@ -761,7 +761,7 @@ - + @@ -806,13 +806,13 @@ --> - + - + @@ -823,7 +823,7 @@ - + @@ -833,7 +833,7 @@ - + @@ -843,7 +843,7 @@ - + @@ -853,7 +853,7 @@ - + @@ -861,19 +861,19 @@ - + - + - + @@ -887,7 +887,7 @@ - + @@ -896,7 +896,7 @@ - + @@ -906,7 +906,7 @@ - + @@ -922,17 +922,19 @@ - + + + - + @@ -941,11 +943,9 @@ - - - + @@ -1014,7 +1014,7 @@ --> - + @@ -1022,7 +1022,7 @@ - + @@ -1032,7 +1032,7 @@ - + @@ -1043,7 +1043,7 @@ - + @@ -1054,7 +1054,7 @@ - + @@ -1063,7 +1063,7 @@ - + @@ -1073,7 +1073,7 @@ - + @@ -1089,17 +1089,19 @@ - + + + - + @@ -1108,11 +1110,9 @@ - - - + @@ -1128,7 +1128,7 @@ - + @@ -1137,12 +1137,12 @@ - + - + @@ -1153,7 +1153,7 @@ - + @@ -1161,13 +1161,13 @@ - + - + @@ -1177,7 +1177,7 @@ - + @@ -1188,29 +1188,24 @@ - + - - - - - - + - + - + @@ -1224,6 +1219,11 @@ + + + + + @@ -1231,7 +1231,7 @@ - + @@ -1308,7 +1308,7 @@ --> - + @@ -1316,7 +1316,7 @@ - + @@ -1326,7 +1326,7 @@ - + @@ -1337,7 +1337,7 @@ - + @@ -1346,12 +1346,12 @@ - + - + @@ -1362,7 +1362,7 @@ - + @@ -1370,7 +1370,7 @@ - + @@ -1379,7 +1379,7 @@ - + @@ -1388,33 +1388,33 @@ - + - + - + - + - + @@ -1428,7 +1428,7 @@ - + @@ -1437,7 +1437,7 @@ - + @@ -1447,7 +1447,7 @@ - + @@ -1463,17 +1463,19 @@ - + + + - + @@ -1482,11 +1484,9 @@ - - - + @@ -1562,12 +1562,12 @@ --> - + - + @@ -1577,7 +1577,7 @@ - + @@ -1587,7 +1587,7 @@ - + @@ -1604,7 +1604,7 @@ - + @@ -1628,12 +1628,12 @@ --> - + - + @@ -1643,7 +1643,7 @@ - + @@ -1653,7 +1653,7 @@ - + @@ -1672,7 +1672,7 @@ - + @@ -1695,14 +1695,14 @@ --> - + - + @@ -1713,7 +1713,7 @@ - + @@ -1743,7 +1743,7 @@ --> - + @@ -1751,7 +1751,7 @@ - + @@ -1759,7 +1759,7 @@ - + @@ -1796,7 +1796,7 @@ --> - + @@ -1804,7 +1804,7 @@ - + @@ -1812,7 +1812,7 @@ - + @@ -1849,14 +1849,14 @@ --> - + - + @@ -1866,7 +1866,7 @@ - + @@ -1902,14 +1902,14 @@ --> - + - + @@ -1919,7 +1919,7 @@ - + @@ -1928,13 +1928,13 @@ - + - + @@ -1944,7 +1944,7 @@ - + @@ -1961,15 +1961,15 @@ - + - + - + @@ -1983,7 +1983,7 @@ - + @@ -1991,7 +1991,7 @@ - + @@ -2000,7 +2000,7 @@ - + @@ -2009,7 +2009,7 @@ - + @@ -2022,7 +2022,7 @@ - + @@ -2038,28 +2038,30 @@ - + - + - + + + - + @@ -2069,7 +2071,7 @@ - + @@ -2079,7 +2081,7 @@ - + @@ -2089,7 +2091,7 @@ - + @@ -2099,7 +2101,7 @@ - + @@ -2109,7 +2111,7 @@ - + @@ -2120,11 +2122,9 @@ - - - + @@ -2133,25 +2133,21 @@ - + - - - - - - - + + + - + @@ -2163,7 +2159,7 @@ - + @@ -2172,7 +2168,7 @@ - + @@ -2251,7 +2247,7 @@ --> - + @@ -2259,7 +2255,7 @@ - + @@ -2269,7 +2265,7 @@ - + @@ -2287,8 +2283,8 @@ - - + + @@ -2315,13 +2311,13 @@ --> - + - + @@ -2331,12 +2327,12 @@ - + - + @@ -2350,7 +2346,7 @@ - + @@ -2361,15 +2357,15 @@ - + - + - + @@ -2381,49 +2377,49 @@ - + - - - - - + + + + + - + - + - + - + - + @@ -2439,7 +2435,7 @@ - + @@ -2489,30 +2485,27 @@ --> - + - + - - - - - + + + - - + @@ -2523,29 +2516,24 @@ - + - - - - - - + - + - + @@ -2559,21 +2547,28 @@ + + + + + - + + + - + @@ -2583,7 +2578,7 @@ - + @@ -2593,14 +2588,12 @@ - - - + @@ -2609,30 +2602,30 @@ - + - + - + - + - + @@ -2641,7 +2634,7 @@ - + @@ -2650,12 +2643,12 @@ - + - + @@ -2664,15 +2657,14 @@ - + - - + @@ -2727,13 +2719,13 @@ --> - + - + @@ -2742,13 +2734,13 @@ - + - + @@ -2759,7 +2751,7 @@ - + @@ -2773,7 +2765,7 @@ - + @@ -2787,15 +2779,15 @@ - + - + - + @@ -2807,55 +2799,51 @@ - + - - - - - + + + + + - + - + - + - + - - - - - + - + @@ -2865,7 +2853,7 @@ - + @@ -2875,7 +2863,7 @@ - + @@ -2929,14 +2917,14 @@ --> - + - + @@ -2946,11 +2934,12 @@ + - + @@ -2964,21 +2953,16 @@ - + - - - - - - + @@ -2989,9 +2973,14 @@ + + + + + - + @@ -3000,7 +2989,7 @@ - + @@ -3009,17 +2998,19 @@ - + + + - + @@ -3034,7 +3025,7 @@ - + @@ -3044,12 +3035,12 @@ - + - + @@ -3060,11 +3051,9 @@ - - - + @@ -3075,11 +3064,10 @@ - - + @@ -3092,16 +3080,6 @@ - - - - - - - - - - @@ -3137,6 +3115,16 @@ + + + + + + + + + + - + @@ -3153,7 +3141,7 @@ - + @@ -3170,7 +3158,7 @@ - + @@ -3187,7 +3175,7 @@ - + @@ -3202,16 +3190,20 @@ --> - + - + + + + + @@ -3219,13 +3211,15 @@ - + + + @@ -3233,17 +3227,19 @@ - + + + - + @@ -3253,7 +3249,7 @@ - + @@ -3263,7 +3259,7 @@ - + @@ -3274,7 +3270,7 @@ - + @@ -3284,11 +3280,9 @@ - - - + @@ -3300,7 +3294,7 @@ - + @@ -3309,7 +3303,7 @@ - + @@ -3319,7 +3313,7 @@ - + @@ -3328,7 +3322,7 @@ - + @@ -3337,7 +3331,7 @@ - + @@ -3346,12 +3340,10 @@ - - - + @@ -3360,13 +3352,9 @@ - - - - - + @@ -3375,17 +3363,16 @@ - + - - + @@ -3395,7 +3382,7 @@ - + @@ -3406,10 +3393,9 @@ - - + @@ -3421,7 +3407,7 @@ - + @@ -3432,7 +3418,7 @@ - + @@ -3442,7 +3428,7 @@ - + @@ -3458,7 +3444,7 @@ - + @@ -3476,7 +3462,7 @@ - + @@ -3496,7 +3482,7 @@ - + @@ -3507,20 +3493,17 @@ - - - @@ -3529,25 +3512,14 @@ + + + + + - - - - - - - - - - - - - - - - @@ -3555,7 +3527,6 @@ - @@ -3569,6 +3540,23 @@ + + + + + + + + + + + + + + + + + - + - + @@ -3973,19 +3961,20 @@ - + + - + @@ -3994,7 +3983,7 @@ - + @@ -4003,7 +3992,7 @@ - + @@ -4014,7 +4003,7 @@ - + @@ -4024,7 +4013,7 @@ - + @@ -4034,7 +4023,7 @@ - + @@ -4044,7 +4033,7 @@ - + @@ -4055,7 +4044,7 @@ - + @@ -4063,7 +4052,7 @@ - + @@ -4071,12 +4060,11 @@ - - + @@ -4130,14 +4118,14 @@ --> - + - + @@ -4154,7 +4142,7 @@ - + @@ -4167,7 +4155,7 @@ - + @@ -4176,7 +4164,7 @@ - + @@ -4185,7 +4173,7 @@ - + @@ -4193,7 +4181,7 @@ - + @@ -4201,7 +4189,7 @@ - + @@ -4213,7 +4201,7 @@ - + @@ -4223,7 +4211,7 @@ - + @@ -4233,7 +4221,7 @@ - + @@ -4247,7 +4235,7 @@ - + @@ -4259,7 +4247,7 @@ - + @@ -4269,7 +4257,7 @@ - + @@ -4279,7 +4267,7 @@ - + @@ -4289,7 +4277,7 @@ - + @@ -4303,7 +4291,7 @@ - + @@ -4312,7 +4300,7 @@ - + @@ -4366,7 +4354,7 @@ --> - + @@ -4375,7 +4363,7 @@ - + @@ -4384,7 +4372,7 @@ - + @@ -4392,11 +4380,14 @@ + + + - + @@ -4408,7 +4399,7 @@ - + @@ -4418,7 +4409,7 @@ - + @@ -4427,7 +4418,7 @@ - + @@ -4437,7 +4428,7 @@ - + @@ -4447,7 +4438,7 @@ - + @@ -4457,7 +4448,7 @@ - + @@ -4465,7 +4456,7 @@ - + @@ -4475,7 +4466,7 @@ - + @@ -4487,7 +4478,7 @@ - + @@ -4497,7 +4488,7 @@ - + @@ -4506,7 +4497,7 @@ - + @@ -4516,7 +4507,7 @@ - + @@ -4526,7 +4517,7 @@ - + @@ -4536,7 +4527,7 @@ - + @@ -4544,7 +4535,7 @@ - + @@ -4554,9 +4545,6 @@ - - - @@ -4610,7 +4598,7 @@ --> - + @@ -4619,7 +4607,7 @@ - + @@ -4628,7 +4616,7 @@ - + @@ -4637,7 +4625,7 @@ - + @@ -4673,7 +4661,7 @@ --> - + @@ -4682,7 +4670,7 @@ - + @@ -4691,7 +4679,7 @@ - + @@ -4704,7 +4692,7 @@ - + @@ -4714,7 +4702,7 @@ - + @@ -4726,7 +4714,7 @@ - + @@ -4735,7 +4723,7 @@ - + @@ -4748,7 +4736,7 @@ - + @@ -4760,7 +4748,7 @@ - + @@ -4768,7 +4756,7 @@ - + @@ -4778,7 +4766,7 @@ - + @@ -4788,7 +4776,7 @@ - + @@ -4800,7 +4788,7 @@ - + @@ -4810,7 +4798,7 @@ - + @@ -4822,7 +4810,7 @@ - + @@ -4833,21 +4821,6 @@ - - - - - - - - - - - - - - - @@ -4879,6 +4852,21 @@ + + + + + + + + + + + + + + + - + @@ -4896,7 +4884,7 @@ - + @@ -4905,7 +4893,7 @@ - + @@ -4914,7 +4902,7 @@ - + @@ -4950,7 +4938,7 @@ --> - + @@ -4958,7 +4946,7 @@ - + @@ -4967,7 +4955,7 @@ - + @@ -5003,7 +4991,7 @@ --> - + @@ -5012,7 +5000,7 @@ - + @@ -5021,7 +5009,7 @@ - + @@ -5030,7 +5018,7 @@ - + @@ -5066,7 +5054,7 @@ --> - + @@ -5074,7 +5062,7 @@ - + @@ -5085,7 +5073,7 @@ - + @@ -5128,7 +5116,7 @@ - + @@ -5142,24 +5130,20 @@ - + - + - - - - - + - + @@ -5167,10 +5151,10 @@ - + - + @@ -5201,10 +5185,10 @@ - + - + @@ -5235,7 +5219,7 @@ - + @@ -5247,7 +5231,7 @@ - + @@ -5261,7 +5245,7 @@ - + @@ -5277,7 +5261,7 @@ - + @@ -5288,7 +5272,7 @@ - + @@ -5296,7 +5280,7 @@ - + @@ -5306,7 +5290,7 @@ - + @@ -5317,7 +5301,7 @@ - + @@ -5325,7 +5309,7 @@ - + @@ -5349,18 +5333,6 @@ - - - - - - - - - - - - @@ -5378,6 +5350,18 @@ + + + + + + + + + + + + - + false - + - + @@ -5597,10 +5581,10 @@ - + - + @@ -5631,7 +5615,7 @@ - + @@ -5643,7 +5627,7 @@ - + @@ -5651,12 +5635,15 @@ + + + - + @@ -5667,7 +5654,7 @@ - + @@ -5675,7 +5662,7 @@ - + @@ -5686,7 +5673,7 @@ - + @@ -5694,7 +5681,7 @@ - + @@ -5704,7 +5691,7 @@ - + @@ -5713,7 +5700,7 @@ - + @@ -5723,7 +5710,7 @@ - + @@ -5732,7 +5719,7 @@ - + @@ -5742,7 +5729,7 @@ - + @@ -5751,7 +5738,7 @@ - + @@ -5760,7 +5747,7 @@ - + @@ -5769,7 +5756,7 @@ - + @@ -5779,7 +5766,7 @@ - + @@ -5788,14 +5775,11 @@ - + - - - @@ -5807,22 +5791,19 @@ - - - - + @@ -5830,7 +5811,7 @@ - + @@ -5847,8 +5828,15 @@ + + + + + + + - + @@ -5857,10 +5845,6 @@ - - - - - + false - + @@ -5965,7 +5949,7 @@ - + @@ -5979,7 +5963,7 @@ - + @@ -5991,7 +5975,7 @@ - + @@ -6003,7 +5987,7 @@ - + @@ -6020,7 +6004,7 @@ - + @@ -6031,7 +6015,7 @@ - + @@ -6041,7 +6025,7 @@ - + @@ -6051,7 +6035,7 @@ - + @@ -6091,7 +6075,7 @@ - + @@ -6102,7 +6086,7 @@ - + @@ -6112,7 +6096,7 @@ - + @@ -6145,7 +6129,7 @@ false - + @@ -6171,7 +6155,7 @@ false - + @@ -6197,7 +6181,7 @@ false - + @@ -6223,7 +6207,7 @@ false - + @@ -6249,7 +6233,7 @@ false - + @@ -6271,7 +6255,7 @@ false - + @@ -6297,7 +6281,7 @@ false - + @@ -6346,7 +6330,7 @@ - + @@ -6362,7 +6346,7 @@ - + @@ -6376,7 +6360,7 @@ - + @@ -6384,7 +6368,7 @@ - + @@ -6394,7 +6378,7 @@ - + @@ -6410,7 +6394,7 @@ - + @@ -6424,30 +6408,26 @@ - + - - - - - + - + - + @@ -6462,7 +6442,7 @@ - + @@ -6476,7 +6456,7 @@ - + @@ -6484,7 +6464,7 @@ - + @@ -6494,7 +6474,7 @@ - + @@ -6512,10 +6492,10 @@ - + - + @@ -6533,10 +6513,10 @@ - + - + @@ -6554,10 +6534,10 @@ - + - + @@ -6575,10 +6555,10 @@ - + - + @@ -6596,10 +6576,10 @@ - + - + @@ -6614,10 +6594,10 @@ - + - + @@ -6637,12 +6617,12 @@ --> - + - + @@ -6650,7 +6630,7 @@ - + @@ -6659,7 +6639,7 @@ - + @@ -6668,30 +6648,23 @@ - - - - - - - - + @@ -6705,7 +6678,7 @@ - + @@ -6719,7 +6692,7 @@ - + @@ -6733,7 +6706,7 @@ - + @@ -6747,16 +6720,23 @@ - + + + + + + + + - + @@ -6766,7 +6746,7 @@ - + @@ -6781,7 +6761,7 @@ - + @@ -6793,7 +6773,7 @@ - + @@ -6807,7 +6787,7 @@ - + @@ -6815,13 +6795,9 @@ - - - - - + - + @@ -6829,7 +6805,7 @@ - + @@ -6841,7 +6817,7 @@ - + @@ -6853,7 +6829,7 @@ - + @@ -6863,7 +6839,7 @@ - + @@ -6875,7 +6851,7 @@ - + @@ -6887,7 +6863,7 @@ - + @@ -6902,7 +6878,7 @@ - + @@ -6914,7 +6890,7 @@ - + @@ -6926,7 +6902,7 @@ - + @@ -6936,7 +6912,7 @@ - + @@ -6944,38 +6920,34 @@ - + - - - - - + - + - + - + - + @@ -6983,7 +6955,7 @@ - + @@ -6991,7 +6963,7 @@ - + @@ -7004,7 +6976,7 @@ - + @@ -7025,29 +6997,6 @@ - - - - - - - - - - - - - - - - - - - - - - - @@ -7134,6 +7083,29 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -7143,13 +7115,13 @@ --> - + - + @@ -7159,12 +7131,12 @@ - + - + @@ -7173,11 +7145,12 @@ + - + @@ -7188,15 +7161,15 @@ - + - + - + @@ -7208,16 +7181,11 @@ - + - - - - - @@ -7226,6 +7194,11 @@ + + + + + @@ -7233,10 +7206,9 @@ - - + @@ -7284,7 +7256,7 @@ --> - + @@ -7292,7 +7264,7 @@ - + @@ -7300,7 +7272,7 @@ - + @@ -7352,9 +7324,9 @@ - - - - - + + + + + \ No newline at end of file diff --git a/deployment/VL.Devices.Kinect.nuspec b/deployment/VL.Devices.Kinect.nuspec index 732fd1a..defa089 100644 --- a/deployment/VL.Devices.Kinect.nuspec +++ b/deployment/VL.Devices.Kinect.nuspec @@ -2,7 +2,7 @@ VL.Devices.Kinect - 1.0.2 + 1.0.3 VL.Devices.Kinect Chau Nguyen, vvvv vvvv @@ -18,10 +18,10 @@ icon\nugeticon.png - - - - - + + + + + \ No newline at end of file diff --git a/lib/net472/Microsoft.Kinect.Toolkit.FaceTracking.dll b/lib/net472/Microsoft.Kinect.Toolkit.FaceTracking.dll deleted file mode 100644 index aa3b053fc61a773e7c19bd960f9a0b9f11907f55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33792 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 ZEY>m|us3fR4Z}0d3C*7?hoTjq{|&=nX%zqf diff --git a/lib/net472/Microsoft.Kinect.Toolkit.dll b/lib/net472/Microsoft.Kinect.Toolkit.dll deleted file mode 100644 index 56bf2629c4dc2e60982831d5744eb47755e90965..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56320 zcmeFa3w)Ht^*?-`XP@kDHuudvgzN$l7Dz%MfZ=Ka;S#w;Zi1IWNEWh^WW#O(L9NRMA$8wYJpSU!g7J|2=1(z2pXHe|_K2`+pnQ z*>ldEIWu!+=FH5Qd7hnj!8WoGk%3QF7tvmP^Iw^Srw-Z>o#=WxksgnIeb8QQ?(2gV z*ZG3(rhtD^O@t!{ub(hbzzOtsrQU>WJK+DhI(Rk{JEO1DMd#JPLWU=Ed8L7e*bBM<9{E6hS>Y#zuQ zmd$zm6?7ro>_#wRu%77|#K2U26BGP{5oDayM{Kba3{WJCX9#FP^kYZxEM^&sU<3^) z*2#~0BA=89ha(O7i=biPiXS=3?)Lyli1kA!j#MMokGeWiW2`ALo{@kG5>ueN0)~v( zxcAcR{zAZoufFH77g+87A|Qus1qn)~%|8nG&=I7epX-!OlNOT$ML=0%2+haiJ4N?k zJUJ$O187u993$(kQj)WzAaPO*|7dW=+Y22wi{T#wc;qa76Kg25B-gH=w3Yx2jzxg@ z;5dBy$0HaySTPmm^v!cNc&w@#H@xSt7FeyS8mPD`cP4GTNtJuPo~ar}sjL(!M{xgv z%DDTZ|8TPvXd^7m38*E+P7vV}C7gs%ialbf?wJfkw|G*~>bl`c=f=;|H^o8@+SsyL z01%)qMG#=Tz6pKUu=uAS^@uPwm9YUR$5NCd2IUCe2YC*wW%EVg);DD!jLV3(Id#uD zV6~pK-jDcT8DO*&I=W%q#GJAIa**^*7#e`50hVU9Nq0RI)<*`7n-gkBohpzgY#i#& z**G%dtWHg`QIakG>5vm2Lcr}9s&cUVVPTPj4H`FdQ2LIg;t5JV6oBDmpl&(^kdF=d zSQO1O6N#Z|m2D8UwmP~+>F>>i9yz&6P^iB*PUn2A1v%>5KMNwFrRndb>Q)bii?z>w zFo5Q+36~3kRKo~>f}-UWK>+UK7Mf?4S>Kd{*uskF!kV;vbSaMXz|J|)hcRre!AijX zbD7X*am;?1Mn%&??O@1U!TM2h3ugAtt6->}(NA7;B(Jm#4-7_+%Bwa>qvDECUOKtM z_2M>H%I~YFDs4Q)rmM86#Ts3Qw0171e=ahOv&}%ymN|jHo%lc`K_djqMlebQ8$uYP zgsw{?XSjKwIY!PlzsoWlBPVA%MwXg*v8&86a-@k2akEu-j2z(R3>+g<-EENJ7#SA; zxhaU&aa?L00TTBwo@-fuM!_7zKOa%5lN8z2cj35bh4#r|>q`Y@Tb)HNQ-5qPZbe?P z$Se2&)a|h9n=dAeL1Xg@{!;mE#-anmQiV(}ny#>dIQ8vEfzdxUahwNz&T7H9evo?) zDrfa$NDAelZWP@Eb7_q!%GP5%E|cSj-8eAT4Ei&xDcqL|wGpaJ1;y%HS}v;uc9n-$ zIJ(z((nh4g9!SsjS3zQ--IW|ydIN+j+IgVGk6df_F9ZNf#L^0KVx#3OLQH|p=1N`} zH*#96%D5=b7Rxi36||yQ|KcbX7sdLQ0DmuesLkbG8TVeI`EAXLi**Xu?D=HVK%CI@B#+e;;M-roi7!0;qQ=Z9P8V2A>wtI0nCZkAZ)V3gRUVI z%zY*WeFB|xDsUZIz+c%-Wgc_`hbtB-CoVuqDhWR5@* z4})4jXIcGTe8uTo+=#V#Rs$It!00ohb%~C*ZYe{w-Lpob(E+RZqU4UZ4VJt&1X;#@_s+`yRU5|attQ!zEeTIiVUwlKvKj^~1k zkY==j#_>!s;~&*^&sqrD3?V?=Y$|CyU^dn(qGm$ zaijUyMN$L+^3sYWd4fQOV)hfJW=`>Ow-j7Ze+#E@s}%nAKnhb$gk^DArC#WRI&DBX z;@STB0XbT*e9|0-e`5$%=}OMGs^S;%Qiv<8&!K-rTFq}LXfkf(2_Ay%ZyWb z=(gZxp!zo>7^>1_N*YW_EM~+A-ID3q!m$_=Ja=N`Q-YM|a!^|^AT%t_CR_b&ETu-rRzw5KTGEF85r}t?xHe$Fssl7_#hdfT?i$mZ{YJ? ze0JmWBYa-K=M8)g;ghKmO~Pk3K1=Xfg^wSf%ka4lpVHk3bfbAB%DI`xuF@X5@p$gW zm`)x3uOkSP(Q?+{^-PAPb&NpL0!|7WW-wC72-Y|eWLPxfiAIJ;BWRaM8k9y5DHY^L z5Xg@pMbXHpXawykY~au~b7u|P3p9v1I&YL}N#sfEgm7)4O{tdT&4WSpO=x6Nuc`|V zI(ei>7@ZLWx{4ssX9R)O5(I_THls*_a3|c1f*?l;PgpnC z*>NTnz2YZ#i=PpWM>}3Oy4vMq{1OQYoZX=;CAE< zcp<~L1Lir`x|x|2E0+uD&C1(&a)Df?SZ-h}Ji|;2F@uFJim5GGE* z#7C5p7N3@&GR<01fW;XKZ!Jg({1sU^JncZ@O0NZLAXQ^Rn-JE6pweWn0Ph5e zg3Sc)h2bbvr(kekk;GlWaUPf!YkXh@C_z{-M?z^)nAyz>qzM1D!jHiT{vSv9PeKPO zUpKG9BmA&jkdI*l{!BeA{})mGMl?SRJ@~H|{$Pavt_VLW3i&Rx{8tM;>Fc53>AFbPXvuf4tyy~^; zv7U3~E6sBU6e_c1mS--Lq$jgOh&!u)C6lb4^YF!;>Q3$%s36;w*PwX*3uGhPC6QWzJw8!8R% zgqTZpV{;`U;mAPOF-8p4EomM$XCp4v^-br3Wcn$Qowixw-$%Nr=m9{RqoVKT=nM2s zEVfY3#0ruj|1Ktv(Km56{(BhVeX0w6EJfBt%v6w}^29PM-l}i;0l574GHZWD-;GEV z{XXWAqTkOD7ySVM(M4ByxabOv6kXv`bo76N>QF8x+f^v*rx9gs;taV`mX=H`BJbhA zVZDLB3P*V!M5O0(D9_@52%!Im2o7+Z^l(8v4}%umgWytKgjxNM0D&$H`dXiP{;%Z3 z3bOhi<(!m1I-+;35$l~b&`a-Q)Rxop7^hsV2Qh9On=uBkJ4C%$_2|+pll>bbQT|kE zOD1;n({U32lL+FYy>a%C-!_&qToK>TAjnDUOHM}5)aaARFi7xp#GC#fE=K{X&p=QQRev@8{G?ZjddoQj{XE-COt@ar`Z=wh zpF1--+<#8dk1hUv|6BTbzE^?1l73$3C8kgPaJ^31?ms<~dg(M2axnV)=+B-PdrOFn z(UhD>A7mL>|Ave_J@^vx;$;gPq7gsbQpM9vUf@@}SV#=5Qv5F?GWZIDHjWpj5jk7V z1B|3?^1ak^8BBJdB!-$K!oQydn$(6qsn_*MeX>vLull6^rB7XUkHpVSBX zq`uK7_3wRBhuQin!+CvDzuPDE{XVIw_P*rK>XUkTcWTZSY_+(-Jg-XA1aCoud42}C z8G9eSO=1I~DarG5MBv2hHU5h6yv|8*dV*CyA8uMU3jo3!A%XxP90(BvQ1j$`^wVta zr{;X;=>U_ZV2YaI9f8MCQmg-$Agbe{d~4uuAi47WouI|p(mZeC8$LCg#s3zd&2J;% z;{1xgxi|t$(+ez?LOlaMD*r)_nXd>~Jt;y4c7FHkn>cl0hVB`S?}B*s?SF?8AgRPE zO#E#a>wL_SVrj9njCfRS&Tf@I))|o%5oEn@qdh<&$&90GV&w#b{u43wF{el8d#F9aQylii=8$OGZy%N(|K_+%t%1$QIm>84Ta68}Op$fUj{)kU3tQ20D7=kR^-g z@EmpbX2`51mDsA$QQ!|k=#Xjk{#DG3KOJg5-}OXXEHBRgp_OolpngMmji_&kG8 zJ3d?fU$oe_n4l2!MX)h%+oR*cBoI&p;b9o+h zq-A8#cOBQJX3!MWJ%ffixU_k31Cw&-h8#}y0;J{8-%*AZ0I^F^_Umxvif?8|Ba?IeX)CsL9FUvo6-&C9&^n z4*Hse-^gP96hRwSdIJ1;w8X|*sucZ9%dzL>&}Rc#OUs>H)4NkxKQpt_P{LRzx6yZ` zEi%BLLBnlK`Fj#;rZAP|{Km;?&q>WgEry_1OHgdu6~9 z+$V|!C7DKQ9EUOs_CV$<1C|3$5zed}=8VJeWzPIG=FBj$JxF&u<>5XU$CV_#GT=B( zqH@8GTbXk<&UQF%4>2}}s--MP1)DE^iDcT6@kPcIs-jI8#L0AF<`)?=w1xCdlrEVb zP9>Uxv#oClw#muZQo2L1%VA=tK>jYWARSkI3SET0#n{<`T}%&6aJbLl@b?n?zHmM)JkO+!wW{0)(JxX< z0skSj4B_)xl`KDo^IEQdXwm2i$?-1hSe$14)3qGoG&hI82Rw+bP5c`8f0oVs8}e$b z7J6%79m1^42834`0fgHUI82jpP&UIaq;Z%pl;y%dM8ZGha@t1(zCyyoDH}lfR}9mq z2t||d=fZiDzzq^Un|K*`-bidmc@F41X*4~Mca3#49g^@_2@_n`^r*$x!gU!>zmnRG z5K5ASS0U6W({??==VEU{_+ad<2%AzTqt%{^9fa_~*erxh3F-6Xzzs$U-Jf)aHHC)8 z?nL-C+YgXxf;BEiqd`_~@vYX>nDg4I>>parYg>mi)Alqp6~bP%yFABxldLE78Uxn+n*vAfc1Fr&o@)^0CMf7|M$ zG&AmX%OPtj4K}g&f#DXFU?0bRVfomaPP;;el4{HVV#Cb$=XdfE?Ox zVv`0i_NHJr)A6*wTXU$MT>#Whdn_ld1L&ZM={Z*0K-xG=#l4l2Y;)5c9)-D#WLT3u zf~htdOh>w52ZuA~HTF;9*J^|54<>dT&cVTS!o=)p8MYym#Lgmcy3+;#8)#y)9Hn|b zjWV(G9kAXsMX+{yMIU54i!L#-KLQ&@*PGak7>6;OZZWYxq3$DTr->aG>|qnTCwq`> zBt2(h=cNs|71Apv76U1xsLR9}4Tmv0oWqv*;kFVQ%`R5xtOIf5sNTe`%N}hzoBnKK ze@AOhpnsW|-7k?IRL-N%|Y7bB7G5bOi(Z#koY?c?P#-JJE8^m5x&x_A_0N`q60 zZ`U%$8k|a3m>6sD9JK{uNix9tr2o?z{?!nIbLNqbFfk;O_gX`hL$whXXE;(mg-S@cgc zZk3C%WbDSdRVFzYOW>uqX+vgFmS9S|v*_s9P}~aJEK1`|nQ+$IDk)E}k7MI42laDl ziir&dHis@!m^MB>Xq!uX@t9k4Lj0ZDJZcl{8k&TX&8G(x2KzF?m``tnv5mGWdPk*` z9L}R-CdN4|q^$8uCg-q-ZZI*>ApXvd6fXUNf;hwkM6RQQAaRqwmGPV632vOzh)3%;DYHc_y(ZW#_8HDA zZMAgF#1doAwbW9ViRHvzhd3LY5=6JyFG$&D^U^>QYaPH?iHXG~Fji?|!z6BniG4GT z<62BCAe`5m*qwsyG_j*u%=x5=Jz!_-brZY6VC=UhwjqYG<0dv=@=Kbc%6Yfscb17g zD>+OuvBYdncbA0gd*8As-o2xeo32eCM5-j}ipC#$KB_ zQM-iF&A5il&*>6!t2nggTeOxgH93doeO;@kD@@KYd2eCYf4yM0+3Q^AX$^FTi8TZB z(;mTIrWuH4<$F*Hgst+oiZJ;`dyAn6VE{@sIEv}U|m~m^cYiXq&CbmtmM@=k% zwNop-D45bbFzLH0hgLdZa%R%)wpRKiigQyp&Q0_;lXDn2H<4b3%F>n825d78FtJtI z?Y7IwBbaEyXs0^_`#AQw+=<#1bVRTZVt3@$&=oYfobadCZdcG&6C0Sf7MyRI*qvBw zTmdeP?#y9-$9%XtG};13i7ph4hUGHl`T-pJ;4BG+it}~sm^4!1D8M=uW-;Yb2Zw*g z4oas<>5){?63zskA!(K5J0v}v=&N7s1Z{%x()uwP}!m-tF(X1g$xLnHlL+DT=B~!uC(v-GUE|0=BuA4cY3H)@jg(~6gYsJpyPWU5Yu{Vj; z60j#pz}~IojxRwdeL?-w$sZfihPt!GcF?j!zjnDx<#i!}X*o%Ieo{rVpr|6!Q zLOD+;%MlKShk`?&&~F!bCqgTIBH;whHDDCIsxhSl;b8g%;W#SSS#lb^h`IDU{YA{L z%k}3l%3CGX&HBo;M!H?U+kP4C)St3#1-w1}GP+qmHlUHliZ@}bcorrL|5))gj0OB0 z*0j9-c$J>ZeHG6Ru|1!Q@I%mfeX&?_ya=%qwYkJLbuO{htsu7Nx9fGTYHhjBHsxm7 z!A&M!7mOv|1y&Hx2erieys@&QyAQSaK4yqd(;wDeB}?8j2=i^vXp@OoFZCk7o_H>* zC!Td40jCwWc6k@sOuT#Kn*LF{4D|17SJAd4hkk>^UPad?4b`ub+;0%hM^Lsg`UljA z-P;E=HhZ#utE75Lzs_>5{*?Y*gdfl!voF@47u{xS`?0V5fOs!z()NmEe2`u~YNz)UFem*J+KmJGJ|?_u_w|$6DTte^pPh{M9(9|3xd0e;?tw@gM7$ zOY{DOaB$2)gkun{(|(zhPWNd~4EQ_Xy9fLelDRG^mfs|;)dpEU&L&Hx#{157+AE-> zSo~>gwVm3UY^P(rJ+8v8*i11k0!Cd7$shKFd;WS>q_M+^n_Q zYN%baU2v|7&3ZM3w5 z^ZUqmTH1Qcbtc@Lz1gx(t3mBhp7`~an}y!4eGz+=rGv)Vuea<3kLVq)4=v@|Ij)Z^n%?04tK|_$ zNT#POFT@TBt7jAdhcz^Sb>I@p}Cb@jCqw@%sD_@w)tw^!ztvt^GUX@*&DI#`Q;| z6`J`RVO_#MjOzfys#yLUqsP<}uZZf2S9M z_!`lP70=qRKkH4iUN5FM#QaWtTLm)img~GivBOjQy%;;}-!6p30*@8AlTf(18_^N&jO8bd~ zZ5B@3F5wOdcS^WV!ow1_8#UD6*eT)j5`G||7Q^&G5|&F?En&NaJ0*Nx!Ve_Wtims0 zxrEgcwoABE!sjLYKtc`n0`euSM!4J2F5ylI_t{t*`)t?K^w{Txa#$#bg>u+-3$2Mg z40@A`vNGO32fIQBW2epo_EW!NoYnS?7P+#%sU1*b93 zJ_!#?Na;)o(lKh$Uew;xa`ZxdiC(8S=-0zKkF%__JZE{sLPoi9rE#5clW~W!-{>?l zW2VJi8)Ly*#g0`-98M17<%yIp24I;=AH(~Ar%a5^2+J)ASnF_zlN0PObfhq_2C-qq z!E26GtUxkwYkeffKmk@8qp%t&#`%ZmicoO1l@~=yVP%^am0CDTm>LoIMCn z#4}HR+K&)k=-}9B%5ED|s**V@N_-mOF4sPU4%^EJl?0XQje)O$ve?DaZcXCLyOqwj z5iX5Agz#%AA0pg5fWw3Y4o3=nTN=abg|bt^FS3~Ou${wg28WwsI9w?F_X__D!s*Or z`b)z31L3?yIDcznx|aJf!n)K?5qg|oARLo*4B^FjClKz^btqcJ{xp~At+`*=?4sXf z=vJ3ju|U`G^Fp(k2z6+d+aML89rvxQpl3^pG^EgQyTAteMffD+6q(yK2koT6YQzGo zL2D($>)`-B7cH*QK!iF@uMz;e5c1u4q9Xt482-jl8s>AY+1ib;FPM4uXI?m8XfwBdmPM2dnt79ixg0P*&A-n>oUpie0 zzp0MZ&Lo6aIaI&DSSbv#=<1L40Y#kM!ON}cu$EJ;Zu12D;724b~uV!C(!4pZzct_LcA?tGIGBV9N$5jU(l~< zh&D>QN!zWxuKiW}r{>hB;gu6t>3c0H#!O?GvC^nB{Kl`14KYR=??!k;hyGr{?#>7y z_`Wfw3!}R`?Y5XB*voXM-5BG?eyh8*+hTTMf7_GqF5!#L&yDjEKxL90( zt+;^^xfAj4q_3bvl2bVM zR*W0h9UnWM@tlrputwsu8Tz~AHzG`CK#t8QH5tz{92S>$bAo^l~}<4GqSqinp>BHR@KwG5ytW3|07~kkx_Km180TkYMTrnmo^6 z+fwhHN^^XTsEbnN^g6#k=nX8Xq(!a4W^Y4LqfJcvq|l(a!fZ*7`RDiz=#{ ztDzv(HuJpA)wN7$2-f%m^}bcyprI5I9R!PJc^ka}Uk$DCHm_LdUDx7+hM@;81GHON zOTqpk0)26_mr0A66U7VW{^LX8~NObeROk!oqi#wH9WZ*7&osikQ_qe)%V z?8jiLl}r-3mQfE^m+`9>2=R604YV$5S+mBAu2)NDA$!pm zwKmq&1^kV^OTpB{tuQO#tEI`|AvSgGiWSqUYu2Lk&h&Zf5rr&ky@B3z(=hgqSWsW9 zirG7AzIQ`^QRRU(!QKf}|L#p!9lAH&tVgeiS>9$<9n1zYcXXRbO!L+p2+b_eUlhU` zpd|qxGOZ2G0ue<@kAy+3^Vd>?`kLcyUFEM1)KaZ?b#+U9b7f<&xw^5&E5l-uza;>W zTY5pjx5n34U2l?5$l2Awy6JemTJ%_uRAy(P^4i*kJg=f04Nd5FGd9-9JWDegYn4Hw zXprW_a!rSd9;%^XQ%FuW1Piwy>qK+1KD*+}h+- zZB8gCV>1K(29qNBR5y4ri3OXgn``R40nzt-rg7xVmil@@A`CrLXf~ZNHJS62AgJjo z%zDu(!Fb2a)Doul8Zn_*)!U-j=ldbaEI+Rof*82cg3}>GvY3trYXQtk2*Kc!Rtw== zBWSof;Hz$IjwViT39u;$k*1-?U?fee4tmLiVQU~Q2rDMk@}{PGUa|mRr9uN_7g?AO3xd2*n33_w)NH&YCUURraQqA|a zGzY5d7n%(joQpx!f{7-=q2zM)BD5a$jzpl?sGhGIb9pf6ZCF*`y4cqoEn{(Y0NR;} zw<&rz_ycPrGL|*eHwG~@eT_bD{z$~)I&XtacM*~~g6AOv4B)VeX4Y4)2}V$*OzBL# zPTnX`bo|^!%u>(2Hj+xpfuXS4w=qIA2R*Yx$|_&Iuemi68(H-5SX#;}PD1xp0QUtL zdWE356|i2Ixa-aHw*IkLS%c?jns`b*s^-Huf_-KG7W2}4ZhmuI%N{O8$Zl7 zeK0CJ*moS~60!rB<@yrJWFFFNAEMS_O!lw3gvx_hR!pz1uV00gLwJ*6E-l0Kh$RY> zYC>sbDH2(;!LDHm4Xw<@a*{&qf`pO?Vm8=f>=p3*0a&}6F`A883fr4TE>y(ShsR>5 z;i7ju3szl%%?-9&-ug&%LldTrMw6=69!jI(E!a|@cY{ha&sP)h2mPy?ixgwgV!ywB zt*^PLwmvLzS#?7_DeKkP9PrnR&MUEnQ{9pQ9|vk*hq=9_0ZS4!2hFQ)q-hZ8#rI;& z%Zsq2R_TMho;EwSfZVc`!O&_%X7uxY&2_#;ikfz?5>kRA`%marOh-rop;2b`67=o9 zI!RwWBqRZo`)c2s7MOERY;IR);gJ#U{fekI?4h`Y-qq%&z5A9oyg$bdIkZ(Lsad3O z6rHqL8k-liG%r{!ORC;+^RZ}&Pk#=N)mj$Ukd3d z)HL&|18ZBFC~D4~74U=LjoxvQj4;_B5qA&;iN&PKnX(rclKj>O~=1R7pZ4(MWiGh#G|UBGLiETM#sgZ?(@9Ywj|n3?Ue6;1H;$i4f*D z*V7@qThBMmQM6O1r>W`|w-6gdZ*4b{%un4YJr+vc;@CpX*yvLZqfn6|YdGPpQ{JUe zYw}{I!rxHD(=M-yqL$M<)B~a2M|3{CaWdUev{t-BA;YVjC84;`n!4{;Zks*~o9MkS zI`$q|&|t$aUK6Dl-v47tU+Bl`9J|UW;zDdmurF0Tr7|cn3)V;KV``_W+NW4dyFMcj z@SBA06OW2eCOE>RaOt_>J*ZS5g84&xQ=X6|B`-!>g1nV6lSkK9WQ8}aA}fMnX=5e{ z%G4d+PGPA`5kF(ZKNxA{kmU+H*os1KM64($FP;j&Tl1;YMe+AwMggOedX;~ai&VrO zU4-(*`(QPxVcfCv4N>#3X5nwsJXiRt*EC|^;H$y4KImtjuf87Mpc;Q;Z7{?WTJltK z+xwdqc?0a+>lGd9&%NS9%W>*=)?9{NC5j&0VgZC);e{oy^)}Y@bjU?mqD+}2!ORdcZGuPanxK6dHHq-DLtLP0uFmAC zV^^%eaw6Q^Q9TAG44XFiHd=#-pRta8t)WiSQ-fmFs(p=N{e`F4aFVDMny3>EDRV@S zYG6Wf%wSrOAi+_Gyuv8kH8@qe;ih$&?+<%IRBH!K(cRX#{cuHFi6GA-JVp1cU@`1&xZx)rUcdAgXUk zPc%VvQ&s))(8&zJvY888lgF&Bn93fNgw;?@f$9XYmSksnc{7$|?5ibSl&ckW)Kq2? zYQsx`5J$Ktn*_hC#d{5VX(m-9sfY=}wwuu6K#KY9?`Fte3f?dwpx_ntQ1zwCOOkrp4`(gmh!hr{Z3gxV*fpR5;3?xC z3#UsU$Zjy47X-nGRT;5wFr??ukdVg2&|dGI&%be@L_?2&xjRahCR~AY#1P*1l0I~p z$!ji^0kP{kbYen_>iiq1IuNLC6?YF|=z2Fs^+6REBA9c1E9?yl*v(eMA90G<=&0V4 zW*_3j!zZ4v=%lQRkgE?PR4r^n=f|R{%3v6Uqii7`C6K>qg-n8QqcL3Bh!((Z5*W+t zQIAN*qV4`;BhGXzLa_URxET#i2+aW;DtGk0FieZ`euZg0vWik@PhE$TD4S|pH+3Q% zj#JY|80D(=)_hONk=ln7;+{f65Vu9(-5@{zzCq?v+|v$H3+|M_se*gR)%bYv7W_G& zHv*~wz9=fibUbnH$3K?B=_>)v6&akaQBtkJHK|d!|KdaHfbjZhHRSNk!idx&oUyZ{ zdfd_RA$AhD{kWskgphM?1Z|YWg~}0K@|tetXn}+x+KAFOKprK8YSMzzk*gduuALVW z`zY&K(ed+!d*cgvt0Xt)QW3gL<@nlZEOLx zMqrxIvjo!--++JB&;t&#@g0PO87MWUXcB3nqXFG@8f|B&u>ZI|Y!q4}x^=h&+$yXy zw$PN_JwD1J4eK7$uN9lnn~&#()%eGG_>eza3EvxjugOa&y0Ci_HB4e4|d?4}0lz_^J7$^jmpqPS*Ds z>T&w1C7qF8Pcz>7)bkmo>7n@Ab?zmLqm330>$!)(8X()3A`ao|Pln}ihfw_IMbk5SN ze?8~Ux|T_o&5r$$47aA)EpF0c0HmZan#h4}bL(2lz?6Y8_)bi;raLdzoLP+6bFIwU z_7_{av;8a$_fFlE?yLq7<0fZ&A(KY~oXM7AQl$eOhB*sAH?H8NkZgiNrI@@lv+4Pj$l(y^89}sfI)^XCR zL=NrtjF2*lKRhm%-Qaj_GHuT@W7}sU;67*jJ)(_r@FY6hA4m~K|strZ)rL@1EKn9AO==9-VdxwgAizVbb z+vVHYuJM3sPuEmQUP2#3fw<;&n~|89h#aKbwS5Liw5C;p)jpTomXq^0CxN)J zCOQG%BAx-=nj6C%%`TyCWmpC{^bZ9hutIj6Y2SW<+_;Et+t!!j$ z48jf}%Zq@j(ZHEY%YGzn;cVw`XsR781`T|I|7;O>@L8-VE_#E{*Nin+t7uA=Mn_GWvMrtBe>5*%sAkZS9P60b*e-QriE<9HDQ-h~?xm=h~mV^rEHN zV-H_vAN^eE(uc;+A7}8jdxP)o8#)JgUYj+Ipp1hy4)|#Re(VJS*faW`2g?542?mw6 z>sC9y*1;a?txjb76tNkMVe8EX=Aio^6w)jOWhm7SL_7ylQ^GZhm)|-@mcoX$%>oZJ(ikrL@N| zf-mW8vGH7>_7qhgHI#XZ)pN}b%tIrFU`D5?@mLOViD*UVAw=3Mxi0?sLMDO3X=_eG+C_zB(q&f@T{P;cUz*0L+~F9va1YTaBl^nFv=(1| z?c(a-+MtbJo{E2X{iswII;+HM4kJ3N@CJQr8cU{^k1j4LnJ5RNtE+3g>V|L-zRs5V z+G$?C)5LcTr{Osn7LAKa*f>wsupZ$`x zMGFGBasr?ELOkvg%wJSKdJL*;9xDXrwFH}|d4sBn{X~-a3ZMgE#dyE zdYq@Xv(X)Z;}!RV_$RKV7VaQUwR|;h+&HPPbvOI@x30s!dv7hX`2$REuJgK^T2|rc zr(2R(jSRWDg%`b2iFvYwQxmx_9F%jIU=gnV`5V{ZYABkyHWVp+${Vnc9vA9S%Qc!4 zX}{17nwDChzewFgg(UM(S@kk+AWT>Uoz;71;?{_HZ`Lo8C#b&K_N_kpXg>GR;t3Ng zyfyXk$IE$f=%5tWq4^S3eQR&+o;%xHkJEOyoCdRIYQ3w0@)HvN#-N*Ti`ToWSK~r} zn~(q8+&SH~es8dGShKs)3!UP0%RCn){%O%){Or%qvProapZZ=J45^FT)Eg*phaOof zaEAuCIU)<(<^`%Ljq0**fxAlD3$Fdecv7cv%Br)^t{zu2Zv5y8C1btCr4xqq&P?5P z59JAMvsqO34iDp&SMdKakDs*>RQek}W7!FOrjFiK*y@R+7YPTo&Q)(Xo`*f*H0&Se z!G}t;GW^l-TkiNZ_guW>r(ZKU5N=959USR1${8Oz{WEVMcJs|Isl;?dxff})EZV?@ z?cY~WYsu(Ut4m79jjygP89&xrGA?%^o^CZylK2Aq|Axr(@iT|f<>l-8{|j={Drmwf zC#wy<#?>1!R~3&RwGo##M>Pc^_el8}avkqF%3WyCe6uU@&Cah-uAV(JZKAfZ;L8-u zkg^ykP1?D7L(QZfX>mQKabrWhdV(rgT*0yZ3@oswJeWP*Q#9GNPj(?W^$eCjl&eBUjno z88&i4XLwLYre`m%2|G&kd64@rU-ai@19FZNQ?@oSh}N&Qq7}bb@N_tYW{jTEgIFPZ#o`lzQ@XZqRV{a|%JRU{qqQQ3B-&M4*%W^LyIPUK<8>?t!mqqWQ z{P+W1){y?0HuEG6xufe+9VNKka$naU^aBU~{)F_>&OPPZ1TeOb!@C*xmc^4%l`xx( z**Bg=o!h?q_pYiVtFW`5c%;kN__MbZ-DoQws&(48RZ`RHC7N+8s|`JQe4}P0PkT~9 zo$i1AhJ;jQ#ArtG@oG&H8C&L`~LX^xhG{&2cryhHsNJv3>a1EnVR9TjDqK(W}IfYf4r1B zw{N{fOI~va%Hq0MGiJ|&oc&wCW?wT-yCvq6p`+~&URGS@dHh_>I5P8HG7kR()sVt7 z)VX`~)g+|-x#yE{aLhTHarl>|V7oLE)lPSj=h?qOc1#)>+w|8^g!{9}IQqp->fEuw zMODAw0Fpiq+T6Af^cR*QC6ae;d>}vv+lL_KUvEKax$s;sfwJvJbSwF#k&Z6?hz`H- z4eHq4^#nEL-i+!WeT{a1_yg)Fz9CL4zWg2q9QnEl2nD|bq0zO`l+p|1wS&K1O&#`2 z{)d(gKab9-I*-z8(&U-1Tp!yP|^4)E@r&b>GN4$I3rbdYubKn?RYg5z~7^gjJ2ya=xIQ_6bm zPU@^W@LTdc`3>mjUi77`1y_-=U3&@rE2*6p9edyh6tkNDhPulP8h0Hun0pi0P!fZS z(xaeCNyk=PN2U0AnvSw3pQL>$zoCxgmv_>#MXylDfuS{Y;EDYTpodLBC|Lt)=*Xkd zl*5ZwQSwro)^Tk1M%o=eP`f$i>B@M0q|IHH_57cD=4~p;eaZLf@Hz2X=e8YNX~$HX zW@P<1fMO5)JDT;v)nwHD4kgQ~Zl?on9nj!K*U|2_!_eCe-zKB!i$9RjHhwo5y9@qA zod>`DGObMef{X)+za!(wV6g4|(Dk5!29Efo= zWIu@S!nVZ4E0dH8lT>!@iMXiy?aDl9rg_4`2tPq0lf_}42f}vje@r_T#fbL}g&E@w zBeCdnu~CIQA-dx5#+ojR!QPAfWW4_{a^LIr6ISbGT*!R;D_#27;$0{6?Hwi%ZQk-@ z_jg$q`K94!6`AgYrmZFfIwQd70g}>31m6FE%=F(Cc%#}vjyax3) z_i?50_7g=Hbq$=r>-dl_A=D)Eu)eJ>DsS|ucOVqas19PwU*X3V*NYvlY~U>DVXnk< zTF^x{-u2>{k$f9oT2#FIq$@sy$!f)zZ^LhT6rYD_776kb@cN|UiTGDkviqb&jSfY{ zrBe(?jp;8Ul!ApBmc=J2ABR{OQM!oS=7Ku%PgnV(E{hLZPRyi*C!?x>cP*g`16`Q> zDZ6(!GoMd&C1w#EuQtgN%li0imZEArB%3b4&jA=LK0hHds>0o3;xbizQ7uf&?9@=b$hbLeugFQGw2;Om`Il4@dS^&|r&H1?vN|)pM300s=8g1;GjT?uze1&Yv@kD2dSCVba*fPWYQGN!^lNTTr-0K* z{R(wIeS=2NV7=Ay@3!fgO8*K~Gn+MQK;O;zrLE_eEb3P_RA-vcDXrFNmL+G{lfH5t zPAC7AWj7lxeLx?U_Di?gmoXY&xw>bR$tml6n)W&qJN}hRe@fw}EOigd=}e*c=*OszUt#2*Mwx@sXh3L+iY{)%mVK2xPrIP*zlx@gdu%$+U?F?@ zn)D;uY&hqDo(=Y;$5;QgGL_h0w>))!IDO4dBmUoSj(!%frxkqqqMv3=#k&%6+38|c zPMD%x8tBHYCCcf&$;RVq!eqe*exOGwn5+b8r zDg(nVmDAR+|2FTZyPbZOamGsPIY`ixxt4GWPgC1uB|&Fz<~SpS>Qo>`r~E~non z_LONBpWh#iM(XWc`f_#QMpE0uzCDqBjIjSFJYaAt8S&j45!`TZDo>$J& zmOVRW~-W!giod3ZQ!`8h+sB`v+W-7iR1t${q={VQQs3gtU z^NS~`V;LU7I`XZ(w5aTv`4lt7@vFO=rr-o;_78A^vn+ElPC8IzgUg(4x82cYahxQV z6TjBoMRD`+_GzqK_;n`v_*rXv`6|4J0Ppme(&fTA8yFL31*&WLU2*Caqxl&wN-h~) zQZ#z(_<};*)hQZ1X2MXoINi)_9(v|yxcg*E9K=kvg%H>hT$Ud{h^(W>7nO_~e_od> zad1@J^8EP0k+`@Q;b(*|Hvva?U1U{nF35KP!|h49d|dJQ9HH)gUhKCq zfAmlqIU4oBIlF{~=9i)sj+rp7Xne^8*7=yCv7^UrJZaeRj}I-aud0q&_SiQl>v*Zw zx&4h+I{MjIobSGmBd~*oBXKfAcps_p+xE*QS{ zbDS(bQlS}KY=g@k?wmb(Vt%HJQVPe9D=oqe&Vn(cizgI~8$WjF$^1-QsqTv&?pSA| zJ;FT+h}n~(`p&7k!~Z+o#q1r@9}1&8gz67wcNjmeq^M+kaY5mjVvNDDr4!8l0K1M0 z2!;4vI?8t?oYE>sn><{6P*)dvn7rgWaJ4~?j3?_hgAb>VZk@88_FZrebsn8sFMzQ( zzZS-3_SrC94DG8d#F;dpCbMm2NK!H+!kEk8 zoK#ANj_!W*mn!q*xA&{e_dU1I%v>N5!H`I0E|obaRGE8zbx38t`y-t73Y$QZk|D{Q zxm4zoQZn~!O4p?3yEn!OU@Ti@!6gc=xj-U_0 zQZgjMm`i0YDJAn`_x(&w81C;38;!+zI5HH25J28@1`9&+aT3Z2N|VV52LZCSzG zer`hlzV+xas-5W={bP(=AlbKfIURJpOP#wj#|vQ84aYs1{lkBPYY`09-FiE9GPL!k zZ{pU&O?c$v=-+O@2>C|5f;#u#979af3}%68=M>zj+KyvEv48a-^ry4_2&D{0AFB&| zj;j`c_B}pA>!9;S3($FV(Fg&IrYA5>AH1O$U5uf&S!ZjV46U3C4KbIo&5h}R6AIKp zAGQ;dI*)z0RRCk#Wtb|2Umy{|kVs`NgYz~xp+Fsc2Skd)02i>+{^rdjWp=kehC*;X z1d^&TB+A(O`-eGxbSGSP;a(e;F5ego~jLZZiftXMcK*0LJz)Bf-V| zM^|{rU=bZuH%(*-Q0KfF7nJ@qjKY9@B7P5@DP`{k6muBZamjKO6$ZAAnWcEbKv_%? z?z=4Z5Cff66(eZ&dfc?iT7M3D!0u=8i#?qO_Tixm{26usfX*el?GIlkLz3DDu9Ku4 z42aZ?-@HBoNX{G;2BdV%69%LPOp!Vgp?T>N%1I+On9d_z=$49F?|mv+|s*H z*U9=jHO;lX`2i(oc2Z~Arw6Gt_aGXrtrHdg`UfV|w*6B&??_W8#T>o&tKwTIvL3N#jmhto&N&5gd3Nx4m3kn>4B%Iv+eUkwEyiN;UdysK19!*0?Q@P z!A-c+#?W2|dfT$&xU*H7b2WxQ5xOlyoy(qjf`nv${yrE)W)p~0b};1r^)Bkz`p}IL zK!h@7Yv2kr*+AIP9S)x?ebDX0XzZ+Gqcgj@X9azTsWJpzZe!h4rgKZ?E%s05w7Z40RsfwvU8VHT@aPOw6|X zuY0kmXu%>!6*U^`dfk2WcL)#ls4CXSV zXk1Mx?NM$P{*yKI);Seg2U7%Sd-?_~Okti#*X0R3-)uzNDRrKZ2)QuDEDtgJTP&yB*6>NS(iZdT#Q@8d;bicJ{*o%IkF8J|ph~+0GP;67^*I8~qA^wdR{9>nE?c+5+E->e( zywMdmy0~EUxB?D~*PSpo1LjvDp1q*_K?$chfRGMr@7u2aU*$XLxjpUMCDM-*q?^|x zvN?rk;{R)#)9AhFf1MQ}x7mN46;VE{GjmqpN8BlYSi%|Ibv&h!>9r00ueajA-irTv zEB?2<6;2+f`3a}LD);3E>3`i7|8-aV|IJ;I+H=b5eM}y{*mJ7U6!KU6O8F~1ht}xg zuQ>Ag*L3k$6mMOwD}RMR;;-1Yak(DxSL|t?62Uqc6MqE*;;%TkWVWvS6&o*uEb&() zpIoJjzoP1Rov!>90*PyZA#p^Ib`kj5Utu3VS3#Zh{A687d-jjgmA^tD@mDY;{)*xs zrA7b|$`tWe9LX=#mA^uSiofE>uC=Yr0}<)YZTWRfm^fMabF zz|SrUfy7W5NL&=mrCbzTP359srJ?V^323`UIV6}Oo(azjPKy8`o_@Xi z$K@H;qkB)BrP=8{>O8z^fB;6-9w(l_yBMAkftEcBPbNd#U2qgIm(lbvJeizOpw43# z7i&V=5kCP=2WAsUQZgjMmlr@)yDBqcBD_VIT87f(|gX7%sy#kCHuDfbELz)>iive5NnX#52a5;aOy;bN`TMNl06t0bQWFRe17QA~$ZB zqY3Fq%se=nSjPUM`Ed2I*p(MoX)33O7b0WMecAd&@SSmi4!pBilQM4mWfcyzx!kM_ zsY=Arm&QgvC!xP5l+MJ?o1VViGv?~z>D!w+QvhS%b!D&(?CCo&XEH1ed-}>YmFnW@ zTe)n!t~`ALiMNd*@$@lQ#M8Iqz+@9+Pv73h%XIPd?Vkt>C2l>=T6y}mzP?abq!Z`E zl(VNV*#nC&p1#=^tklKRx5Kvzd9$ZaAjz8{@$?;NScypX^i|D5O7Zlqyk?m$p1!(& zErhXUPoLx|p1yrESL)*F+i}Z%$>o}(cv0vXh$C$LYoCjKO|~NO{pY8T#2f0nmw@xNJs|}gk(}o25sRPP7>Uz> ztgd9M!7p0-Kkc1eXdG1($LE$*;|CgBlvrcADYf)r88&S#p`egvQ&W&8BxxzKCd_81 z`RMEiJG-W<6lz5Tp(0x7gMw0&s)&Z72sH&C^g+PxKh=BE z`Sz8wqfMtTPM-Pwm;9mZ3uQ6uu_~v9mF%s&TR+74MfP8^e~|nhj$dX!%lS0hcO0K# zdxZKgQI;g{D96XxuVzJf=U;~HV_;pBDqqdp-%4?;e(_@DzI0@Lv_UN;et;^i(JBjI z_-85H6fLaB-hYj%or|kBhK-k?ZizN-gcN^?W-L~z1@{-ND1`sldex#l_!dUArn3QR zelY@mGga;7>G8F3?xo4*<(n+T{R=9C+!6MFJ?)CdnfzVM(4EU0Yb4mSm|={T^C<{d zH25Rj7Y#Lw4#qi}ZExgiiwCENZ=P%sS5}7Tf0t&eqrW0$s&fZ)5&D~cDt=gJb45Al zFaKW*2@`B(P}Xr+HM8hH7(sD)gTXhVfiKrJ!QZBh#0H``u)()1( zU3i&!gxCXKsjXW3a(O={jL`!4QJ+fMPy=jrXZ6>{Y};0Go-mpp?q$7qa3}0dBe>bF z`w@ipUFe&6uQaBStJcu;GCX-O5xNqhPt)o?FDX^rGbb%_WPkz6dMks1@z z^8wc5j<0j0qa|>sX;FMwrV?F3x4p<^|j((=l1{?}n&}qWNp<-Ap@~36;TxmnuwJhQcV>0bA4( z%Hp_F)G40wMho6do|?XAoU$1ukha1ajs#h`*KN4MsW(6IpcV(X-2QG`W$IogoN*PO z8=f7@UaquwEFv=?^h~Iid|#rVr+63D6Gh()0s$5&Tml@^sZ!C5UvL+gzA?33r(mWA z5tW<96w2iPhk}{d3k*6KNYCMR88&8mNhV#7#w+HvUQWX+;!^xnadlyFWg13)x9Gr zn)QAX&DByqnaE9LJ#-%ZWIg_D5&_TTfNSoax|QsFIwfBGH_~x=vk23Ba;z(7(f#XH z^(+g)#6rUJ1n6xUezEJ?Y0ooF<{rR?tktf-K~%N+tUa9X=5rUvlFl~qTNG`Z*(6o=0r}Hn6u~VgkMZJ~kbBSwl6M>5Deb_EwJ=7ngyn|I`oosQl zi7)r#i}XHF1GJ07O-Y|g>4R!JO(yNoNhZup zT1tqd77>;AQ4|mXL9gHg5IqVWkKls?9#DK#K~dqV9ABv5>r^@Q{{L%#^GXYHj^5w7 zzk6?B*0GJPe-Zf%p8Q*;@U_7himRtTR4tzjJ~`tv zR@aj=diEx>(V#D{ORf{$wNC`|R* z_6Q%b5p-;{$}m)Vgv9pIYO+)$xY+Se-B!Q2ZcYppRow_BwvSE#Y%cJq!R2LO z$WV4N?6_o_J;H)!JXw`bw#_G%@TqFfEZ98-)ta~4BYd`0nr93O=QP(fqmL8k+0uw7 zTpc!rbNyKaN$3(odG5r_YHWVtgk@JD*czWY9iEC!MU~hzg6RMsB+t~GX2+u7G~Zw} zw79Lr(BPc(Ni2z>1sA-%2yTWxL zPkIrgB38ss4{OaRYoe?Eh&SSiNW_=kOn%TGa6IYLfO^vN6)psf)dQ%`3fboBG$z!A ze6LfpJ)%uwRQw(SlWDvW>uEI_$y$?dQm4Ui8PO8Aw zh#b4Ju4>K!CwMLKW0MGDr@#x-7S4!B>{MXEr zuqS$*VAxwyxdqG*QrBGs!TPOL!3zU}3l2NYpRh+}z~UCG*$hj|MDvWzMU_+RS~K?b zqZDf1WXcd7KQ2TE%xIh!lBo!5U!mW%Av=b__gB2R6>2Iy`iQ*&_*?{6P3CM%hB9vk z$j$@r5?@KVx0(VUpujH+0&v?u!);Gtw%8`z>5jnm7zR6piN%2OczxC0YTpF^gn$!B z51{qH)szpx%NG_LYrBpu*Hq$I+jZ5i7PFybsK(2ev}7hFF_EC&$|HoEylrdt_*iFS7xU56qepgI%EyjMsUB z#(pqmqR%wA12x0G7_z4^n3@g8cTkG9}7R&4b6_H~!h#Rj4E&k?lYZ?6T+G`mWdxV0wnfn#wHEuI8e_=G1H_UqP+$r`5X1zBe>8)hi{%jSV zqbxHL+%HgqPdb=SM5I^OM7Hm)iT$qHx>1BA>atFH6Uv*{*>28@-2^g*0rNMXV|caI zK0~i@=@JpFQy#%MNf0(O+t6x{Yp#{<2GtX2aRPQ0X8A*Y^wE*)^KmkQlxvm?%oOkB zW8S)BmWjU$G0shHz?-gI#jOZ}-X6i6^SV@nDXW`TaWVsse{*V$3)rnt%9N)rxC(KA z+LKM~GWiMi2vmC^O2q|H_?#Xr6NPF9^$Arso>-ode1t+b zO)jfd>93F2rj~7L*|G9ke(n-zATq-DefgP>`4y0#z{U#LSQn}e)%8?Y)b-dSn0($d zo>RtNI2TJ7ZHv^sbd;*k*;Ovh2dWaG>$s21A| zdQ#{IQcdsmfpKj_#VfKm1jsg-F7hb1H>oRWN_SpK}W*&w_HBRi_G zlOLdOu#vr}j1vb1V?IpAP|1Fxr6Ln@iZZ6MwlKm5{IzMMSAT^aXlab8Q?G@z@ue3|X{lhVExQ{_px?l?F0 zR%prI4G_Br0H*-W+eROk$`+(|25iK}_-Zx=@TZZk{BsIL6Z~a`NQ8c*3e}{o2Itne zl`%j3SnK9k`Gpv(qn={X6K(Dsj1!k5j1wQAxJH$%Z1xDYq~2{?N0nbvFiO5@rujqp zV>m|cIyzHF$uoKmMZ9&{0r+AR`<9ZEc;h_FTu~w0*f9u}Y+dqaaK|xcaNapgf?PG@ ziu+h}pQ^D>$$%)FV<$sq!gv`ACs{k4Q@LiFJ8OCb`vb4Mio6ZIMjpExwu6Axb28>|BCw(K2%YveH>5I^m?zJvQJuJ6{dh`U(DWPG+i#-cxpWnf0naV17F3m`V0Zcsz zLXW?Yq)_VDG+&ye)V_e;3#5lorP9gEPpOt6vn-Uz2bvcfXS@5fZ`dQRV$6f6Zj4D! zg%4&9*B2PMvd2G6rvioGivG)cmK{ z+iG#n*y)LEKg;S5z255STGZjvPU8@oXH3Y4X7g9=5sZ}C6S9=s6+R2w6%yD4(L30+ zP!^YBp3!xry`xA5ywyW$&@C{z%_q6V+!M208H#|Rl9W*7lnLUAp_0FOK^|jFo^Ow+ zeytuimEs6K#y?{ZE(m*uD-km-6Fhn~60-e9PhImrn#vwkv2d!f!K11cV(ZCvJqpoK zo!WM@vEE#b-RMr?7&c}8(OXeuj}XFbZ!5a(xcjp)NdL9_vqO+E%F+q;8MCB>g^h@x zE@NZbS4*%F(m#7;5Kk;ZdeePMx2#^8k3w zCDIp^Nh1hOjpRMx8O8`SRt4+)K~#jHAwB(#!BjV^e8L`iAN_1K8^3aLad-=piv(sB zg*ZJ)qKVrIO<<}Wn^X^<*q+$isMi~NJ08s^)zxK@Of_CUz{;FaiXedQ%rg|xDRvEI zb&3(=6vI9D6+rFSm4Kyl3+oH!7Te_9;*)br71T9fVQNjVwDQ6lQynC==zPKvcJwY7 zfZXsw+OYzuOGH8TS_m=1S2e2r;1<JwR0*An!W^jN7sPKLaK5LiJHRm+(I@m+T{{#Wppiozj;3fuh9(N$Ds^^cOM_V z*eCF4KED`aLoARm}z@;&EGYeQy2%fkXm@MQBDRMNiDH#{NaE^I8|qTR8s=5V-kI0p?B?Ir+^Z&*8Z!3cNd)Ne=G8 zMgw`gUF0`dUQXWJE#56=wK;j!=1#Ds7W8!$C|i+A@1`*RY$VMsmwjM*a2kj|SqnLd zaU7Bh@M^;AlX#&=@+Z8o^OJ*k4dJy6FCSi%g&%l+l2*LV#4FDa0f&B-VO`34@XF&N z9}JTRCrG$5G1)KIDg0*W<%S9JRt%3{S}VG${c@mk(L}#|uY&MWg*PdjuY6IwPbF6= zoHem_ieEloLHJ-O5cSJIWLd;7ziA}=lgfW3Fb|~-^@NtZ!S-VxPWYn$WuC2mxgjKn z8jm%GWTV2D>W(#5%e^%(H~8f-XIZ3LhUvI3g4b`%JBH^Xl$8Sw%t#hXmp01vJ20aSNe}vgzJ3{zN;OHsZ4awRN zIhl!sn}dYczMFAo(#_1ImG9m3_48K~QZH1T_Wq9+Y*UXxY1_vff5~USSMn z*G{6&n?TXdC#R6Q8Px4HBBwy7$Ssg1X{rtEATK}2$_Wg3XTJ}}g@}PXcrLM6^-Gz7lY4x+{--GfY!SV>5lhLD2xkv8S zvddNSmUz6%HupjMKlWL2w&$mS$LfFK>mJ)u|BP?r*iPryfIpm0 zcnUYO2AR z*bo8y0yeCce5qjy;2(oi0e_(Qlas#&4UZ^%sAdNEhi%$+uWB=T-qkP*{LZ@B{=DZ0 zt!L4%xe6l+e=p=bt#GAsKCAdG3NHrq%SWA7zh5p^_$Kt)FSD8!K=Ze!(S{vO{Fs}x>8op`^(H!D0(;mtnse_Bb{t++?wG3ETsOa7&*;hqV^ z?^67Gs(-h()isIy8il8*&It;aDE$32mR_cM9#)-aDgG-D`A3vCM{i{R*e4 zo=S!9QERVI3-_vL)+?t`ai8K3D7-^uzNYv;DgG9f*{hr-iq8PvJ$8Bc*FLM}cT>*9 zXtqv07tln`t@RjjceXlB#}FY8O(OhPKuaF*al{`5oFPw6=d7F?eFmJ#8VO#7Z&3J4 zmHD*eN8}$?m_+={ka-$E5BON?QH9R{=3D%&b1uBv6d>GGbFP0w6iG&|XxLca1`B^- zD5q*dm)|G9b*cU)Qh#=-#>NexJTp*Du5do>XIX_y#kJlqdA3hZa?5@`^$7M2 zXS-BuWHaKvw?JLs56G=bJ#WpdZ$wW1pi(bbZS|v|zM>R$?)E$Kl2V62`6VQ;DD@@T zT1BemBxBi*XE+hEEh61)&)ce&ItC*!Y>O6=OuBYD^4QGc~OtkjoK z?=Ywrl{zFJoX*{dcP1qdLCcl?39@XKp^iE4@z=@ar;xh7Ay@wqe^mbIR8sWry`Ub8 zkurA9kbhU|u=7aOr!aytn`MWczM6+Xo#j%eH+&vcn@inX{UuQ6xzzoWkH`$^R?75m zhU`}A3Ymw!*$lbVrT#GCan!r6Kt1C>MQ$%pKlRU%Pbzg-e%17Q{~P4TN}0aTlgsDO zvg>7K?JNHIGO>k}@x%h*d#t3Mp5O~CkQOY@q*hkd2bRj#HyG*<6HX4Skd5<6ar{mT ztQNkB3P~NmHFCL9#xHB+KBca39&210SR>zZsXs+lfI8|@PlwO8)`)ijwOrvmu4S{8 zI_zB0unLlkT?hG6V;23~E zk34GK6u36fC#S0xM$gTGJ+jVF&KIT~kqhN~mwIBF1!|{Db@-3SKH1|^8!@Bz$&gE3 zh_aMi>{23)azv>s2C`CVC>`4z3uFv=Xl2!B1BMb%)0?p770SNR^yPq|Sa!*jCjvap z@b6JyYRb0)ml^_8Z|JaptUz5FdMdQ5y)ag}uiaoj)`Lihb z!%4H8B6Yicwq+oFe6KJfi1K7C-7c(wKF4`sClEz8_6F$N7vQ zK;0O;#CfPdU5T>KNo`3?d|u90%FOrAOUjL&*$uOt&&y>l6@$+{FE=Q4*txF$3Y5K1 zsT*-&_)btS8A;*zJuEX8v&k!jQbvB*E^5N#?x75a^&N(ODU7x9+#_?GV}H; z6oWr+jGk6^lT)Os1GhQLfan2jJrGVO_{G0 z=ijHDZ%MbIVAqPF2&ydO#VYD_VyRf&t)kuQZ$#p zndwq5pzL?j;!?jv+3(~urP!lL@b_}AOC1IEN9j_^^ysKuh>xyjs^Mtn1gh0j=w3U3{1tbwh65 zW3b1P8(^(1{m|@@-N3za0dSvu2pV3!^xdyoYNOV_sAkg_qX*ZPXyuUhbg_Er2H-xm z+^?1gC6I-^xR~}h}j~tOhd$u%q3@7T9 z8*GV!Z`%e!<~H2*STYmZZ21CO^vKgwsM+W=d~!Tx93y%9WJ=D~h$@{;59&NB32ZpqZ5`J;a|xcCv9w zCSDp*Z-8HI>|Dt&#YIJ2=ckcH zZJhk5leyHZnWVH|_=N3oy)&(xs(nmqA4~DPelNz+i(5>;#4(m}j3i&T;$7u9qF`ga zh1*x2p(g`|a0K00UxRmG2+vTsTw$lejS9CZj4MnkJP0@mXC3OfNjY~&8&2@o>v?>m zwXyzGIS5!IhZJ59*eW*x`sEIV*K6IowX_y%PMh3s9h$aU=4rvR;20?z<-c0%Ta5f>T%#3>z@K# zDn}Hzz~32s2JrdD=fTO;{s!>H>Aw|PauodeHGcu;C^$#0b85VnW#2LRBr9mQMq*aj zo)MjEO}5*nEU;$S?C;%j-qa=5QE7E*fImC!Z0ix>nerw1$+TtGe0z3uC2D=5aRX{S z=WMrLk^|K{0s8^Zu-7}ifZL|*0sL%apGsb2J+7YVwCTO)Wm@DCYn%NMoDrUv>d2V2 z(XMH{!iodF6a0GYdA8XXVXw2%{{7_Zz$biMe3QS7JLGuP?N-n_EA%PAPfz)*br8LH z#F}iqW#U(?u*F?T*y8>pY;mXYyu73C`_^oWJJ{J4_o}n4w@<*lv+teyBkSwdVT^@k zT^-nozQn73W6gjD+(tmd5qVsAj<^Xn9|ini%`4U&YX4E|!JuV7E^nLWm%Fv}ak&Za zjx2|_qxN#EwrPoVzw%qq>+|fR)_13Gvll6Tw!%kL4}EyK{fPD441GQ6L7E0224pS;E*f?%*hhKi)AU`rD(TOu96j=YPn8U0lrJd0N*QbL#fxI zRgOigDlJ-7W6`Qwi&iyQe*|o@Zii&l`XJy;>mI<>TB}QIZBTxXbuai^txp2(upR{5 zW&JZ?pY=t+z1CxZDeFnVA?q7}IqN%s7hBH)UTQrLIA*;7c)9fpz$>la0A6MN9`HKr zPk`^T{sQ=3%jljE_?;Vkq=u9fFHG{0^Vnx1o%noRKU+zEr9=I%?Etg zS`7Fl>ny;>tYv^tSStaavep28%UTckwABOnthEjBIqOY;Kel=Se`@Uo{G~Mj_!}z& z_&e(W;J;g!0={A$0u=iSK(GByK*zogu+n}vV2yn?&H zqdWw7vV0M6j#!~qStu=lXUQ3WZ3@p*ez(F4qyzk3z{4^k=Z8*4mU}38*t$h_g*^71 zG6wh&xhHfo@CN{iw*mh?An{({fr?(me`Mbx^D8`_TVz?q$$;xCdI2x3c(~@Xu=C-X z2LPW_C}DCWOioncvWes@n@G+sg=5MYQ~Y*?4=d+k#h+6swW_C9^(b7fFs|?sh0iOr zCQ)XF!rLdY*6oTvtnd+q&nf>o#h+Iwb*yD6jMlMMRPkjB{~}NNEbB?12d}w!Ewa9X zar4Ve-)WflAIBZX3wWPxqV+E8ChJ4iQ`R4?D*F_Bj=j)6%id&X?ThV?*`KgKZU2+~ zi2X0N2YU;yv3{(k0ql(&+zwabt@;UAQET!3dp$n=-hgZ~8KXNznlaM6OzoTy#eV-o zO@!}hoC)}4KkBe<{ z$0FV2hqnSgsrUm8JAgkBhyw;26M#>t{>^^Yx>(_hQ!WHPw_ynI%qq6^<@y}p?C3$j zdo4;nu5fnr&B~#+$1TFy(ZhhNn<(?nNrbx;-x(p^If3v)%Bixi1U@@@HQ>Ek*J$`7 zaPA5{`ogIX9t{BcBnaroOtInDD!?H8$`e%>um*F-MmC=WI2C@jWg5I}%XIh{8+-6@ zCI!V$l*|BJfDy1UuVw)*l2ZXs!+yt>#TXG=+VRe^g?Cct0`I_X(UMhwwqOqeyi?(N z)V7i9PXjzCrvqMsU6L(t#XPlf^RyI_Zv(XDO1u}1wGzV^?+_@b}AF;I{$Vay#CQw&V^#8}Afv1iVwa0q>E`fFG4DfFHv* zdo9H6HsJT-(;=4J2WaCx;Wq;R1R&1c@BqGf0S^Sw-;?3ZHv!hluK?c_j^eW+Z^Syc z!rpCPXdklQZQo&gEuVE-9b(%GSk*X}c*nSlM(!>A@m+5m;tGFH*k9M;a;an3~V*l(o-V^pZ59ONBAO1P=h3Pn^;Q0VfmkshC@^0&Nc&!bu zRd|i!*Al*ob>kJR5wBo{@W_K&PdZl)4i6+U@!hG!uK5Kjm(GB~$9Up{ds2z{vOm!a z)_i=sGC7!=FPl3Da|;(pPue`GqI0k>aWS>DrBf+LC)0zw78Eora5XG28Wu=LPv_d@ zt5$Zb-?Vml&(6)A>w4xd-q}8X;f94q>*7VPCbC#tpTGD7tRmrsDMc)@|D*lg<@z zs@txWwwp@ZWq&+1oY=Wj@G}wZ@myT>cEo!VJ(+m#K74wsJ299|XS66=M7s}WbBTf0 z;uvRJS0x4$nPjig+ml97IPpA^ zI^s!|u0~7UiFl@Wugh4M7|z5~>k_#G>C8Ttw;WNrKe2ph2!ip!-UJ3Jk#fsc(m(1y zmqFjOCvrMeE~_t@9ZF}>S|*WAWcC9&fqS}#61~ZIDtQTt3;s=HHV-BTlev7s^4;nE ziJrZgM4}@-oXPE_!&V+lq>_EI0>963;KW5*YyIHybv9!zX4WSAR-|*e^gxL+@cL4T z7n=uHP5<|y3L?h-^JW^U#?vm1ya-Woz zlscu9U(y%T_tL^be~vFI_@z|7L|J|UxZNpe8pkhlO{uE0x1O_a=gt*onsy`;sXjS- z+wrXJ$Fq#B$Mezh@l1}!@mw|JI5wwdccM2v*r!RRfGTGok=vU#(-*( zZyRQ_tjuK68O7Ekz;r%ymP@*f>cna^5Z{wPes0So;<<#Oy3)N!8K|`1WoW)FOkyNB zBd3}9c(zKHNEoy)kg-1ry(F=|AFXQQZ$t9S#Leh%!s2zveGS}LXPr69?0_$?g zL8LWzp35d|b#ny@^EgvNnZtoQgspC{QcX{~D?PY}`PqCm1dQ&zm@mxQF2`)9DU9L9 z3gRyD>7fI0tQlC_(b9ShYPmh#xx7G5PZ0&OH$8N)SV)5t-MaeZy|0`74e{Jw8Q`{G zG5T^#vJX6BI?WBK15rYo6`u=_DMvUMZoB#%U=(lTJ!{_k~#V4-WRW#Z#%>NXeqA+^k<=Uy+G}EY@V;WT?2TX`{NB!XYCt5PQ$XJP;h z1z$1548e8OV1=X8z!28w!JOd^aBNgTS7JXf9Y}+6z~Llvp^}*)i!8Vyc`+Ef%P36; zrgQA_hGDEQCUJ~ssw8&9zF|~h0P860!8)7mA5NK=(7h+-Tp~Vz*^RS$DTB2%a$Et@DpW#u;sQY2 z-88NVbk0N5&_V7UwO!*?-7LE3Zas)%Pdhvydah~14pGzv`2YlMgc*$>I0P=LaxTv8 zGb|b&7}TcLce`08-{JfXNa<}zeot7o5Nd@@?j1?tvLr8R;yZbXu6~kVWqDzMA02Q* z6^9k~qD#1?)l~_m<#{Glxdqe3sKD3FVTl}ljIACn1E6~SZf-{1&0gQii+izoBY#~w zSJ+|{xyv(qu*)CJA*R;%Z{kMu__B3~h9cKpdJ2c3Vo6?Ck<&St#e$dYO>#CS2GW^> z#j>^Wi?I@59Mrm1i5xFnbRU{!800sC8W%ljakskM%gFXbCXI+LUPPF)e{x8N+{8eE zr9(fCS2$m{Cx;4x3>O4{DNE~)JinfBZiUBzAg_V<6?#U zTCy3$Jzfd5Ha-~N1I6eur#n_%5a}EtQh6asfy^J1OL;?a9$-p2{m9Rnf>6Vh<|%jU zSvEs-KDMRPnLg~CatYobq8@D76i?!IO?dcl(KR^8acGohu)Q!U-yHT3Cp!C>Yf>@0 z9do-0xAT&dt(X-RxsRJSu=3a9IQHa6p*Ux=t@&acGH?N!b5Gk8ZskQeQmt;Tx2Mws zu#22aifC)Ea+17qzz!&mL!$J#PX>gJESUulqDuv4AJ20Is<)8BSpf_1Py$zrNRf&D zesbc2$$>Hkb?VwWzJcSJiHsYJ6s2J%l=4);;aGJcfCGZQS&$`BZiuqVEK!cWnV=Yz zBcI?n!pf!HJ^{DLf_aor;i&2^a~feQQ}H2O%dX8z4*5M*S_Gau5lU{Bv~T%J$y5sQ z){CpGEYdpfe%9*!RTg8)+h6uNt0rdgo<;@-Wsvz5!Cb4fx^C;nrSOT0^Jm;bxj8yv zkU0ifZfAP(&Q#lQMctjqVIz+3RMS;G?3Q-b?P4ij+TEZ_Ubq)f&$j_QKI0={Wl;l6Dff71O7wti zP&kZp3CW15q}xT+JZ0uHwGk;#)rMD=s|}0Z${tsPZ4`w`4RLZAIkt%HIexL;&@iTy zWcJJ#VfJNma0D;)a)`n`*z~UN*F1_*k*s^MSi;(jO+gpl8888r%uovLbtu-aa4p_c zTgRWvry=Xo2XNDj5yrE0lUKMk+Kml{TY{ZfIh)a4&e6CoXO(MJ0ldXCUTqoQ=q+Qp zipzL7jQ8%tO1FHl5AP$v%oHxP^}=Dp#nPkiyi1brzne?3<(W+Upl-d*dASYysXf@f z<6V!Px*p(8jdvwMP=b`|+Cq8KrZeviQVc0-xDRf}aG|Co*gz2Tq|lI7Uev zG_e7c^Z`o&KLClG>;*O`!{CtDk2*#YaijP?NM}$&Gbl-&NtpZUdNU~N*IKwaS8cLo z-Rr0~gf^0>L7UkYaRW=8gEd-pCHR9R%g4Jei~hvbNm2A^5IX3SUTB`HR?%(r3@t;5 zi*<6b#%5Q(4btpEKR(V$FG%P3R_JdtNc2S-)az_*M!x2&wl%p2Et)atg62K=AW;${ zlfXc~XD&MNf8KxA*r9G66Kq;xD{d0tjbblam7=#2_*l~jK29|X&ImpXH7YH@)@pC} zYE2`tz%AJTPcV-0Mwv!*M(ZzhOV{ILIMlZYv{Wp_N3(WA2fiFyu^2oTAL)R0<3CQU z9Q1J#C4fcYRr;3^LI38bTAsg0En;8tGl4Q`L>02KLiTJWKFUQ4hrl(Fknf{Zv7JHJ za#_x(VvCGy#xQ3|9A06BX94r`mv!Q>pEl9vgLvjN*4u%x9nRSQl7>SU(H%55KRjk~ zpNY?IwW}GNf;1bybdE;m;?)BVCmb#d-N4)jiF_wHfJKRJxTRP1bHK*S=Lft8Eio82 z;FT$nqRs`dqywLj8-+wx!=qgK)mmWPg@2`PJ9@#Ma3F@@R@PbcSLzf4dp&GrO{NV7 z`EZ#RP1sZ8X=NI%3tlbpF#tFg`SkiAbRyV!aJ_y$4Dx4CM6k6}cBRIoHRp#pNM@)oko=c}0_`hT(87VVr}w zi^r2uQ%qM>PE}mg_N##$s9qSEPd7Q>5=Ndou))VDS7BahXPr+@< zC8+#by9K6>l`x7KoEeYiFm_mnJm$U9y~I+)&&3)=XW|3YqhgJ{^F(I+byu2RM9~PB z4Q^|gJpVRhWbEI|9SL<8f z^tX&%U0!uL!ihuF3lX#CbFam72q$|KU)IRyW1iMiFp#^0K7_lWOY1Vv@5a#Pb85aT zzeg z%qivdcr!tVnq4V-J-!{L18Bd1LC1xiTNdsu%%pxTZQMti9d7>gNt$*IE1x049?IA) z%YibAXl^n4=NH;6%6gA8JiqzniHVm9RGWf2n#4KE+{5#bnXT+(`PPR+S`3I%XGU=j zGaKsJA_qEAv-Bb)znS2czaKh_?mhmNh+(%L_31>~bx_?Fl~X_&o9Rg6;~hJGmX+H2 zUzlaM@S1zW7tbBuGOPXi?mwK@xXGR+-l%0co~T$pAmK2{YDLfRMg>3cHYu_VU#0W2 zaO{KT@nvto3eR*VMQZGcGSTw-r%tp&HBdv@Y4}ZQRDj4t%jW<18jlqjdp{so{AJ zehflreh5D_>p&~*4}o^@^|Pi1GQe+w_|$MJ*x)qS{sw$K&2DJ$MQy9P8l?>mfYqQP zyC_l}@K=WqMm9%ABk{=CAzFRN2fZq7S1TPx6HR#8Ui?n+K|idVI!!zwt0^cRe69PX z>ZwiCS`CqESjd;H6=yiEK$8#dJv3Y4d~a03NrC}XsD$q#tNj5x5{-1hSj(=i4tQaI zc}3I z?{j)Bzy`;jir)$Z?g!4AJ79XHVydXc2WuRqQ_g+o?z}8~By^_p#K^?IJURFK8@;^Z z^;!fr0l#MECDV(+5U(r)u;ioHq7=YG;3e=8;DkSfw2r39F391N? zy3SovdhGbm99RA34Bn7G%p{}>8Krpf2rFPCeh5ck1pvNyi3vt9fdIdDBHl0oe#1h% z_)#74@=J7He#y>@UmC$b2^A-dzN7g53nY1bqYvf_?&AU5IxtL6YD?f_(%jfGGEQ z<@a)3SQU0-!RtfLPRZC^t=8B(#=Wgj`c86d{=J6cyUT^o`L;yM-%xLf;(a52xOwSf z{Q5ZlYl*s_C|Ww07|!8~T`kcK_+mq{_q@cx9(-qFaOv)O3;R#&KfQnc{JzuX#TUjW zSv_`5_rBy1G~rX@z4~6QWluwFq5A9iei(DqjXn~7Jg#~*3JzaNChYTI9pM*`d= zUITb-1$_}-8}LGnNCRHW@QT|05FRmz4CC45^+(3;0MZV|4!jm2?T1r9hMcI^3I;3D zR#burt?*1=6gl0&WS(eElmIeFq$#pG5VcSt5)DN?Q^UI|!#g5TAHL%op2w7JS4RUV zMQ(>8`k0%LwqjYhNT9PEPfO2d2W*w^oL}KA6yiuYVnUG!TiZr3& za34X6CUg<24RK9F!b3s~x~NlGWbV?0+E5>@ij3V~-ezR%Q%!IVTCc%McE3OB!LO!p z9kavp)Jrzj3=4!NTB`RtYGXARPEDjMfEtxkD}xmnkebSxhMHiFjT%;s%^Ee4)m5lb z6K<&q_eIW*bZJ}R7NYQuTYySb6AXrD2H}HXumK1Lwjl(ik#|mkZB`Ri0k(0x zTIl9VqXeU9S(Pe|5LEG$Cx)1gA*O*izL>@};Y4Ol1R+2J!7_pb00IJl_3$q*ASi%P zDqQP}A=t@R`F5mpSOBn#Kr8Y0H^M0=|MhGAU8WwpZc8RUgzxzjKCq~7n`SM@*~nfZ zOD$<=UAM9aAN%4LKwI+pWj_*(B|X)(`T+!f$HV|IvvPe|{dn zc_IP#(--(BcR2v4LUpa5?^0qVP&7C)I!J;Me=Pz0`zoQ+y zJpN1-|4OQ~y>^un$@bSRx#G1Yt1St}Mz*34+i1TbF9vy#WQ!%I#!^d1_-6QMOK#~1 z-hLl#$t)ew_rOP6b}t< z-j3hx;1<*Ud)C9P)A@L-bSL0Syw%c;>xcFDw+wdTxejk(a04XrIq$EJncrqG0giP^ z`P^FZ4++kl>PjlWgn-of*ty`-qS&qQoXayRPs{w9skO|mvhw;~(;7aLe@Un-axd(S4IXESX z*QIJ3-$NyzBTebNKS}YD=I=RXMH@|=m=6>5;eLbnz(ue8J=?^;*P~-r-q!e$8$WJK uw9ayjE#FicKy;g1n!i>L?)v|K|F?MHI`c0GzH-k0Egky*{rJy#;C}&Qoe~uQ literal 0 HcmV?d00001 diff --git a/lib/net6.0-windows/Microsoft.Kinect.Toolkit.deps.json b/lib/net6.0-windows/Microsoft.Kinect.Toolkit.deps.json new file mode 100644 index 0000000..fe86164 --- /dev/null +++ b/lib/net6.0-windows/Microsoft.Kinect.Toolkit.deps.json @@ -0,0 +1,36 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v6.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v6.0": { + "Microsoft.Kinect.Toolkit/1.8.0.0": { + "dependencies": { + "Microsoft.Kinect": "1.8.0" + }, + "runtime": { + "Microsoft.Kinect.Toolkit.dll": {} + } + }, + "Microsoft.Kinect/1.8.0": { + "runtime": { + "Microsoft.Kinect.dll": {} + } + } + } + }, + "libraries": { + "Microsoft.Kinect.Toolkit/1.8.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Kinect/1.8.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/lib/net6.0-windows/Microsoft.Kinect.Toolkit.dll b/lib/net6.0-windows/Microsoft.Kinect.Toolkit.dll new file mode 100644 index 0000000000000000000000000000000000000000..721a4fd3a8bb34344dd470ebed4f72f9969c3417 GIT binary patch literal 36352 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 literal 0 HcmV?d00001 diff --git a/lib/net6.0-windows/Microsoft.Kinect.deps.json b/lib/net6.0-windows/Microsoft.Kinect.deps.json new file mode 100644 index 0000000..5842213 --- /dev/null +++ b/lib/net6.0-windows/Microsoft.Kinect.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v6.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v6.0": { + "Microsoft.Kinect/1.8.0.0": { + "runtime": { + "Microsoft.Kinect.dll": {} + } + } + } + }, + "libraries": { + "Microsoft.Kinect/1.8.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/lib/net6.0-windows/Microsoft.Kinect.dll b/lib/net6.0-windows/Microsoft.Kinect.dll new file mode 100644 index 0000000000000000000000000000000000000000..c28f65e4d88eb6aeb79668bee0e97aee01adbe69 GIT binary patch literal 155136 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%0D$mI0Y%*^Q2cv59uU4Aj0x|B_> zq>?grtUj2UPh~K~WLA>X52hC{WM}7-7qY8s%gY#lRa;(1%S)?i z842f7$(ch?Qi4r@msT=9^5vyVsg>+}dNGAcPQ7|9wK#nxJCj~@8R~R1SC&)R>81Ilm27$utXGYK7?J+RXI)B9cR8UQDA-(~B3A^J%mKkg4pY^y2797NlS)DX(U-$tmPduoM>5 z0EIwI7Djix*O80LGY0uFPCQV@fw*k=GWJ7nA9EHosa< z&tzxQD`=NBkq5SDdMP`dT$b9&%%T6yWEasjy`5X+&U7ZbXKR=*i;ldkE<^ZCcF^J% zQXm6>#H}K~_TcLoy<~Ry}6Qbvm8(nOeI(C)EzNJc}--eMxE?BRlAyj zAUBn>3CZj%t!0+iGNQY(Q){#68?)#L6bvXmh#qshx;7>K>r(Qfx8MSsNiApQ)M|F= zL7kR_P0cK)FQ?}HES9Gin({P-ipegmq*IH?FlO>W=#?cePFK6z&D82%9TURA^paF? zYl&2LKDmPBLV7Wix{z8qL^;l-m$TEz#i0bNb4zRUGf+n!suu0DlDvdAy8qmaR=Ad%TA@l>#E7bS&M!?rh(Tc`HJwq7+@^ekd+1zpaV9&Tn#~;2un#V# zQb*yFiw~mUM=+pd9D#P^;s}~qRLfC3F0G(hk0MCTPob%gNI_~r>hP#)IEp~m!%-Bh zh@11_jabBa2QV3eRX1^WU<&`u>kj%|_ zLtV|2)>n%=#c5=tVXQe*d+CA?FE)pnTBTaGG@@SFspYL!n)%{}mEX&k z{HWwkp;$?lH=DqkD>G#0W4TtzTlIP?Vj)+C6|1mRwaSYyiL?@+1Y+n~ZJ-?6sI5cE zR?ULFg(kZ}lSXTq#Ma^iGcg$Qin$WZc+D7_zdhIY;kCUhT|hQrh!K>Cn`56-^OgKH zH?&qR`NGIFmeVd?j1a;myCZf%rz%a2c`C)15r2KLUVUg2Tk5&K0yEOyinR$9RnrS_ zw%IDIL6%)uiOj6~06Ob1=HYWt+G=t=y8cXk+a!(>pBe1Rz0t(;+n;5K|vPM<$5Dm#u~Sv zimn&+u~sg=c8B0iXdJsAAXsk-N?!%sF6e{S-fXS1Z6fLgG>o7$5o11W7zBWkWB?So z4}fm4lP_JjYNcG&B&4%zcTLG<69}xDAh4q%SB8Nx)S3*sA;-uHqj9s46bRFbQ8oq& zY7X5@tyMQ`xq?NLG6hCza5`5Oe|DYiti9MPXo#wd5M!}Q778j?C}dYD32>m~MQ6v9>u=$pnB&?I^wr(0J^o zwMxkw?I^rX%}brG+o5dH@nSDe*BQ6LrdYpgkjmm_8P&Lkfnfuct1I+Ujj~oyH_W%G zJDAy)lAd4(nrK!msM&hM#tLZ@Oj^d?dZjQdS8i~V3hlpP)#%X$;~r$Cj-akSCy1gs zexc+xk4PAJ`7pKswIItC?CpW`Dkqo)g?gvzgb&f7Ax(hHr$t3s;4H%|NIcMFsm6JT zjmg$I5*re<_fEB1al+)_1L%RE1*|6!l^RAvAFgI$?s45=j;)QNT{GH`YSA7&^ry?1 z(}M(H+gn9&W4i(O!VaAKusQj_wQQE-EQEEoXq5;Y2?CA=0TTg0WC6Q&0c?jy0)Qhy zz|kOJA^<391;7`EM}yJ|0*(d&69GU;D*(PQoCr!Q2sj!9OauTWtpNC?)|4){g08fJ z9%=<~0@n(4Cq}Kf)`?3ijekbcil>6ZS}9#3tP55l2Fivelc#l^^E zwMLT}Lo0Z;grRx5RIDyz^azOdDsC6_4`q0qSB z+Zx+5A!tR~gMpqCwBkJzhF0XOcQ8=Y%9zi!;*#rf7Rg$v=)K@pin$_AWYqFo#eA-G zIMs9ogP$xbS~)CZSk%V?0&tZ&7XCpwb2qqKV`Yll7^ksrYeg+oIFZl8;&ud)9#eO= z*R9%79E1!x*kQ=I+;xk3IM>K;q0V_qsFgDe8d62A7?iKpI0QGfvw_*+ zG!}sYEX}ym$`Lvm2l&!7f3za?X^>Vp*8DBN3$Vt>1Zl?F$nBJ5p^NO6EUs4TTNO;5 zvYZSy!Q9!gt9~$Bot{})Mm0Dmbr8!19ujBj!b(dN19M~G912h*}tNQGdq z8&A&}-3WP%p zoV>XS;&de5$H|+f8%s9Cc}QD%Yz0u+Z4`d)uymZ>2DtN9mn+D+C0tJ4O+we zjY4*gaogtL1Gq`+I?9z~uEnlz8^sx~F1Fo6kS-6SPvsb?pMkcq>9NL-abw%9B%PX5 z%hD{gx|jp(98}7INS6o1&}JhC@{A<13=qP@P;PvG1JIUkR~r}0dJ1Gi-B@UfRcq5Z z)W#^Atss})P6hEqW@J+5TCPN#Xgw9-5~P5V(4O}3ZEv>zfoyI$U)ap?=IPta&P`&w zxd_mKQW2t>G8MZKb(_jw66(`YmxqzM{8u4TCDWGF%4AdzfO%q=tql>r)UNEb)g;p*3F^jLD_3D%kW=&|-|+`sx>k7?fnuCid3R85e7iEGWVBlA zfw0nAx@P1dJh;F!X`ghRvg&RjZVXuajy1g4NinU}lJ8>HH=O1zD-(N{~~%^Nf~+$uU>c zsYrFr7E4$I(4y^}G1gOcY3Pky-tx>>pfc>Lv8@Z*M#7NAnb1*aPldD+B4e~0AIivw z_jB6XX%s3q$~vlxk^;c?%uM@8U@^h!Isn1^`zTkdR_+=$VWlzDLNSl6hOJ83lB+BR zTF^-JrL5P^FOB8{kOD^-d@%ILW)R7m_XdPn3lNc8VA$$yfmNH6^o0?_7nW@1c6~5r zvk7#=v!|g==w=60nc4kz#oivpN#Huv+un=^RL|NwrZ9^)ns?i<&E?v5RF->v9ug0V zne|}wwwq%WQrUX*HlB;iyIvG;xmcFHo)ru0K3bFz*QiGJI~Tm}3o(7!!$c;qRj9HM zA#YgE?Yt03Ba-t%vN`T`8wMi2#*fUCC&=e=^{r{l?WCepwHi!#1CN( zjY-~*$gbP_loFG4vsi{<)5+oF4HLg;Sp_fbB6icE*F3REWorh9jStYQAcQL0Fz3Q0 zRMfL*$}#uqGzE8(#K$C3`K<~zh4U6}BGDKn2yWa2A{fI|K_DIi7zoc=LCKICMFM+T zTbPJ$W42rOXX0>d^>EY$t8q9IIXoP>erRT@i&m~CbyK!I^}V`NSJ1A=CtBu`P78aM-XgdwIoxg&5!F5n zP};L1o9f!n>Rl^ayH(jDlOf7QxPuLrMw@9Ih04KvWph0oo3*5K+k)tg$b#iCaoWwx zj3$-pU>Y6RU36eZg6(qGK4OU>`fgg17b}up-Z`<4bmgK8_r#?*{ChK94JDTLD{8X zhNIt5pcjQ2q2SEB+^h>LdsUWi+j6JWBc#T~Bnt068Rs3%HO%r%Ct+yk{**6K4 znSVK>NW+<|dt^1CsvbY_?z%|hQGG(8JD}Hcsj7OKujvk5?{W5_*9kO~Ngiw!2@Or}jB%ZtapswIT}v071QE|v9U z(Z7Ezg=qp^ZwhbtcAT-)++K%uANTs@sEu7``jnJftrEw~n;uZHw*zq01{lP4){#{D zLMlxnA>3<)fl$2JqT{s(AAw7YV*!hzGQONv5FeHlP-x<{L>k14IP)bUCkgN?q`4>^*mKlvE^1G^rbK(y~!HWeH^)EJ=N5UB277 z*Wla^A>6mfHN<;q3#$+%X9H!}!)~pm(vWn~33Bq7)-X?qdF71RmLMsL4}dKB!c?T* z2;?x0%_gh>B(m+tj*~1z>@evtU&+;qxpKn>VxC|QFDcHDbf3itLuPg_6d-aT`a)XX zwbEt`ZB?J%bAz^zsp_d%x{QO-kVn~tQPU-y+Tuwnp5DSd=sFKyKw6ZXmqe{|Hk*QZ zZ4c8d{j7mTrD3G@LuD6AmT=R#Qi&7p86>hvW(%kn?5E?XnGK<>W~sJ}&1(mQUF=*b zzeCd)7qxmW#yvWOQ?SKUYE!k!4VhSiiBXfF}ulr_p+NH%cD ze|-m~=Ls-3|FBDjcH6 zap}h1vQ^tI)`K~SDQ0s=-->WkH`~?=s6wmeg4fEJwnE_-_y`4Ok79cDQpn*5H-Z)^ znP~F(@~-&mF5WIB6k}m0-*6GOa8NH`Q{F|S<@h*X8gXGZ7p9ggdk|*vBk)FXy;wqR zxY2lUNIJyaj#ilbvIAo#K<@>a6VO*RL4MHZ`4PI@u0dd!w}CVe>m3hyIYsaDdjT^X zh`}LM*556|O-4qAqXF8p3SDGrues)?13Pt5zdBIhbW)VC4kPEcuVZ0tXb z#;$?!r#_3r>AY)%Ehj?ZENwv9Ql-%GxQ<~ST1sup`Ie=P4avu0xQ)XQ z$QO!!1QxY$7&d!@ulJzc)D4heSkL4(6>5|Mt_n9q3y2;RfSJI}6m!rbau0Hl`WiZ3 zRVfhkAUDZ8EM8bB%eynknwiJg6o!kw(ZDEdMQ4D~ZDAi4R~sIL1H?`#h9o&?V#Wpq z-KvKWvyV-_-2b!36CU|>{D@l9r|n5LZK225*^upReQ+M#if0QYdwNK3g`=N(sN4gI zQVLH{MtSV7*wp^1@Sss@Osz^=4LzthEQjcGuY{9D(9ovC=?FsI{G zQZZk|06hhR#|n>RI4QQw2$*wTc6wXB3gSICx!4&9zhSuBxk~5~FcX1&|2c!!aL%tY0J#Zwap+|K9CUaO|osc~)I)H84$9$&i z50v@x zE0$3MsB^W!>=qk=a7LiQbf}y_R_g%EWi0brhtLgW3+QD$ z6f8I{qQp}JTdO8yH38JKby0hA$DH==$GI;vLR%9ZeA-+QP_$Lt~VR}7`X$kDM5RGS$EDV;+Q7}-V6{Sf8^ zg6#()sTP=C&^eqy;*SH-@dJc&Zr2Ya=VsUjRjtF=XnuXdlv^4ldk+KF0rSvYeJ~Kc zU4^Zp+%S=#_p#Q1Nx2Lb+!f%LnUX{1x(S@ULk*+4bay2+Oh$L@Em^ojid|6Kb|+d- zU$b|Y!Ok)nMHPF7P`O(TO(%gQAHK8e(nx*?b1n7g2Q#|?V8Lb%g*KS z&|sldG7uAJ*)bsnZS+E#6?MX)hyBLgTy-INzO>*5?Jg$ev=8A+5uE@kYH?>C~uo@??F&(vLZ&HmG{q z)Btojr6vueZblz3Oxo8A$V%zG5GExOW3y=rOI8eP4~acQ*x9jDH(^g38VLDFc05eH zVO%qVUfb3;rKc+yC>Jd2@Cc)Y^|&1(6FyI=+lL-Ze$fQ7hlsU+UoWnfirWe&w>OKJ zX+Bh`Y{N`gm5a}6s?xyKY_+aGt3_V)UftP-o`-{7Jh&oA(l;P12;1f<=q^OZnj7Cr zHG2WMMnh-Ne-%gbRV?k4mK96^pdWWpVEP~do_ePdU6tkDVv@HOapQatgn zz`%(Af+#)l;$aF<0U%$1Y@^0^x2t4?k44jaFkiXZDVA!qCYenNo}|{RHRNk!J4_3;sL>eL+gQB=PMVL zS`N>NY|E;SK<_p_CW-cfk0{pLVx@=$h*<>^NZr)}b=HO%$I;P!)dPiPW3-0D921Z7dcb1v^n`Ki z!V}87@!44J-6*L5PjJKI&pS7$r2gDXQxeG&-0=7z_vUI99$1CaGlnqD!5DCLd^-SH zu`RpkEG4d}G1cH@7wJAr3(k9MD!t_TSq}5wg$vZPA7d;pxNuxP!nx5hw?~#XjPX#Zx{J9O9BSCX8O0jxI0Zc;c5yZ@7b3aBpi`;s zxj>fBT`5bId4hVGDtg@mEpm&=6V@v>F90%8@w~w83=U`nK{d_EWD?~+-z^~TA@7^< zXqwmgqSl;~>&h$^jD`+6cjL}4-ECMVZXan>*&SFA%q{T+3>&D7)h#SIW%zYt+hZ%9 z*cME4*d8}HS2HB|xI+t))cfaYoO{`*@KmTT?4#7HMhG--!9%#*IEP?-vGq|y-P!qO zlbv25+>ME;0?J;HrsCvePf#!;TAIW5P4F$8lD>y*g1H?@)56g+B|&%PMusnIhoM{e zG?h`CWqquUplIP1P=)}GH=&Y47t&HLf5;5FnCDca-I4)NH6 zb$d{?BOi*>yI4ZzW9CT><&lu|CE3HWx!#<}$I})UFhu+Cof;d0Nxs&lHsCN4KR;t! z!5Kt>J4}M$ZcI#nCp}Nr4eIZ%7i^O;+%!H;1j0t(A)&vVo zRj0#L1KtskSz!=d8~AnHY{SX!a;2&=_$#tW^>vScBfzr#Wv_MSi{;nq^CWXM1(SQJ zh@v~iTcugv0ZVyc!oZ%mM$kr&11xk|0>Q(g1-#_k8#Y^p2CH9cGy#9%J&80G-;3Fx z=~QP$rS%4--T20;mulQ_AWQ)=3ds5iz^W#vtt+S=2x;C6k)3RFJjiTr zEBzW9Y;|(e9t(3GD>ngiw#S4n;DUF`j+Fo4D*Ow9k z-eR+9^rXoSY2!++WQQqzeD=_LnB2y--geo-;a7{-Wte$~jKi*+jWtY~@sNG@2WOg* zZby~baWlH^?X!UtZubpD=X}%UCieNJlAwH2-Np#OLqIc?ZRbKl%g@2+Q*-*KVQg8p zm#zj%8PNlT_t7gXIII$DUOHnd9tVwFl1ycdC;x@iwb65n8Ni@B0{UE8(>r_EL~Dj< z_1Xf4f!O~a?!o! z2(8@T!sTR~<&`@wtvI7^VZpNXExk}0xQwXh3L;|0OKQ}a39+yq1loCS%|~7F#hH-U2gEnVJf;Xx;D>Z;(G9r3Ulz(LW}o7I1l2>e0MI zEwaORW^2VN;TET5o-p<-aLx_e;t<$IO{+TWfYL8R6pVxEnYx0-_sCb)fm{LW+F`G- z+fC>>kYol?E=U(}U@!J=X)bnP{q%laV$N^8?#24qzhhQrk}GnhnNbvx1qe=>AYQlV0C-U>hjn*nBIv zZr7kWLO3Yf)Rn4zeXbd;4?1FAXs*{ecr%l!%Z8iYqC*?o6CAWMA27y7R{*M|pE$7w zX;S|rKb}4`6{b!XIed`XD z$bJhX&xM4SL`xXi$R4-SC!ultUXC%=RbGZ76VT(53CNIR{7_uRM}g8(BF7O?AU)b~ zI%`8nBU)Ze147^lLM3~w1mN6cN}%w02v%DOs)ZZPaf&o`dlE702b}@Ee9-iD$~kh&@}?>KVAnn-I{d7!>tydD=bIAT+57NKZ9>*7;&(o9BnIABCN0T(`w> zGkpvYPdoDDqHb?P6@;$lwS891k;qrxYo0{dIZG=yfuXnDpOt7bvl;@;g& zu)`G-(UWm>!e*l@Ogk0aE3$K76hpPD!F3lddLjUx#cRh$5h6p7GRM4 z8ge-d>xoaMB6;S)AYR#E>v#c)-QMf>s)`>IlGE{= zceqQ$I_@grK$-s+dvVR1=L?))@D-)+wHt#+U7z0+RO_a-fLHMYM%6O5Q+540A=U=Z zi#Pz3+!wC;P;LNX=mvxfj*9rWc*AuEL((an)7fe`x$y*((0!N^cpxT&9*EAN2T=9+ zf%JrsNl!>v;kvk+I$8Mu>n_e%*F~A?6A6%fUfSm67;_>S>OG6b#89C{9ma0Fn6wP7 zfYB98a2cUAN@j4n_KjE1;bcV*&Z0j}K#vT(zlj9w-fI&!h3m%5Wzc%IY14`f+ZfI< zjo;J+XM`gA`f*he4b(?7cq0I|-AYEL-nUwXoe!|#3%$nkuB(<&nG-K4{1Bq-yQeY2Uz=p=5(90xol- zEz^>3&;2&_Z~WVu2eCp@)Jm})P$YLCrUhsam^gt7JtXYHk|>8my(YsM=Qs0UF=krga6 zU4!3}M~hWWkcAsws|D`F;u5~vrlrJ~LIi+=ZMdLa!X=&t?#^R+V&4UuFXFNq%#GXp zP#$o~3XW8#f5pPVRUQS_NH>UPlr`xR?tN&2*5I5?vD1} z6^%$>!1K?#^;(~WHWp-QJbNo#$qOhN#3hN^k}*Z`9Ed#blBX|)90#NE3Z{6m zvxKRcw3P;MOVtx(A(5<%PLf3@0Bebck_39uJV-4>-k^(d6`hPY-dhA5)@YR$l9o3T ziD?DqId+L2)a;5>q1wxV!8-(+S)E3DMpbhn+fJR@)fdl`r53n*Qq4(IaxbA~q(3{( zbJjYhxjYrfMzp$v@nyo)h(>Djk@ic)Xzz9Xd5x4%1Qx4w^adV)V@Hu^!nr2F=};mr zaFm2y6oU+dxCLaYQHPNV!DOT-`i872Y}S}w5)9hpZO*ouq;%}O@XSiLhO$$zwG_~I zphhU6vVUrq8*-(e{}usrs<8=tNIbj&9uUoeI^7laHSL0g9o8Fm^Q5my1 z7WJbk%QwNhx%EVHf#|Iw=7Kbt_7H9#jrQ@89%%U3LgQz36AB+UZ?1y5-Gsu&&6~0t z&u$p4l}y%~(Jmh>zj-~vQ>JPQ#HIE(96F$LQZT6DTJam4LIg>JZ7nrO3P2Oc&4jMG zfVado0`#%pIO}vH^PWaAG$N|AWfdBI8`A(4EIrR%@8&7?U1|ac#Z4SLz-Qs z>1l8cbz>oSB5o~nTqie2p@aC?Z6+G1nM(lD<>8lU$g_@J#|D@ChQ0%KW9F@Ee0m8~lxNFPeuMXp}w#J;!TFNUW7$t&v}>+>o`TJvlV5 zq?jujixs@RqA5I6Jye@BWAISe0u+SSzgC~Ugq5teHKle{b{7k&T`9;^4mUV(Tp4S1 zXPa3NkO}>R#De7*=L4{s-QxhP^P69WS781J>l4n>Eja z3L=)?FeoJvn4rDjY}NhUC)jgRW&EmYi8d0=m3L0H4-H~$39^L4jU{QPoc#W=c#Gn) zif|^YR@{{=7_WV^)&!SoIN~<7r?Pt<`=MNX#c4ME6~=fckll73%cOFCPoeUp89gBM z`DPGvAU~9f^UZt@8c$6zGMgpGmldS%f{_amomrScs9Mbm2UvXWgUR5w{l_v?(pZ!bu-vy-Hgdo(|NK- zrp_L&k7pCqW!Z$t`HtR-($Gr+3_Y45n;vJPq^lMK z<6A2UY7suQ=DXxA0DCJ}W6@Qtns`NS#Yb~#vdrYG+R+z4`Jf3c>nXlUh_}LMaM%89 z8KVaum(W4*1Oe@>JXL^WC-kSwkYpXwhePqMA=EvP^OYO&pnKhcm{W}Q&b%(EoDBy# z6g~%}VtI#=uP<^ZpoEuzYq{$Lh`lAXU4=JY=cU-Cnhrq&X!8wsfO*E7{n7EWci8aR z;zna{4kWL`OBTDfSG~BX%BrXu_{*u1N~#_BD{3Bpd4*?R@GU4ysps05l-gBQKiySgmUhOH>c>!^WRd?AXxrDS?a!WB) zye%TMEYYEuUgm}+VY%w~s*X8HMcuv%NJHwx&7(TTRJZY8PN|ctNH2$&Rd6unJ&C&^ zs80*2&q#dGy?|+y@P`A~5_1!Hw3;)T+7 zJpKKLaI%me=E_p*NMRl6kEs#BHsBk^e|caAkn#rLqwq1s5&Y!<83KI{IU0wLc^boi z%;g4L<|&UDEUA~%y2P_{oI`waWXv(d978yC$1>8afzEDM_EX4P=OdteOm!)BH~VQp zq-z>6C=puYWFY12-#K8_F_%i+b_uW=+Kg?xiFOZ?6Q`efB#|=Cd@waiGG!NX^Kx4o zZ30(8>SgIc3n=TNT0`%QD{o#x&wWthTPO*Z9pFKYMZW5G@}<78bxfLhPYnZI3S*bP?FSYP7L-? zTsA~Jjz`S(B4Sfxu@o$~)>0dQiu4V;{BAJ^cQM9wseL?5Ev333Y3%?;J+JO=rC3FY zs`!txVe04Zl;o3|*Vd@aA9YhrYJxJQUN#Fn%gH*WK4x0jVukDGL65lVE}akdGRg)= zX_k@wNNa30HV1B$`Wy1)D8pW5_p>#mp95c=qFw9iq$*L zgPh<52g*U&LVMobTIN>)%bIMUyqGY8PQ8Rw?wCfoV3{eWn^HHbbhi zt))_9?ub1F>J9wI6j{f9S)T{o8GT>u)uu<(`}nQVF{ikViS+gOqF%AuG(-3{@`g11 zvx}7Ey9gKWyd#Y|WH&%}4L8Sg=XkpIT6>4?k({AZirKGUCvB8O-D#Z;t^N{HQJb@` zP;0Oi*;4krjT)YFN;MWlNm$X$oxSZ#>5*CebDL*V&WQT_!%L*@sv|Z>S>`=(o|v@D z%l^oIO1W4?f1zY>#HU=d#BP7(c%gOpF5;*=veKT^C|({4|33Ye-#M8mKArjz>*8yA zUi`7YQIWU`MdP7RtPM`@?eunw_x|?V`--8y)3La^y>B~oQuW>5H{W(roeZ4}pN!nz zyZ@$8__o{o4xVvfC!=lgaHu;>9^rPf+y8?OGU?ra3g7*AhWbv$^!MOC1GsFy2^(>b z0mKM+f2eQ&i#BFXSRM=;g0v*ot$|l0vnN$FuKM;sa8N{s`DMmY#M8jj+tv~4J@}ls znNAfB^&RAT5B54cB7J+k`=9B1HArLlV-dn9PIh#M!@WHx^uOK%_+rOEx__YmKc>Qc z2M7B9<2|9sovPZpigoqwKk>YdwxHBw_;->m?!?m>@1;02HF}6O zi}pSl5;rVvqz{lL(&uz&NE6T7*vTPMOXinAer z-yvp8s!mpoP>WCa_M%DLB$yJ!&WH`F3B|snBjRCX7$Dbe5M?QfaBQbAQNGdK6#Ucu zEaVr#??gOemkI0TbFJx z_MBKp^!V}Py$4TA8+@Rrqm9yg@Q&VtH`ATy>WIc-K=&S;>jLiJX;NQ3-qE4Gz+LV3 zYKxQ6aQkU0i?4f>MQ{6=Cddmr+D?bj-F;*TdR0ugJ$AAqa+;OuW%eA2D(&P2qkh?y zPxlHJTkP7;^get$x?QFP$|mW%!q$wU6QkOwe11HPFDsVHPXo@h$555+oq`3oShOqD z`!JdW#OQckp?-9}_KuG5ZS5)0N^fnC#dzxn@qb?x4d2<>iN-x~;%dj;XWCBp?f+EY{;%}yKO2j6_8##6epU|?>^qq0 zZJg558=anP#tadZ#VJ#NuCMRlMBhO#+VKQ*B3Pmk{=7ql`;poY>*C1p zhV~AJV-&SmKN{~e6XGU!{)iHKMB)VoR&P^6Y5JGhaTvC977OCB?G*S$|dsPp0xBnsZ_q&nKOTzpY>x%U~9y^0Se!GwfjpX45a69EEYlrM z)0q7J7f*Dw_3eKNd6KBYD=wVo*mMoj&6Dm9u(BC(Y_i!oiN&7VBZKGPIwO@Kxii$> z#oWX?Wys=)B|ZEZRQz!k6prE~DFWSdTc{J@6CyDm6!(p&c0Hw%mQJI>`#aCHooVx` z=Lu-(i9V0MJ~#)+!8tF@RY0yn2cf7Xqif;oJ$N)0>+eB(K5Ey=+eO|U7PlY+`wvq* zA?NttD5TTKWheSzKlB;8$`h1#4C7FYk`>80$K$?(tKyb0(1X+=BqL zy^UaskDuTO)~&zYRP)ffn3$W1Z(m0{0w|w^A%A_ZhNjd3z(MzFPLNOE)d6`1-A7Ot zKZPP1dV@cMSv)d(vM;veAMOMd+-_gf0;t4vwaL2)n4_S zw#QHh>nRk}OsHR`W%F7!pgW)uphv{h77xWZB}L!FhXs^LGbp6AVKxstEOj!zR4w-) zzL}MgC4__X9I1?s)fsNEQo;p^^w{B|v9??nhbha^kPFISSOrrI23?({kG;x;M&oYcxbBOo!oUgbv0n zBuA%%P8`7K`)-5t4p2uwdJN9D82lFgMPneDquCw52Z;Y@{-1;?c~Wt+fhOk!7Rw`w z2K)(pH}FU77;xMyNZ?z*-vsE#)m#A{TCs*e$bA6rBqTtd5JueF(9y>cWehM{AjW~8 zfRCA2M|cC&C`_16h)z^RJ6RAI{Z$mXSJC5iPSEM5gTkn251n2*eRNL3VcGC6{gmx_ zcMn+m-F)e8rG`VG-HwZZwlXvaP> z2_N#UqNhOjoM3CiEB~Qp3@AXPpz8(YiYk;DdYwL{diFms7}|ep(_XUomNy>7)=yu% zH@}^q7&{j?5zX!0b8#GP;#2DPpC26Jf9K-n8PWU8)((z%;dIj|9=wuw{SSu#k7vW zedOoSaQiXC>9YAIY>xLBKn#VRL3S{oLUtZMMF#No9SkuIJ#QhuFG*0QI|x30*5)%8 zZa+@)hv{6UQ!t#<3^d^Ezuk%Zb_PGndO#%Dmq_wzI%t3BK;$J(_yoy5`Fv*JkP(hl z309pMvrfU=GH8-$IgFVyzHg-SD4qAvVbdH`>0{Fze2~ts&_Vt89_-V3n$9QLQm_ip zeM;Pq5d0LJ$Jvwze@W-r2-Y9q_;|l$NlzSIFY9w3@vvIx!g{eU(RUeAkDlE(L?_e6 z<=xpBhQq!!^a8+oIjIYskk!imXFA}=1nH+Rpu#)}YW57oIV*s(P+w+w69;AAX<*3< zAIFwyVm+f7K0_7<8NC*g59JuJ9x|j0bdN^k6TzYgR>w#PYh&ggIQ-uoqqnEGM+}na zgm=c0&w|Yu)|#9CMk488czWRH`ol@^J42 z7EW+`Cs0$zk7EYFDRAFCz`@KXb@YM0czXylHdrBPi0tPa^Nu(zK`kmG26!N%gNw>1 zd(U-YorR?}`Lto0+Iuc05sINU&TmflrNwAWqY{R5STPqI%C^Dt?^xs|jIribqh^<=(3>WX7=s1dHCQ^i9w&u&V-nJ}a)! z+6q);tjLT(vI&-@36|;ILXDxL!UbK=5cIcL&|uu5N$9qrPy|a7%o??6NZPBN0s?Bt z0hVy65(ppicYrT52#W@42BsjH=7CI_ROd{Z^s=23H0fouUpqy{ID%nL&Lof%OYHCQ9k3fGb5^9=onN7ItX~JbxAMy_q1Xfk_9lWxKb5Sg)zb>`$ zAr=tUfvz~r%5C@;>k_&8n7AJ&X;1H?UGX-4I*%PYhMJ(azq2zQ6&P#>+K1IRszJ!j z*QMz+(K=B>?IwOFOiaR}ySvjsxu7_1lXe;|-R8?mX4DggKquT4gH`3>Zb*bKwnznP zx{Ecf%kqSjasLU{0F(emDk=IGrHD^zooRD!#OEL9AgH?5lRr(^nPwV7LpNfoyCVHx9Cjs9mUOn&UnQ zpU|RkjUL_AzoN796-ijueLW|7P#NJ+Cwl!UmX6;ZQJx3qg!%v)2%7X$Ix0VC`KP#e z;CgTWDfDphe1@^1Oo^l=jK-&@q?SI6+5lH%0ogl^lAoshpdNpPwa}qc`AfaZz@nw^ z)G>f%{Q_HNT_fB&uF$`AN(_@^AqfnyCUwptUf5QX9?;T5Zo|SvSdaqV$?li zn$kR<1}o$YOn)k>LY@D7V(;GHDu6fC4RrrHprvlE*$ZDEmJLDR$*j?p>6FpM_n z{rg{%4C%@{FrNl1cmFHMyFl;^wvl(!Q>YzIz?p3g&N+Pz<1}1$4 zdhZi2TvW!8u9+cef~R#Wz8xBiN*5*WJqIDDHii$X8R93(78qOIi#Ejk$&;};utA?f zABA9dclWa;8K!U?N4YVN1qGz-87*|rh!2H+2C}*jrH2*g*?x9DYAJLJ?S-urQjdO! zz64trx(-ZC@O0DDE}j_L>=;agF)$LlMW>3yI{QITK;vP}ZtD19UFxg+U=oDF!_|Q| zO5lx}px{<<`V`g4!IR+p4$P&r@6CN02yLTbsH2ktA_4vf0{RsL9A^)9NJsKgK*K{C zK1%mMA?eeYC(5j#vl~OXW(|?*=|>e(MMh%%?B7qYqs#El0aZLbVHCD{Djs8c_#ag7 zgNRe7$e^oph2dcWabsli(PLo3FaACQB?%=4?Ex1#`X=&%(XopndAx58ZHH+qyALL= zsA{t%`w^+K30;2^67iE#fBT=LxWz@>;G*HBUiBx8h0WclE6AW2b`GEOp1|;ZaMq@i z#1c9&bO#y}wfW{a8q*1MAV4eBaZd_iVRVnfh^4s)jMzm)5;3E&b>uRI76?ogAREh| z;!L#%?FgOpQ70MC5CGGZJv2LLkIg6stQn(&&^jB-IvdM6MI_IyYktIsCe5Ico<@Df zdY~#pF=~8xbpYy^eFL13#Sfwa*b6At2)@w-@kNBro_>P+4z_yY9l#n}S@ zO%mGKkHH5N@O1X02ha-;|F0%zKw%+aUN?y#Y8nCVM*iONo+l;JKm8I9b+7FP8*mT31=arPY~PYa)e`y=ybR@M-*YN$3fo`J(ur6!(3=b&KySbTPMpyZ@=!J)A5cw+LdS z2T_Nh|1uK8AP8LIqrezSK#k!70nwB( zswIG^m0~(O2NOd7NivAT3!OvvAaRUI8jT^4gt7 zG;k^GkEkv@3|pw&sE;%Ja7bOu;I+s&o_X7<6yosJETodR3i0*5cr$Cf6YqaFebBxq zYVMWGl^gxQhf>*)y7CWYzH06QdGD?NWAc}qO@_HIEi}zPTIEO+nwzxZ2lM|ID#us( zoiHxTkBF+CkUDnx-bXG!7Qb@uBUc_%Y9gdYJ%G5>!M%^j=drlwF5bP5cmjynMwwO+ zOA2Q6!cMVpc5KvIAD@_*9GDnApBqSQ44sE>!WtM_w-RIdd~SSWeBvb`b#`ph+Sr&_ zpB$JRoyZR)awDJ{*%%p^9LujyB=Uv)#OOFo+L8cjhfxX>xx&!K*u=nCVlpw17#;%k zcz$fa%8yS@SYwmx`Hh68oR}V+PEE}w2a=;>GXsgq@zlW7^ki}%H90;ulAIVG8%sgf z$#Y`j{LDluH8n6XJv%axNFB2;BF7Af)!+;=Gu8?<0=)u{cyp4Np+O!hP=} zt{*Mz{AwZ!=lD@P&qH@8p(pfM92XpUJ=XII-@T8t!jK`>^3YH+F*Q0lGLRY_9veuE z4^0nD4o!^@%#Keb*i=J9)28Ll4^N~<&yNocOeH7K#)+Y^fr-h94GMo`c*>?6O(loNXTfB4BsGv=J|T9bOmwTx3 zs=17&l`O8wUbhN^@tH~-H`3!fbqjZo_TP@ye3Pw*L{$vh^2EnM0(rzYDz*5=4&SjC zHgONnIG+M`V!c8KujfiTR(w0R7te3y@N*}~Up!}XsOe`^kr|~fWAo*+zxB0Wy+0m+ZC`j{``f?ko4@jofBB;yefM2=%|DrW+vD&3!&5i@ z^;qe>zy6C)KmU`R*Pi-~e^Gw+KYip21E0J1>Tmv0p>Okxd)RSBVXD{Ei_5J_x?8koSfr&TWxNC0qyJyoccqE&y{p{Ob^*#Ub z=a))_ryuJ7kL9cJx!@pls2Y|D_2 z+wu1_D)cMJJCVPH@L7aE7zGaD?*jZ9V1Ge4{GY(zyWxKcR$Si;nj-l82EOkB?I^yp z`2H8*?gRYw;PZEY74UZj{vQMUC-E)d`z?Im0bbX!tJc$U^#x4M>67qfIi-BF+b<6w z!b|;oj7MF7c|FMgiJ#m)Bk#Q@^8t_zeY@9SeiM-v-4ovb7&l=CQCCAQOYe1o!;iFA z5h?CJGtTqg{`)YW2hrJ9qSmVdZD^{qw{k0H6ofCm^@}lOkjHO!H|7ZtCH_9wV}2JA z2fa65Zhk}NHpuo%y-|+7By&HzMeBWu)_XEl5Z*(=Te&LpqaZ%-C%)C&GQWwa&+%SO zAsc;R=Ffq8kr(9^9{-)07of+U_LA!E;a;1W2f_JPf>y!N!sWgDl0(${ZY3(y47xnC z5A|{G+qpmULg=D9kG?{a0?BD6=Q$f^wo3Df1`lXtm(kcIa?$tbls6)*u-|TA53WkKUw{pAYdqH?l z(6t#hV)F%?p8#p84P`GQ9r^P6HJej``s{05#atBhqTe!dRR zXkg+U&&Bnt3vvCx_+aP(S#~Cu)A78#bRA!};KS3ZCUUMExA>A{oR94Af%o_pn6F#l zi$^&ILuWa8Gry@Ps9dRr8P1*|;hS1kArx<>;zUj}F%%o5kY!n1zu^$y-l>x&o+`_) z5XT#pIG%`z^R)#-Smc|b@eMw%F&LjlrcL4WO9xni;}HwZY)~_~=Ov+6%GxcyQ7qx< z2c1T7yIQjNYzpRlR=kXf`*kbc^iyG|UeNQE;?Snlm}YYeS=EF$$*K@FXZ5A5l3b&a z%Wt7IOuH52*Dcp zQ*nD|`{h`{@Eba-UwV$u%+JU9gJ#GX=EQ6mle02fBlHSKswgcr`B4&3Qkd+Y#6!DP zwh5VANv*EUXYP#;?LIPe@8!or_pvM+cwUp!bW>0#^R%_dO#Qk(krc0NNVDNJ`ofJ| z&C)ed$1j}mrxXiuc@HVBA2VuUHW(Vdl&h7|G472g%bHe}5-5{?&`7!xYnmn{{2)VN zFf`;WXic9piv(8THs80_i{C+qEc8#@-(!nwVy;7+UsU08CG?U&n&#(-g!G&d1yqgQ z+0X>&?`(-2GP?!I#uAE8O%8@$W~l8ZuI-drV0I_IB!VY{r2e)mcsx0D(q+v;OHU5H zC(H&h7_B$3T*I$7N!x?Z9)8ma%(n4J6PIvxS!OXmm9p@@yk6OjkDebIJkfQfvZI$% z`VkW@!D zBf8VFA*9{yYce1kh1dZ57T6$zCLp**m zBNx|icg0Iqd9$&l3#+?V0~7|z2cn9w%V@0tZCS5Z@-V&F9e-9{${!4+btCI0bF`hO zD>x&|p`(dBiH8B?6-Tl{4}{qly#Q4P4N_~wb?NK!E;C14f9a%GZsEB#yF~I%5M$e> z4SAVJ|7y@+$oW<7R2jdW=IZUBF|uy#!G{l!b`qMIJ4TMWO3}&2P1WKVxA}8N52*LCRQB1a?|qZ#W#{<6Je^oJVXvkaXk9)DM z|4|Petje(S&6G+Dcw$P4Eyl723#F2ff9r1W=y~@YpZUb8yFLvor~Zcpsq91`1%-uz z!dzcrk}NPx#Bg&_@jVjx$Aif{m&{|y{Kq`QM5K5m`G5ZlssU`z0NfADo*%32+%QVF zz)3fUzsvh!bqWhe``@VuOs49hT2)!NDZFU1igyE+@ajeu-$mGgmW1@<(Xag-=FixL zV$1TBxc+{JgmfFTt-b$d5Wq$d&bHUUN58PaWh~#P;lHyY85v-Cd%o^_H9`o~hocn3 z5c0&AONyY{4B)gZH15kj37m*W9pHU{Uc{y0hcA{ejXim*L~h&zf3x>pn1@#h4?Fi< zkl;6IBrl#fKW>rNkkp#Z>mqpJr(;nnE|2+d81KtW;BQF&nD*_+KWj|CsKS>+N}dwj zEdPVJQ^2=4_zyd|;KlbJHiZjorHcA+-wRXd#tQAvG?xsVHO@5cJTs(g@7qaRx5F}c z^4+r?)SrGc=G$q9gw&m%M{^A}*WZN1NurMHDEBs`qJ$F1A(8%?Z;r?M`v2U&YFJTE PzK7lQfB*acT@Cy{==VTe literal 0 HcmV?d00001 diff --git a/lib-native/x64/FaceTrackData.dll b/runtimes/win-x64/native/FaceTrackData.dll similarity index 100% rename from lib-native/x64/FaceTrackData.dll rename to runtimes/win-x64/native/FaceTrackData.dll diff --git a/lib-native/x64/FaceTrackLib.dll b/runtimes/win-x64/native/FaceTrackLib.dll similarity index 100% rename from lib-native/x64/FaceTrackLib.dll rename to runtimes/win-x64/native/FaceTrackLib.dll diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/AnimationUnit.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/AnimationUnit.cs new file mode 100644 index 0000000..b3b73ef --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/AnimationUnit.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.AnimationUnit +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + public enum AnimationUnit + { + LipRaiser, + JawLower, + LipStretcher, + BrowLower, + LipCornerDepressor, + BrowRaiser, + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/CameraConfig.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/CameraConfig.cs new file mode 100644 index 0000000..5994487 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/CameraConfig.cs @@ -0,0 +1,65 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.CameraConfig +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [StructLayout(LayoutKind.Sequential)] + internal class CameraConfig + { + public const uint MaxResolution = 16384; + private readonly uint width; + private readonly uint height; + private readonly float focalLength; + private readonly FaceTrackingImageFormat imageFormat; + private readonly uint bytesPerPixel; + private readonly uint stride; + private readonly uint frameBufferLength; + + public CameraConfig( + uint width, + uint height, + float focalLength, + FaceTrackingImageFormat imageFormat) + { + this.width = width; + this.height = height; + this.focalLength = focalLength; + this.imageFormat = imageFormat; + this.bytesPerPixel = Image.FormatToSize(this.imageFormat); + this.stride = this.width * this.bytesPerPixel; + switch (this.imageFormat) + { + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_GR8: + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_R8G8B8: + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_X8R8G8B8: + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_A8R8G8B8: + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_B8G8R8X8: + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_B8G8R8A8: + this.frameBufferLength = this.height * this.stride; + break; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT16_D16: + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT16_D13P3: + this.frameBufferLength = this.height * this.width; + break; + default: + throw new ArgumentException("Invalid image format specified"); + } + } + + public uint Width => this.width; + + public uint Height => this.height; + + public FaceTrackingImageFormat ImageFormat => this.imageFormat; + + public uint Stride => this.stride; + + public uint FrameBufferLength => this.frameBufferLength; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/EnumIndexableCollection`2.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/EnumIndexableCollection`2.cs new file mode 100644 index 0000000..a5b1efa --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/EnumIndexableCollection`2.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.EnumIndexableCollection`2 +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + public class EnumIndexableCollection : IEnumerable, IEnumerable + { + private readonly TValue[] valueArray; + + internal EnumIndexableCollection(TValue[] valueArray) => this.valueArray = valueArray; + + public int Count => this.valueArray == null ? 0 : ((IEnumerable) this.valueArray).Count(); + + public TValue this[int index] => this.valueArray != null ? this.valueArray[index] : throw new InvalidOperationException(); + + public TValue this[TIndex index] + { + get + { + if (this.valueArray == null) + throw new InvalidOperationException(); + return this.valueArray[(int) Convert.ChangeType((object) index, typeof (int), (IFormatProvider) CultureInfo.InvariantCulture)]; + } + } + + IEnumerator IEnumerable.GetEnumerator() => (IEnumerator) this.GetEnumerator(); + + public IEnumerator GetEnumerator() => this.valueArray == null ? Enumerable.Empty().GetEnumerator() : ((IEnumerable) this.valueArray).AsEnumerable().GetEnumerator(); + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/ErrorCode.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/ErrorCode.cs new file mode 100644 index 0000000..bb101db --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/ErrorCode.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.ErrorCode +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal enum ErrorCode + { + InvalidModels = -1884553215, // 0x8FAC0001 + InvalidInputImage = -1884553214, // 0x8FAC0002 + FaceDetectorFailed = -1884553213, // 0x8FAC0003 + ActiveAppearanceModelFailed = -1884553212, // 0x8FAC0004 + NeuralNetworkFailed = -1884553211, // 0x8FAC0005 + FaceTrackerUninitialized = -1884553210, // 0x8FAC0006 + InvalidModelPath = -1884553209, // 0x8FAC0007 + EvaluationFailed = -1884553208, // 0x8FAC0008 + InvalidCameraConfig = -1884553207, // 0x8FAC0009 + Invalid3DHint = -1884553206, // 0x8FAC000A + HeadSearchFailed = -1884553205, // 0x8FAC000B + UserLost = -1884553204, // 0x8FAC000C + KinectDllLoadFailed = -1884553203, // 0x8FAC000D + Success = 0, + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceModel.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceModel.cs new file mode 100644 index 0000000..b351263 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceModel.cs @@ -0,0 +1,190 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FaceModel +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal class FaceModel : IDisposable + { + private readonly FaceTracker faceTracker; + private bool disposed; + private IFTModel faceTrackingModelPtr; + + internal FaceModel(FaceTracker faceTracker, IFTModel faceModelPtr) + { + this.faceTrackingModelPtr = faceTracker != null && faceModelPtr != null ? faceModelPtr : throw new InvalidOperationException("Cannot associate face model with null face tracker or native face model reference"); + this.faceTracker = faceTracker; + } + + private FaceModel() + { + } + + ~FaceModel() => this.Dispose(false); + + public uint VertexCount + { + get + { + this.CheckPtrAndThrow(); + return this.faceTrackingModelPtr.GetVertexCount(); + } + } + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize((object) this); + } + + public Vector3DF[] Get3DShape(FaceTrackFrame faceTrackFrame) + { + uint shapeUnitCount = 0; + IntPtr animUnitCoeffPtr; + uint animUnitCount; + faceTrackFrame.ResultPtr.GetAUCoefficients(out animUnitCoeffPtr, out animUnitCount); + IntPtr shapeUnitCoeffsPtr; + this.faceTracker.FaceTrackerPtr.GetShapeUnits(out float _, out shapeUnitCoeffsPtr, ref shapeUnitCount, out bool _); + return this.Get3DShape(shapeUnitCoeffsPtr, shapeUnitCount, animUnitCoeffPtr, animUnitCount, faceTrackFrame.Scale, faceTrackFrame.Rotation, faceTrackFrame.Translation); + } + + public PointF[] GetProjected3DShape( + float zoomFactor, + Point viewOffset, + FaceTrackFrame faceTrackFrame) + { + this.CheckPtrAndThrow(); + uint shapeUnitCount = 0; + IntPtr animUnitCoeffPtr; + uint animUnitCount; + faceTrackFrame.ResultPtr.GetAUCoefficients(out animUnitCoeffPtr, out animUnitCount); + IntPtr shapeUnitCoeffsPtr; + this.faceTracker.FaceTrackerPtr.GetShapeUnits(out float _, out shapeUnitCoeffsPtr, ref shapeUnitCount, out bool _); + return this.GetProjected3DShape(this.faceTracker.ColorCameraConfig, zoomFactor, viewOffset, shapeUnitCoeffsPtr, shapeUnitCount, animUnitCoeffPtr, animUnitCount, faceTrackFrame.Scale, faceTrackFrame.Rotation, faceTrackFrame.Translation); + } + + public FaceTriangle[] GetTriangles() + { + this.CheckPtrAndThrow(); + IntPtr trianglesPtr; + uint triangleCount; + this.faceTrackingModelPtr.GetTriangles(out trianglesPtr, out triangleCount); + FaceTriangle[] triangles = (FaceTriangle[]) null; + if (triangleCount > 0U) + { + triangles = new FaceTriangle[(int) triangleCount]; + for (int index = 0; (long) index < (long) triangleCount; ++index) + { + triangles[index] = new FaceTriangle(); + IntPtr ptr = IntPtr.Size != 8 ? new IntPtr(trianglesPtr.ToInt32() + index * Marshal.SizeOf(typeof (FaceTriangle))) : new IntPtr(trianglesPtr.ToInt64() + (long) (index * Marshal.SizeOf(typeof (FaceTriangle)))); + triangles[index] = (FaceTriangle) Marshal.PtrToStructure(ptr, typeof (FaceTriangle)); + } + } + return triangles; + } + + protected virtual void Dispose(bool disposing) + { + if (this.disposed) + return; + if (this.faceTrackingModelPtr != null) + { + Marshal.FinalReleaseComObject((object) this.faceTrackingModelPtr); + this.faceTrackingModelPtr = (IFTModel) null; + } + this.disposed = true; + } + + private void CheckPtrAndThrow() + { + if (this.faceTrackingModelPtr == null) + throw new InvalidOperationException("Native face model pointer in invalid state."); + } + + private Vector3DF[] Get3DShape( + IntPtr shapeUnitCoeffPtr, + uint shapeUnitCoeffCount, + IntPtr animUnitCoeffPtr, + uint animUnitCoeffCount, + float scale, + Vector3DF rotation, + Vector3DF translation) + { + this.CheckPtrAndThrow(); + Vector3DF[] vector3DfArray = (Vector3DF[]) null; + uint vertexCount = this.VertexCount; + IntPtr num = IntPtr.Zero; + if (shapeUnitCoeffPtr == IntPtr.Zero || shapeUnitCoeffCount == 0U) + throw new ArgumentException("Invalid shape unit co-efficients", nameof (shapeUnitCoeffPtr)); + if (animUnitCoeffPtr == IntPtr.Zero || animUnitCoeffCount == 0U) + throw new ArgumentException("Invalid animation unit co-efficients", nameof (animUnitCoeffPtr)); + if (vertexCount > 0U) + { + try + { + num = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (Vector3DF)) * (int) vertexCount); + this.faceTrackingModelPtr.Get3DShape(shapeUnitCoeffPtr, shapeUnitCoeffCount, animUnitCoeffPtr, animUnitCoeffCount, scale, ref rotation, ref translation, num, vertexCount); + vector3DfArray = new Vector3DF[(int) vertexCount]; + for (int index = 0; index < (int) vertexCount; ++index) + { + IntPtr ptr = IntPtr.Size != 8 ? new IntPtr(num.ToInt32() + index * Marshal.SizeOf(typeof (Vector3DF))) : new IntPtr(num.ToInt64() + (long) (index * Marshal.SizeOf(typeof (Vector3DF)))); + vector3DfArray[index] = (Vector3DF) Marshal.PtrToStructure(ptr, typeof (Vector3DF)); + } + } + finally + { + if (num != IntPtr.Zero) + Marshal.FreeHGlobal(num); + } + } + return vector3DfArray; + } + + private PointF[] GetProjected3DShape( + CameraConfig videoCameraConfig, + float zoomFactor, + Point viewOffset, + IntPtr shapeUnitCoeffPtr, + uint shapeUnitCoeffCount, + IntPtr animUnitCoeffPtr, + uint animUnitCoeffCount, + float scale, + Vector3DF rotation, + Vector3DF translation) + { + this.CheckPtrAndThrow(); + PointF[] projected3Dshape = (PointF[]) null; + uint vertexCount = this.VertexCount; + IntPtr num = IntPtr.Zero; + if (shapeUnitCoeffPtr == IntPtr.Zero || shapeUnitCoeffCount == 0U) + throw new ArgumentException("Invalid shape unit co-efficients", nameof (shapeUnitCoeffPtr)); + if (animUnitCoeffPtr == IntPtr.Zero || animUnitCoeffCount == 0U) + throw new ArgumentException("Invalid animation unit co-efficients", nameof (animUnitCoeffPtr)); + if (vertexCount > 0U) + { + try + { + num = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (Vector3DF)) * (int) vertexCount); + this.faceTrackingModelPtr.GetProjectedShape(videoCameraConfig, zoomFactor, viewOffset, shapeUnitCoeffPtr, shapeUnitCoeffCount, animUnitCoeffPtr, animUnitCoeffCount, scale, ref rotation, ref translation, num, vertexCount); + projected3Dshape = new PointF[(int) vertexCount]; + for (int index = 0; index < (int) vertexCount; ++index) + { + IntPtr ptr = IntPtr.Size != 8 ? new IntPtr(num.ToInt32() + index * Marshal.SizeOf(typeof (PointF))) : new IntPtr(num.ToInt64() + (long) (index * Marshal.SizeOf(typeof (PointF)))); + projected3Dshape[index] = (PointF) Marshal.PtrToStructure(ptr, typeof (PointF)); + } + } + finally + { + if (num != IntPtr.Zero) + Marshal.FreeHGlobal(num); + } + } + return projected3Dshape; + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackFrame.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackFrame.cs new file mode 100644 index 0000000..a2180a2 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackFrame.cs @@ -0,0 +1,168 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FaceTrackFrame +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + public sealed class FaceTrackFrame : IDisposable, ICloneable + { + private bool disposed; + private IFTResult faceTrackingResultPtr; + private WeakReference parentFaceTracker; + + internal FaceTrackFrame(IFTResult faceTrackResultPtr, FaceTracker parentTracker) + { + this.faceTrackingResultPtr = faceTrackResultPtr != null ? faceTrackResultPtr : throw new InvalidOperationException("Cannot associate with a null native frame pointer"); + this.parentFaceTracker = new WeakReference((object) parentTracker, false); + } + + private FaceTrackFrame() + { + } + + ~FaceTrackFrame() => this.InternalDispose(); + + public Rect FaceRect + { + get + { + this.CheckPtrAndThrow(); + Rect rect; + this.faceTrackingResultPtr.GetFaceRect(out rect); + return rect; + } + } + + public Vector3DF Rotation + { + get + { + this.CheckPtrAndThrow(); + Vector3DF rotationXYZ; + this.faceTrackingResultPtr.Get3DPose(out float _, out rotationXYZ, out Vector3DF _); + return rotationXYZ; + } + } + + public bool TrackSuccessful => this.Status == ErrorCode.Success; + + public Vector3DF Translation + { + get + { + this.CheckPtrAndThrow(); + Vector3DF translationXYZ; + this.faceTrackingResultPtr.Get3DPose(out float _, out Vector3DF _, out translationXYZ); + return translationXYZ; + } + } + + internal IFTResult ResultPtr => this.faceTrackingResultPtr; + + internal float Scale + { + get + { + this.CheckPtrAndThrow(); + float scale; + this.faceTrackingResultPtr.Get3DPose(out scale, out Vector3DF _, out Vector3DF _); + return scale; + } + } + + internal ErrorCode Status + { + get + { + this.CheckPtrAndThrow(); + return (ErrorCode) this.faceTrackingResultPtr.GetStatus(); + } + } + + public object Clone() + { + this.CheckPtrAndThrow(); + if (!(this.parentFaceTracker.Target is FaceTracker target)) + throw new ObjectDisposedException("FaceTracker", "Underlying face object has been garbage collected. Cannot clone."); + int hr; + FaceTrackFrame result = target.CreateResult(out hr); + if (result == null || hr != 0) + throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, "Failed to create face tracking frame. Error code from native=0x{0:X}", (object) hr)); + int num = this.faceTrackingResultPtr.CopyTo(result.ResultPtr); + if (num != 0) + throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, "Failed to clone the source face tracking frame. Error code from native=0x{0:X}", (object) num)); + return (object) result; + } + + public void Dispose() + { + this.InternalDispose(); + GC.SuppressFinalize((object) this); + } + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Analysis doesn't see these as arrays. If this returned an actual array, we wouldn't see this warning.")] + public EnumIndexableCollection Get3DShape() + { + if (!(this.parentFaceTracker.Target is FaceTracker target)) + throw new ObjectDisposedException("FaceTracker", "Underlying face object has been garbage collected. Cannot copy."); + return new EnumIndexableCollection(target.FaceModel.Get3DShape(this)); + } + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Analysis doesn't see these as arrays. If this returned an actual array, we wouldn't see this warning.")] + public EnumIndexableCollection GetAnimationUnitCoefficients() + { + this.CheckPtrAndThrow(); + IntPtr animUnitCoeffPtr; + uint animUnitCount; + this.faceTrackingResultPtr.GetAUCoefficients(out animUnitCoeffPtr, out animUnitCount); + float[] numArray = (float[]) null; + if (animUnitCount > 0U) + { + numArray = new float[(int) animUnitCount]; + Marshal.Copy(animUnitCoeffPtr, numArray, 0, numArray.Length); + } + return new EnumIndexableCollection(numArray); + } + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Analysis doesn't see these as arrays. If this returned an actual array, we wouldn't see this warning.")] + public EnumIndexableCollection GetProjected3DShape() + { + if (!(this.parentFaceTracker.Target is FaceTracker target)) + throw new ObjectDisposedException("FaceTracker", "Underlying face object has been garbage collected. Cannot copy."); + return new EnumIndexableCollection(target.FaceModel.GetProjected3DShape(1f, Point.Empty, this)); + } + + public FaceTriangle[] GetTriangles() + { + if (!(this.parentFaceTracker.Target is FaceTracker target)) + throw new ObjectDisposedException("FaceTracker", "Underlying face object has been garbage collected. Cannot copy."); + return target.FaceModel.GetTriangles(); + } + + private void CheckPtrAndThrow() + { + if (this.faceTrackingResultPtr == null) + throw new InvalidOperationException("Native frame pointer in invalid state."); + } + + private void InternalDispose() + { + if (this.disposed) + return; + if (this.faceTrackingResultPtr != null) + { + Marshal.FinalReleaseComObject((object) this.faceTrackingResultPtr); + this.faceTrackingResultPtr = (IFTResult) null; + } + this.parentFaceTracker = (WeakReference) null; + this.disposed = true; + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTracker.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTracker.cs new file mode 100644 index 0000000..2bf49da --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTracker.cs @@ -0,0 +1,349 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FaceTracker +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Configuration; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + public class FaceTracker : IDisposable + { + internal const float DefaultZoomFactor = 1f; + private const string FaceTrackTraceSwitchName = "KinectForWindowsFaceTracking"; + private const string TraceCategory = "FTR"; + private const string TraceLogFileName = "TraceLogFile"; + private readonly Stopwatch copyStopwatch = new Stopwatch(); + private readonly ColorImageFormat initializationColorImageFormat; + private readonly DepthImageFormat initializationDepthImageFormat; + private readonly OperationMode operationMode; + private readonly KinectSensor sensor; + private readonly Stopwatch startOrContinueTrackingStopwatch = new Stopwatch(); + private readonly Stopwatch trackStopwatch = new Stopwatch(); + private Image colorFaceTrackingImage; + private CameraConfig depthCameraConfig; + private Image depthFaceTrackingImage; + private bool disposed; + private FaceModel faceModel; + private IFTFaceTracker faceTrackerInteropPtr; + private FaceTrackFrame frame; + private long lastSuccessTrackElapsedMs; + private FaceTrackingRegisterDepthToColor registerDepthToColorDelegate; + private long totalSuccessTrackMs; + private int totalSuccessTracks; + private int totalTracks; + private TraceLevel traceLevel; + private bool trackSucceeded; + private CameraConfig videoCameraConfig; + + static FaceTracker() + { + try + { + string appSetting = ConfigurationManager.AppSettings["TraceLogFile"]; + if (string.IsNullOrEmpty(appSetting)) + return; + foreach (TraceListener listener in Trace.Listeners) + { + if (listener is DefaultTraceListener defaultTraceListener) + { + defaultTraceListener.LogFileName = appSetting; + break; + } + } + DateTime now = DateTime.Now; + Trace.WriteLine(string.Format((IFormatProvider) CultureInfo.InvariantCulture, "---------------------------------------------------------------------------")); + Trace.WriteLine(string.Format((IFormatProvider) CultureInfo.InvariantCulture, "Starting Trace. Time={0} {1}, Machine={2}, Processor={3}, OS={4}", (object) now.ToShortDateString(), (object) now.ToLongTimeString(), (object) Environment.MachineName, Environment.Is64BitProcess ? (object) "64bit" : (object) "32bit", (object) Environment.OSVersion)); + Trace.WriteLine(string.Format((IFormatProvider) CultureInfo.InvariantCulture, "---------------------------------------------------------------------------")); + } + catch (Exception ex) + { + Trace.WriteLine(string.Format((IFormatProvider) CultureInfo.InvariantCulture, "Failed to set logfile for logging trace output. Exception={0}", (object) ex)); + throw; + } + } + + public FaceTracker(KinectSensor sensor) + { + if (sensor == null) + throw new ArgumentNullException(nameof (sensor)); + if (!sensor.ColorStream.IsEnabled) + throw new InvalidOperationException("Color stream is not enabled yet."); + if (!sensor.DepthStream.IsEnabled) + throw new InvalidOperationException("Depth stream is not enabled yet."); + this.operationMode = OperationMode.Kinect; + this.sensor = sensor; + this.initializationColorImageFormat = sensor.ColorStream.Format; + this.initializationDepthImageFormat = sensor.DepthStream.Format; + this.Initialize(new CameraConfig((uint) sensor.ColorStream.FrameWidth, (uint) sensor.ColorStream.FrameHeight, sensor.ColorStream.NominalFocalLengthInPixels, FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_B8G8R8X8), new CameraConfig((uint) sensor.DepthStream.FrameWidth, (uint) sensor.DepthStream.FrameHeight, sensor.DepthStream.NominalFocalLengthInPixels, FaceTrackingImageFormat.FTIMAGEFORMAT_UINT16_D13P3), IntPtr.Zero, IntPtr.Zero, new FaceTrackingRegisterDepthToColor(this.DepthToColorCallback)); + } + + ~FaceTracker() => this.Dispose(false); + + internal CameraConfig ColorCameraConfig => this.videoCameraConfig; + + internal FaceModel FaceModel + { + get + { + this.CheckPtrAndThrow(); + if (this.faceModel == null) + { + IFTModel model; + this.faceTrackerInteropPtr.GetFaceModel(out model); + this.faceModel = new FaceModel(this, model); + } + return this.faceModel; + } + } + + internal IFTFaceTracker FaceTrackerPtr => this.faceTrackerInteropPtr; + + internal Stopwatch Stopwatch => this.trackStopwatch; + + internal int TotalTracks => this.totalTracks; + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize((object) this); + } + + public void ResetTracking() + { + this.CheckPtrAndThrow(); + this.trackSucceeded = false; + this.faceTrackerInteropPtr.Reset(); + } + + public FaceTrackFrame Track( + ColorImageFormat colorImageFormat, + byte[] colorImage, + DepthImageFormat depthImageFormat, + short[] depthImage, + Skeleton skeletonOfInterest) + { + return this.Track(colorImageFormat, colorImage, depthImageFormat, depthImage, skeletonOfInterest, Rect.Empty); + } + + public FaceTrackFrame Track( + ColorImageFormat colorImageFormat, + byte[] colorImage, + DepthImageFormat depthImageFormat, + short[] depthImage, + Rect regionOfInterest) + { + return this.Track(colorImageFormat, colorImage, depthImageFormat, depthImage, (Skeleton) null, regionOfInterest); + } + + public FaceTrackFrame Track( + ColorImageFormat colorImageFormat, + byte[] colorImage, + DepthImageFormat depthImageFormat, + short[] depthImage) + { + return this.Track(colorImageFormat, colorImage, depthImageFormat, depthImage, (Skeleton) null, Rect.Empty); + } + + internal FaceTrackFrame CreateResult(out int hr) + { + FaceTrackFrame result = (FaceTrackFrame) null; + this.CheckPtrAndThrow(); + IFTResult faceTrackResult; + hr = this.faceTrackerInteropPtr.CreateFTResult(out faceTrackResult); + if (faceTrackResult != null) + result = new FaceTrackFrame(faceTrackResult, this); + return result; + } + + protected virtual void Dispose(bool disposing) + { + if (this.disposed) + return; + Trace.WriteLineIf(this.traceLevel >= TraceLevel.Info, string.Format((IFormatProvider) CultureInfo.InvariantCulture, "FaceTracker::Dispose() - TotalTracks={0}, TotalSuccessTracks={1}, TimePerTrack={2:F3}ms, TimePerSuccessTrack={3:F3}ms, TimePerDataCopy={4:F3}ms, TimePerStartOrContinueTracking={5:F3}ms", (object) this.totalTracks, (object) this.totalSuccessTracks, (object) (this.totalTracks > 0 ? (double) this.trackStopwatch.ElapsedMilliseconds / (double) this.totalTracks : 0.0), (object) (this.totalSuccessTracks > 0 ? (double) this.totalSuccessTrackMs / (double) this.totalSuccessTracks : 0.0), (object) (this.totalTracks > 0 ? (double) this.copyStopwatch.ElapsedMilliseconds / (double) this.totalTracks : 0.0), (object) (this.totalTracks > 0 ? (double) this.startOrContinueTrackingStopwatch.ElapsedMilliseconds / (double) this.totalTracks : 0.0))); + if (this.faceModel != null) + { + this.faceModel.Dispose(); + this.faceModel = (FaceModel) null; + } + if (this.frame != null) + { + this.frame.Dispose(); + this.frame = (FaceTrackFrame) null; + } + if (this.colorFaceTrackingImage != null) + { + this.colorFaceTrackingImage.Dispose(); + this.colorFaceTrackingImage = (Image) null; + } + if (this.depthFaceTrackingImage != null) + { + this.depthFaceTrackingImage.Dispose(); + this.depthFaceTrackingImage = (Image) null; + } + if (this.faceTrackerInteropPtr != null) + { + Marshal.FinalReleaseComObject((object) this.faceTrackerInteropPtr); + this.faceTrackerInteropPtr = (IFTFaceTracker) null; + } + this.disposed = true; + } + + private static Vector3DF[] GetHeadPointsFromSkeleton(Skeleton skeletonOfInterest) + { + Vector3DF[] pointsFromSkeleton = (Vector3DF[]) null; + if (skeletonOfInterest != null && skeletonOfInterest.TrackingState == SkeletonTrackingState.Tracked) + { + pointsFromSkeleton = new Vector3DF[2]; + SkeletonPoint position1 = skeletonOfInterest.Joints[JointType.ShoulderCenter].Position; + pointsFromSkeleton[0] = new Vector3DF(position1.X, position1.Y, position1.Z); + SkeletonPoint position2 = skeletonOfInterest.Joints[JointType.Head].Position; + pointsFromSkeleton[1] = new Vector3DF(position2.X, position2.Y, position2.Z); + } + return pointsFromSkeleton; + } + + private void CheckPtrAndThrow() + { + if (this.faceTrackerInteropPtr == null) + throw new InvalidOperationException("Native face tracker pointer in invalid state."); + } + + private int DepthToColorCallback( + uint depthFrameWidth, + uint depthFrameHeight, + uint colorFrameWidth, + uint colorFrameHeight, + float zoomFactor, + Point viewOffset, + int depthX, + int depthY, + ushort depthZ, + out int colorX, + out int colorY) + { + int colorCallback = 0; + colorX = 0; + colorY = 0; + if (this.sensor != null) + { + ColorImagePoint colorImagePoint = new ColorImagePoint(); + try + { + colorImagePoint = this.sensor.CoordinateMapper.MapDepthPointToColorPoint(this.sensor.DepthStream.Format, new DepthImagePoint() + { + X = depthX, + Y = depthY, + Depth = (int) depthZ + }, this.sensor.ColorStream.Format); + } + catch (InvalidOperationException ex) + { + Trace.WriteLineIf(this.traceLevel >= TraceLevel.Error, string.Format((IFormatProvider) CultureInfo.CurrentCulture, "Exception on MapDepthToColorImagePoint while translating depth point({0},{1},{2}). Exception={3}", (object) depthX, (object) depthY, (object) depthZ, (object) ex.Message), "FTR"); + colorCallback = -1; + } + colorX = colorImagePoint.X; + colorY = colorImagePoint.Y; + } + else + colorCallback = -1; + return colorCallback; + } + + private void Initialize( + CameraConfig newColorCameraConfig, + CameraConfig newDepthCameraConfig, + IntPtr colorImagePtr, + IntPtr depthImagePtr, + FaceTrackingRegisterDepthToColor newRegisterDepthToColorDelegate) + { + if (newColorCameraConfig == null) + throw new ArgumentNullException(nameof (newColorCameraConfig)); + if (newDepthCameraConfig == null) + throw new ArgumentNullException(nameof (newDepthCameraConfig)); + if (newRegisterDepthToColorDelegate == null) + throw new ArgumentNullException(nameof (newRegisterDepthToColorDelegate)); + this.totalTracks = 0; + this.trackStopwatch.Reset(); + this.traceLevel = new TraceSwitch("KinectForWindowsFaceTracking", "KinectForWindowsFaceTracking").Level; + this.videoCameraConfig = newColorCameraConfig; + this.depthCameraConfig = newDepthCameraConfig; + this.registerDepthToColorDelegate = newRegisterDepthToColorDelegate; + this.faceTrackerInteropPtr = NativeMethods.FTCreateFaceTracker(IntPtr.Zero); + if (this.faceTrackerInteropPtr == null) + throw new InsufficientMemoryException("Cannot create face tracker."); + IntPtr pointerForDelegate = Marshal.GetFunctionPointerForDelegate(this.registerDepthToColorDelegate); + if (pointerForDelegate == IntPtr.Zero) + throw new InsufficientMemoryException("Cannot setup callback for retrieving color to depth pixel mapping"); + int hr = this.faceTrackerInteropPtr.Initialize(this.videoCameraConfig, this.depthCameraConfig, pointerForDelegate, (string) null); + this.frame = hr == 0 ? this.CreateResult(out hr) : throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, "Failed to initialize face tracker - Error code from native=0x{0:X}", (object) hr)); + if (this.frame == null || hr != 0) + throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, "Failed to create face tracking result. Error code from native=0x{0:X}", (object) hr)); + this.colorFaceTrackingImage = new Image(); + if (colorImagePtr == IntPtr.Zero) + this.colorFaceTrackingImage.Allocate(this.videoCameraConfig.Width, this.videoCameraConfig.Height, this.videoCameraConfig.ImageFormat); + else + this.colorFaceTrackingImage.Attach(this.videoCameraConfig.Width, this.videoCameraConfig.Height, colorImagePtr, this.videoCameraConfig.ImageFormat, this.videoCameraConfig.Stride); + this.depthFaceTrackingImage = new Image(); + if (depthImagePtr == IntPtr.Zero) + this.depthFaceTrackingImage.Allocate(this.depthCameraConfig.Width, this.depthCameraConfig.Height, this.depthCameraConfig.ImageFormat); + else + this.depthFaceTrackingImage.Attach(this.depthCameraConfig.Width, this.depthCameraConfig.Height, depthImagePtr, this.depthCameraConfig.ImageFormat, this.depthCameraConfig.Stride); + } + + private FaceTrackFrame Track( + ColorImageFormat colorImageFormat, + byte[] colorImage, + DepthImageFormat depthImageFormat, + short[] depthImage, + Skeleton skeletonOfInterest, + Rect regionOfInterest) + { + ++this.totalTracks; + this.trackStopwatch.Start(); + if (this.operationMode != OperationMode.Kinect) + throw new InvalidOperationException("Cannot use Track with Kinect input types when face tracker is initialized for tracking videos/images"); + if (colorImage == null) + throw new ArgumentNullException(nameof (colorImage)); + if (depthImage == null) + throw new ArgumentNullException(nameof (depthImage)); + if (colorImageFormat != this.initializationColorImageFormat) + throw new InvalidOperationException("Color image frame format different from initialization"); + if (depthImageFormat != this.initializationDepthImageFormat) + throw new InvalidOperationException("Depth image frame format different from initialization"); + if ((long) colorImage.Length != (long) this.videoCameraConfig.FrameBufferLength) + throw new ArgumentOutOfRangeException(nameof (colorImage), "Color image data size is needs to match initialization configuration."); + if ((long) depthImage.Length != (long) this.depthCameraConfig.FrameBufferLength) + throw new ArgumentOutOfRangeException(nameof (depthImage), "Depth image data size is needs to match initialization configuration."); + HeadPoints headPoints = (HeadPoints) null; + Vector3DF[] pointsFromSkeleton = FaceTracker.GetHeadPointsFromSkeleton(skeletonOfInterest); + if (pointsFromSkeleton != null && pointsFromSkeleton.Length == 2) + headPoints = new HeadPoints() + { + Points = pointsFromSkeleton + }; + this.copyStopwatch.Start(); + this.colorFaceTrackingImage.CopyFrom(colorImage); + this.depthFaceTrackingImage.CopyFrom(depthImage); + this.copyStopwatch.Stop(); + FaceTrackingSensorData trackingSensorData = new SensorData(this.colorFaceTrackingImage, this.depthFaceTrackingImage, 1f, Point.Empty).FaceTrackingSensorData; + this.startOrContinueTrackingStopwatch.Start(); + int num = !this.trackSucceeded ? this.faceTrackerInteropPtr.StartTracking(ref trackingSensorData, ref regionOfInterest, headPoints, this.frame.ResultPtr) : this.faceTrackerInteropPtr.ContinueTracking(ref trackingSensorData, headPoints, this.frame.ResultPtr); + this.startOrContinueTrackingStopwatch.Stop(); + this.trackSucceeded = num == 0 && this.frame.Status == ErrorCode.Success; + this.trackStopwatch.Stop(); + if (this.trackSucceeded) + { + ++this.totalSuccessTracks; + this.totalSuccessTrackMs += this.trackStopwatch.ElapsedMilliseconds - this.lastSuccessTrackElapsedMs; + this.lastSuccessTrackElapsedMs = this.trackStopwatch.ElapsedMilliseconds; + } + return this.frame; + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingImageFormat.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingImageFormat.cs new file mode 100644 index 0000000..ad05773 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingImageFormat.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FaceTrackingImageFormat +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System.ComponentModel; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal enum FaceTrackingImageFormat + { + FTIMAGEFORMAT_INVALID, + FTIMAGEFORMAT_UINT8_GR8, + FTIMAGEFORMAT_UINT8_R8G8B8, + FTIMAGEFORMAT_UINT8_X8R8G8B8, + FTIMAGEFORMAT_UINT8_A8R8G8B8, + FTIMAGEFORMAT_UINT8_B8G8R8X8, + FTIMAGEFORMAT_UINT8_B8G8R8A8, + FTIMAGEFORMAT_UINT16_D16, + FTIMAGEFORMAT_UINT16_D13P3, + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingRegisterDepthToColor.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingRegisterDepthToColor.cs new file mode 100644 index 0000000..6c17ee0 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingRegisterDepthToColor.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FaceTrackingRegisterDepthToColor +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal delegate int FaceTrackingRegisterDepthToColor( + uint depthFrameWidth, + uint depthFrameHeight, + uint colorFrameWidth, + uint colorFrameHeight, + float zoomFactor, + Point viewOffset, + int depthX, + int depthY, + ushort depthZ, + out int colorX, + out int colorY); +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingSensorData.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingSensorData.cs new file mode 100644 index 0000000..2bf327f --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTrackingSensorData.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FaceTrackingSensorData +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal struct FaceTrackingSensorData + { + public IFTImage VideoFrame; + public IFTImage DepthFrame; + public float ZoomFactor; + public Point ViewOffset; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTriangle.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTriangle.cs new file mode 100644 index 0000000..6c96eb5 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FaceTriangle.cs @@ -0,0 +1,53 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FaceTriangle +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System.Diagnostics; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [DebuggerDisplay("({first},{second},{third})")] + public struct FaceTriangle + { + private int first; + private int second; + private int third; + + public FaceTriangle(int first, int second, int third) + { + this.first = first; + this.second = second; + this.third = third; + } + + public int First + { + get => this.first; + set => this.first = value; + } + + public int Second + { + get => this.second; + set => this.second = value; + } + + public int Third + { + get => this.third; + set => this.third = value; + } + + public static bool operator ==(FaceTriangle triangle1, FaceTriangle triangle2) => triangle1.Equals(triangle2); + + public static bool operator !=(FaceTriangle triangle1, FaceTriangle triangle2) => !triangle1.Equals(triangle2); + + public override int GetHashCode() => this.first ^ this.second ^ this.third; + + public override bool Equals(object obj) => obj is FaceTriangle other && this.Equals(other); + + public bool Equals(FaceTriangle other) => this.first == other.first && this.second == other.second && this.third == other.third; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FeaturePoint.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FeaturePoint.cs new file mode 100644 index 0000000..250f368 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FeaturePoint.cs @@ -0,0 +1,83 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FeaturePoint +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + public enum FeaturePoint + { + TopSkull = 0, + TopRightForehead = 1, + MiddleTopDipUpperLip = 7, + AboveChin = 9, + BottomOfChin = 10, // 0x0000000A + RightOfRightEyebrow = 15, // 0x0000000F + MiddleTopOfRightEyebrow = 16, // 0x00000010 + LeftOfRightEyebrow = 17, // 0x00000011 + MiddleBottomOfRightEyebrow = 18, // 0x00000012 + AboveMidUpperRightEyelid = 19, // 0x00000013 + OuterCornerOfRightEye = 20, // 0x00000014 + MiddleTopRightEyelid = 21, // 0x00000015 + MiddleBottomRightEyelid = 22, // 0x00000016 + InnerCornerRightEye = 23, // 0x00000017 + UnderMidBottomRightEyelid = 24, // 0x00000018 + RightSideOfChin = 30, // 0x0000001E + OutsideRightCornerMouth = 31, // 0x0000001F + RightOfChin = 32, // 0x00000020 + RightTopDipUpperLip = 33, // 0x00000021 + TopLeftForehead = 34, // 0x00000022 + MiddleTopLowerLip = 40, // 0x00000028 + MiddleBottomLowerLip = 41, // 0x00000029 + LeftOfLeftEyebrow = 48, // 0x00000030 + MiddleTopOfLeftEyebrow = 49, // 0x00000031 + RightOfLeftEyebrow = 50, // 0x00000032 + MiddleBottomOfLeftEyebrow = 51, // 0x00000033 + AboveMidUpperLeftEyelid = 52, // 0x00000034 + OuterCornerOfLeftEye = 53, // 0x00000035 + MiddleTopLeftEyelid = 54, // 0x00000036 + MiddleBottomLeftEyelid = 55, // 0x00000037 + InnerCornerLeftEye = 56, // 0x00000038 + UnderMidBottomLeftEyelid = 57, // 0x00000039 + LeftSideOfCheek = 63, // 0x0000003F + OutsideLeftCornerMouth = 64, // 0x00000040 + LeftOfChin = 65, // 0x00000041 + LeftTopDipUpperLip = 66, // 0x00000042 + OuterTopRightPupil = 67, // 0x00000043 + OuterBottomRightPupil = 68, // 0x00000044 + OuterTopLeftPupil = 69, // 0x00000045 + OuterBottomLeftPupil = 70, // 0x00000046 + InnerTopRightPupil = 71, // 0x00000047 + InnerBottomRightPupil = 72, // 0x00000048 + InnerTopLeftPupil = 73, // 0x00000049 + InnerBottomLeftPupil = 74, // 0x0000004A + RightTopUpperLip = 79, // 0x0000004F + LeftTopUpperLip = 80, // 0x00000050 + RightBottomUpperLip = 81, // 0x00000051 + LeftBottomUpperLip = 82, // 0x00000052 + RightTopLowerLip = 83, // 0x00000053 + LeftTopLowerLip = 84, // 0x00000054 + RightBottomLowerLip = 85, // 0x00000055 + LeftBottomLowerLip = 86, // 0x00000056 + MiddleBottomUpperLip = 87, // 0x00000057 + LeftCornerMouth = 88, // 0x00000058 + RightCornerMouth = 89, // 0x00000059 + BottomOfRightCheek = 90, // 0x0000005A + BottomOfLeftCheek = 91, // 0x0000005B + AboveThreeFourthRightEyelid = 95, // 0x0000005F + AboveThreeFourthLeftEyelid = 96, // 0x00000060 + ThreeFourthTopRightEyelid = 97, // 0x00000061 + ThreeFourthTopLeftEyelid = 98, // 0x00000062 + ThreeFourthBottomRightEyelid = 99, // 0x00000063 + ThreeFourthBottomLeftEyelid = 100, // 0x00000064 + BelowThreeFourthRightEyelid = 101, // 0x00000065 + BelowThreeFourthLeftEyelid = 102, // 0x00000066 + AboveOneFourthRightEyelid = 103, // 0x00000067 + AboveOneFourthLeftEyelid = 104, // 0x00000068 + OneFourthTopRightEyelid = 105, // 0x00000069 + OneFourthTopLeftEyelid = 106, // 0x0000006A + OneFourthBottomRightEyelid = 107, // 0x0000006B + OneFourthBottomLeftEyelid = 108, // 0x0000006C + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/FtInterop.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/FtInterop.cs new file mode 100644 index 0000000..94c083b --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/FtInterop.cs @@ -0,0 +1,13 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.FtInterop +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal static class FtInterop + { + internal const string FaceTrackLibDll = "FaceTrackLib.dll"; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/HeadPoints.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/HeadPoints.cs new file mode 100644 index 0000000..b47bb9a --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/HeadPoints.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.HeadPoints +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [StructLayout(LayoutKind.Sequential)] + internal class HeadPoints + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + private Vector3DF[] points; + + public Vector3DF[] Points + { + set => this.points = value; + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTFaceTracker.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTFaceTracker.cs new file mode 100644 index 0000000..9e48ff4 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTFaceTracker.cs @@ -0,0 +1,64 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.IFTFaceTracker +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [Guid("1A00A7BA-C217-11E0-AC90-0024811441FD")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface IFTFaceTracker + { + [MethodImpl(MethodImplOptions.PreserveSig)] + int Initialize( + CameraConfig videoCameraConfig, + CameraConfig depthCameraConfig, + IntPtr depthToColorMappingFunc, + string modelPath); + + void Reset(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + int CreateFTResult(out IFTResult faceTrackResult); + + void SetShapeUnits(float scale, float[] shapeUnitCoeffsPtr, uint shapeUnitCount); + + void GetShapeUnits( + out float scale, + out IntPtr shapeUnitCoeffsPtr, + [In, Out] ref uint shapeUnitCount, + [MarshalAs(UnmanagedType.Bool)] out bool haveConverged); + + void SetShapeComputationState([MarshalAs(UnmanagedType.Bool)] bool isEnabled); + + void GetComputationState([MarshalAs(UnmanagedType.Bool)] out bool isEnabled); + + void GetFaceModel(out IFTModel model); + + [MethodImpl(MethodImplOptions.PreserveSig)] + int StartTracking( + ref FaceTrackingSensorData sensorData, + ref Rect roi, + HeadPoints headPoints, + IFTResult faceTrackResult); + + [MethodImpl(MethodImplOptions.PreserveSig)] + int ContinueTracking( + ref FaceTrackingSensorData sensorData, + HeadPoints headPoints, + IFTResult faceTrackResult); + + [MethodImpl(MethodImplOptions.PreserveSig)] + int DetectFaces( + ref FaceTrackingSensorData sensorData, + ref Rect roi, + IntPtr faces, + ref uint facesCount); + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTImage.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTImage.cs new file mode 100644 index 0000000..94e62ba --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTImage.cs @@ -0,0 +1,57 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.IFTImage +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [Guid("1A00A7BC-C217-11E0-AC90-0024811441FD")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface IFTImage + { + void Allocate(uint width, uint height, FaceTrackingImageFormat format); + + void Attach( + uint width, + uint height, + IntPtr dataPtr, + FaceTrackingImageFormat format, + uint stride); + + void Reset(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetWidth(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetHeight(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetStride(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetBytesPerPixel(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetBufferSize(); + + FaceTrackingImageFormat GetFormat(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + IntPtr GetBuffer(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + [return: MarshalAs(UnmanagedType.Bool)] + bool IsAttached(); + + void CopyTo([In] IFTImage destImage, [In] ref Rect srcRect, uint destRow, uint destColumn); + + void DrawLine(Point startPoint, Point endPoint, uint color, uint lineWidthPx); + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTModel.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTModel.cs new file mode 100644 index 0000000..456dba4 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTModel.cs @@ -0,0 +1,54 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.IFTModel +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [Guid("1A00A7BD-C217-11E0-AC90-0024811441FD")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface IFTModel + { + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetSUCount(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetAUCount(); + + void GetTriangles(out IntPtr trianglesPtr, out uint triangleCount); + + [MethodImpl(MethodImplOptions.PreserveSig)] + uint GetVertexCount(); + + void Get3DShape( + IntPtr shapeUnitCoeffsPtr, + uint shapeUnitCount, + IntPtr animUnitCoeffPtr, + uint animUnitCount, + float scale, + ref Vector3DF rotationXYZ, + ref Vector3DF translationXYZ, + IntPtr vertices, + uint vertexCount); + + void GetProjectedShape( + CameraConfig cameraConfig, + float zoomFactor, + Point viewOffset, + IntPtr shapeUnitCoeffPtr, + uint shapeUnitCount, + IntPtr animUnitCoeffsPtr, + uint animUnitCount, + float scale, + ref Vector3DF rotationXYZ, + ref Vector3DF translationXYZ, + IntPtr vertices, + uint vertexCount); + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTResult.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTResult.cs new file mode 100644 index 0000000..b59b0d0 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/IFTResult.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.IFTResult +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [Guid("1A00A7BB-C217-11E0-AC90-0024811441FD")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface IFTResult + { + void Reset(); + + [MethodImpl(MethodImplOptions.PreserveSig)] + int CopyTo([In] IFTResult destResult); + + [MethodImpl(MethodImplOptions.PreserveSig)] + int GetStatus(); + + void GetFaceRect(out Rect rect); + + void Get2DShapePoints(out IntPtr pointsPtr, out uint pointCount); + + void Get3DPose(out float scale, out Vector3DF rotationXYZ, out Vector3DF translationXYZ); + + void GetAUCoefficients(out IntPtr animUnitCoeffPtr, out uint animUnitCount); + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/Image.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/Image.cs new file mode 100644 index 0000000..0bc0563 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/Image.cs @@ -0,0 +1,149 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.Image +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal class Image : IDisposable + { + private Image.BufferManagement bufferManagement; + private bool disposed; + private IFTImage faceTrackingImagePtr; + + public Image() + { + this.faceTrackingImagePtr = NativeMethods.FTCreateImage(); + if (this.faceTrackingImagePtr == null) + throw new InvalidOperationException("Cannot create image instance"); + } + + ~Image() => this.Dispose(false); + + public IntPtr BufferPtr + { + get + { + this.CheckPtrAndThrow(); + return this.faceTrackingImagePtr.GetBuffer(); + } + } + + public uint BufferSize + { + get + { + this.CheckPtrAndThrow(); + return this.faceTrackingImagePtr.GetBufferSize(); + } + } + + internal IFTImage ImagePtr => this.faceTrackingImagePtr; + + public static uint FormatToSize(FaceTrackingImageFormat format) + { + switch (format) + { + case FaceTrackingImageFormat.FTIMAGEFORMAT_INVALID: + return 0; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_GR8: + return 1; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_R8G8B8: + return 3; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_X8R8G8B8: + return 4; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_A8R8G8B8: + return 4; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_B8G8R8X8: + return 4; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT8_B8G8R8A8: + return 4; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT16_D16: + return 2; + case FaceTrackingImageFormat.FTIMAGEFORMAT_UINT16_D13P3: + return 2; + default: + throw new ArgumentException("Invalid image format specified"); + } + } + + public void Allocate(uint width, uint height, FaceTrackingImageFormat format) + { + this.CheckPtrAndThrow(); + this.bufferManagement = this.bufferManagement == Image.BufferManagement.None ? Image.BufferManagement.LocalNativeImage : throw new InvalidOperationException("Cannot Allocate again. Image already allocated buffer in native image."); + this.faceTrackingImagePtr.Allocate(width, height, format); + } + + public void Attach( + uint width, + uint height, + IntPtr imageDataPtr, + FaceTrackingImageFormat format, + uint stride) + { + this.CheckPtrAndThrow(); + this.bufferManagement = this.bufferManagement == Image.BufferManagement.None ? Image.BufferManagement.External : throw new InvalidOperationException("Cannot Attach again. Image already attached to external buffer."); + this.faceTrackingImagePtr.Attach(width, height, imageDataPtr, format, stride); + } + + public void CopyFrom(T[] srcData) where T : struct + { + if (this.bufferManagement == Image.BufferManagement.External) + throw new InvalidOperationException("Cannot copy data as buffer managed externally."); + if (this.bufferManagement != Image.BufferManagement.LocalNativeImage) + throw new NotSupportedException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, "Unsupported buffer management {0} encountered", (object) this.bufferManagement)); + IntPtr bufferPtr = this.BufferPtr; + uint bufferSize = this.BufferSize; + if ((long) (srcData.Length * Marshal.SizeOf(typeof (T))) > (long) bufferSize) + throw new ArgumentException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, "Array size for src buffer ({0}) should be less than native image buffer ({1})", (object) srcData.Length, (object) bufferSize)); + if (typeof (T).Equals(typeof (byte))) + { + byte[] source = srcData as byte[]; + Marshal.Copy(source, 0, bufferPtr, source.Length); + } + else + { + if (!typeof (T).Equals(typeof (short))) + throw new InvalidOperationException("Invalid type of data specified. Only byte & short supported"); + short[] source = srcData as short[]; + Marshal.Copy(source, 0, bufferPtr, source.Length); + } + } + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize((object) this); + } + + protected virtual void Dispose(bool disposing) + { + if (this.disposed) + return; + if (this.faceTrackingImagePtr != null) + { + Marshal.FinalReleaseComObject((object) this.faceTrackingImagePtr); + this.faceTrackingImagePtr = (IFTImage) null; + } + this.disposed = true; + } + + private void CheckPtrAndThrow() + { + if (this.faceTrackingImagePtr == null) + throw new InvalidOperationException("Native image pointer in invalid state."); + } + + private enum BufferManagement + { + None, + LocalNativeImage, + External, + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/Microsoft.Kinect.Toolkit.FaceTracking.csproj b/src/Microsoft.Kinect.Toolkit.FaceTracking/Microsoft.Kinect.Toolkit.FaceTracking.csproj new file mode 100644 index 0000000..ed9d2c6 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/Microsoft.Kinect.Toolkit.FaceTracking.csproj @@ -0,0 +1,19 @@ + + + + + net6.0-windows + 1.8.0.0 + true + ..\..\lib + + + + none + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/NativeMethods.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/NativeMethods.cs new file mode 100644 index 0000000..0854079 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/NativeMethods.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.NativeMethods +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal static class NativeMethods + { + [DllImport("FaceTrackLib.dll", CharSet = CharSet.Unicode)] + public static extern IFTFaceTracker FTCreateFaceTracker(IntPtr reserved); + + [DllImport("FaceTrackLib.dll", CharSet = CharSet.Unicode)] + public static extern IFTImage FTCreateImage(); + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/OperationMode.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/OperationMode.cs new file mode 100644 index 0000000..3521721 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/OperationMode.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.OperationMode +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal enum OperationMode + { + Kinect, + ImageLocalBuffer, + ImageExternalBuffer, + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/Point.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/Point.cs new file mode 100644 index 0000000..59af886 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/Point.cs @@ -0,0 +1,37 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.Point +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System.Diagnostics; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [DebuggerDisplay("({X},{Y})")] + public struct Point + { + public Point(int x, int y) + : this() + { + this.X = x; + this.Y = y; + } + + public static Point Empty => new Point(0, 0); + + public int X { get; private set; } + + public int Y { get; private set; } + + public static bool operator ==(Point point1, Point point2) => point1.Equals(point2); + + public static bool operator !=(Point point1, Point point2) => !point1.Equals(point2); + + public override int GetHashCode() => this.X ^ this.Y; + + public override bool Equals(object obj) => obj is Point other && this.Equals(other); + + public bool Equals(Point other) => this.X == other.X && this.Y == other.Y; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/PointF.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/PointF.cs new file mode 100644 index 0000000..22a5d61 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/PointF.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.PointF +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System.Diagnostics; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [DebuggerDisplay("({x},{y})")] + public struct PointF + { + private readonly float x; + private readonly float y; + + public PointF(float x, float y) + { + this.x = x; + this.y = y; + } + + public static PointF Empty => new PointF(0.0f, 0.0f); + + public float X => this.x; + + public float Y => this.y; + + public static bool operator ==(PointF point1, PointF point2) => point1.Equals(point2); + + public static bool operator !=(PointF point1, PointF point2) => !point1.Equals(point2); + + public override int GetHashCode() + { + float num = this.x; + int hashCode1 = num.GetHashCode(); + num = this.y; + int hashCode2 = num.GetHashCode(); + return hashCode1 ^ hashCode2; + } + + public override bool Equals(object obj) => obj is PointF other && this.Equals(other); + + public bool Equals(PointF other) => (double) this.x == (double) other.x && (double) this.y == (double) other.y; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/Rect.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/Rect.cs new file mode 100644 index 0000000..f4bf23c --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/Rect.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.Rect +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System.Diagnostics; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [DebuggerDisplay("(l={Left},t={Top},r={Right},b={Bottom})")] + public struct Rect + { + public Rect(int left, int top, int right, int bottom) + : this() + { + this.Left = left; + this.Top = top; + this.Right = right; + this.Bottom = bottom; + } + + public static Rect Empty => new Rect(0, 0, 0, 0); + + public int Left { get; set; } + + public int Top { get; set; } + + public int Right { get; set; } + + public int Bottom { get; set; } + + public int Width => this.Right - this.Left; + + public int Height => this.Bottom - this.Top; + + public static bool operator ==(Rect point1, Rect point2) => point1.Equals(point2); + + public static bool operator !=(Rect point1, Rect point2) => !point1.Equals(point2); + + public override int GetHashCode() => this.Left ^ this.Right ^ this.Top ^ this.Bottom; + + public override bool Equals(object obj) => obj is Rect other && this.Equals(other); + + public bool Equals(Rect other) => this.Left == other.Left && this.Top == other.Top && this.Right == other.Right && this.Bottom == other.Bottom; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/SensorData.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/SensorData.cs new file mode 100644 index 0000000..9472f62 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/SensorData.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.SensorData +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + internal class SensorData + { + private readonly Image videoFrame; + private readonly Image depthFrame; + private readonly float zoomFactor; + private readonly Point viewOffset; + + public SensorData(Image videoFrame, Image depthFrame, float zoomFactor, Point viewOffset) + { + this.videoFrame = videoFrame; + this.depthFrame = depthFrame; + this.zoomFactor = zoomFactor; + this.viewOffset = viewOffset; + } + + internal FaceTrackingSensorData FaceTrackingSensorData => new FaceTrackingSensorData() + { + VideoFrame = this.videoFrame != null ? this.videoFrame.ImagePtr : (IFTImage) null, + DepthFrame = this.depthFrame != null ? this.depthFrame.ImagePtr : (IFTImage) null, + ZoomFactor = this.zoomFactor, + ViewOffset = this.viewOffset + }; + } +} diff --git a/src/Microsoft.Kinect.Toolkit.FaceTracking/Vector3DF.cs b/src/Microsoft.Kinect.Toolkit.FaceTracking/Vector3DF.cs new file mode 100644 index 0000000..c42c238 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit.FaceTracking/Vector3DF.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.FaceTracking.Vector3DF +// Assembly: Microsoft.Kinect.Toolkit.FaceTracking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 1A78CF7A-6101-44D2-89EE-184B8BDF2A78 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.FaceTracking.dll + +using System.Diagnostics; + +namespace Microsoft.Kinect.Toolkit.FaceTracking +{ + [DebuggerDisplay("({X},{Y},{Z})")] + public struct Vector3DF + { + public Vector3DF(float x, float y, float z) + : this() + { + this.X = x; + this.Y = y; + this.Z = z; + } + + public static Vector3DF Empty => new Vector3DF(0.0f, 0.0f, 0.0f); + + public float X { get; set; } + + public float Y { get; set; } + + public float Z { get; set; } + + public static bool operator ==(Vector3DF vector1, Vector3DF vector2) => vector1.Equals(vector2); + + public static bool operator !=(Vector3DF vector1, Vector3DF vector2) => !vector1.Equals(vector2); + + public override int GetHashCode() + { + float num1 = this.X; + int hashCode1 = num1.GetHashCode(); + num1 = this.Y; + int hashCode2 = num1.GetHashCode(); + int num2 = hashCode1 ^ hashCode2; + num1 = this.Z; + int hashCode3 = num1.GetHashCode(); + return num2 ^ hashCode3; + } + + public override bool Equals(object obj) => obj is Vector3DF other && this.Equals(other); + + public bool Equals(Vector3DF other) => (double) this.X == (double) other.X && (double) this.Y == (double) other.Y && (double) this.Z == (double) other.Z; + } +} diff --git a/src/Microsoft.Kinect.Toolkit/CallbackLock.cs b/src/Microsoft.Kinect.Toolkit/CallbackLock.cs new file mode 100644 index 0000000..fb7c751 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/CallbackLock.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.CallbackLock +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading; + +namespace Microsoft.Kinect.Toolkit +{ + public sealed class CallbackLock : IDisposable + { + private readonly object lockObject; + + public CallbackLock(object lockTarget) + { + this.lockObject = lockTarget; + Monitor.Enter(lockTarget); + } + + [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly", Justification = "Helper event to defer actions until after lock exit doesn't need arguments")] + public event LockExitEventHandler LockExit; + + public void Dispose() + { + Monitor.Exit(this.lockObject); + if (this.LockExit == null) + return; + this.LockExit(); + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/ChooserStatus.cs b/src/Microsoft.Kinect.Toolkit/ChooserStatus.cs new file mode 100644 index 0000000..08c15cf --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/ChooserStatus.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.ChooserStatus +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; + +namespace Microsoft.Kinect.Toolkit +{ + [Flags] + public enum ChooserStatus + { + None = 0, + SensorInitializing = 1, + SensorStarted = 2, + NoAvailableSensors = 16, // 0x00000010 + SensorConflict = 32, // 0x00000020 + SensorNotPowered = 64, // 0x00000040 + SensorInsufficientBandwidth = 128, // 0x00000080 + SensorNotGenuine = 256, // 0x00000100 + SensorNotSupported = 512, // 0x00000200 + SensorError = 1024, // 0x00000400 + } +} diff --git a/src/Microsoft.Kinect.Toolkit/ContextEventWrapper`1.cs b/src/Microsoft.Kinect.Toolkit/ContextEventWrapper`1.cs new file mode 100644 index 0000000..95ca6af --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/ContextEventWrapper`1.cs @@ -0,0 +1,180 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.ContextEventWrapper`1 +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; + +namespace Microsoft.Kinect.Toolkit +{ + public class ContextEventWrapper where T : EventArgs + { + private readonly ThreadSafeCollection.ContextHandlerPair> actualHandlers; + private readonly ContextSynchronizationMethod method; + private bool isDisposed; + + public ContextEventWrapper(ContextSynchronizationMethod method) + { + this.isDisposed = false; + this.method = method; + this.actualHandlers = new ThreadSafeCollection.ContextHandlerPair>(); + } + + public ContextEventWrapper() + : this(ContextSynchronizationMethod.Post) + { + } + + public bool HasHandlers => this.actualHandlers.Count > 0; + + public void AddHandler(EventHandler originalHandler) + { + if (originalHandler == null) + return; + this.actualHandlers.Add(new ContextEventWrapper.ContextHandlerPair(originalHandler, new ContextEventWrapper.SynchronizationContextIdentifier(SynchronizationContext.Current))); + } + + public void RemoveHandler(EventHandler originalHandler) + { + ContextEventWrapper.SynchronizationContextIdentifier contextIdentifier = new ContextEventWrapper.SynchronizationContextIdentifier(SynchronizationContext.Current); + ContextEventWrapper.ContextHandlerPair contextHandlerPair = (ContextEventWrapper.ContextHandlerPair) null; + foreach (ContextEventWrapper.ContextHandlerPair actualHandler in (IEnumerable.ContextHandlerPair>) this.actualHandlers) + { + EventHandler handler = actualHandler.Handler; + ContextEventWrapper.SynchronizationContextIdentifier contextId = actualHandler.ContextId; + if (contextIdentifier == contextId && handler == originalHandler) + { + contextHandlerPair = actualHandler; + break; + } + } + if (contextHandlerPair == null) + return; + this.actualHandlers.Remove(contextHandlerPair); + } + + public void Invoke(object sender, T eventArgs) + { + if (!this.HasHandlers) + return; + foreach (ContextEventWrapper.ContextHandlerPair actualHandler in (IEnumerable.ContextHandlerPair>) this.actualHandlers) + { + EventHandler handler = actualHandler.Handler; + SynchronizationContext context = actualHandler.ContextId.Context; + if (context == null) + handler(sender, eventArgs); + else if (this.method == ContextSynchronizationMethod.Post) + context.Post(new SendOrPostCallback(this.SendOrPostDelegate), (object) new ContextEventWrapper.ContextEventHandlerArgsWrapper(handler, sender, eventArgs)); + else if (this.method == ContextSynchronizationMethod.Send) + context.Send(new SendOrPostCallback(this.SendOrPostDelegate), (object) new ContextEventWrapper.ContextEventHandlerArgsWrapper(handler, sender, eventArgs)); + } + } + + public void Dispose() + { + this.isDisposed = true; + this.actualHandlers.Clear(); + } + + private void SendOrPostDelegate(object state) + { + if (this.isDisposed) + return; + ContextEventWrapper.ContextEventHandlerArgsWrapper handlerArgsWrapper = (ContextEventWrapper.ContextEventHandlerArgsWrapper) state; + handlerArgsWrapper.Handler(handlerArgsWrapper.Sender, handlerArgsWrapper.Args); + } + + private class ContextEventHandlerArgsWrapper + { + public ContextEventHandlerArgsWrapper(EventHandler handler, object sender, T args) + { + this.Handler = handler; + this.Sender = sender; + this.Args = args; + } + + public EventHandler Handler { get; private set; } + + public object Sender { get; private set; } + + public T Args { get; private set; } + } + + private class SynchronizationContextIdentifier + { + private const string DispatcherFieldName = "_dispatcher"; + private const string DispatcherSynchronizationContextName = "DispatcherSynchronizationContext"; + private object dispatcherObject; + + public SynchronizationContextIdentifier(SynchronizationContext context) + { + this.Context = context; + if (context == null) + return; + Type type = context.GetType(); + if (!("DispatcherSynchronizationContext" == type.Name)) + return; + FieldInfo field = type.GetField("_dispatcher", BindingFlags.Instance | BindingFlags.NonPublic); + if (!(field != (FieldInfo) null)) + return; + this.dispatcherObject = field.GetValue((object) context); + } + + public SynchronizationContext Context { get; private set; } + + public static bool operator ==( + ContextEventWrapper.SynchronizationContextIdentifier contextId1, + ContextEventWrapper.SynchronizationContextIdentifier contextId2) + { + return (object) contextId1 != null && (object) contextId2 != null && contextId1.Equals(contextId2); + } + + public static bool operator !=( + ContextEventWrapper.SynchronizationContextIdentifier contextId1, + ContextEventWrapper.SynchronizationContextIdentifier contextId2) + { + return (object) contextId1 == null || (object) contextId2 == null || !contextId1.Equals(contextId2); + } + + public override int GetHashCode() + { + if (this.dispatcherObject != null) + return this.dispatcherObject.GetHashCode(); + return this.Context != null ? this.Context.GetHashCode() : 0; + } + + public override bool Equals(object obj) + { + ContextEventWrapper.SynchronizationContextIdentifier contextId = obj as ContextEventWrapper.SynchronizationContextIdentifier; + return (object) contextId != null && this.Equals(contextId); + } + + public bool Equals( + ContextEventWrapper.SynchronizationContextIdentifier contextId) + { + if ((object) contextId == null) + return false; + return this.dispatcherObject == null && contextId.dispatcherObject == null ? this.Context == contextId.Context : this.dispatcherObject == contextId.dispatcherObject; + } + } + + private class ContextHandlerPair + { + public ContextHandlerPair( + EventHandler handler, + ContextEventWrapper.SynchronizationContextIdentifier contextId) + { + this.Handler = handler; + this.ContextId = contextId; + } + + public ContextEventWrapper.SynchronizationContextIdentifier ContextId { get; private set; } + + public EventHandler Handler { get; private set; } + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/ContextSynchronizationMethod.cs b/src/Microsoft.Kinect.Toolkit/ContextSynchronizationMethod.cs new file mode 100644 index 0000000..0770f20 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/ContextSynchronizationMethod.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.ContextSynchronizationMethod +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +namespace Microsoft.Kinect.Toolkit +{ + public enum ContextSynchronizationMethod + { + Send, + Post, + } +} diff --git a/src/Microsoft.Kinect.Toolkit/KinectChangedEventArgs.cs b/src/Microsoft.Kinect.Toolkit/KinectChangedEventArgs.cs new file mode 100644 index 0000000..86c7972 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/KinectChangedEventArgs.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.KinectChangedEventArgs +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; + +namespace Microsoft.Kinect.Toolkit +{ + public class KinectChangedEventArgs : EventArgs + { + public KinectChangedEventArgs(KinectSensor oldSensor, KinectSensor newSensor) + { + this.OldSensor = oldSensor; + this.NewSensor = newSensor; + } + + public KinectSensor OldSensor { get; private set; } + + public KinectSensor NewSensor { get; private set; } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/KinectSensorChooser.cs b/src/Microsoft.Kinect.Toolkit/KinectSensorChooser.cs new file mode 100644 index 0000000..fc99ae4 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/KinectSensorChooser.cs @@ -0,0 +1,219 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.KinectSensorChooser +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.IO; + +namespace Microsoft.Kinect.Toolkit +{ + public class KinectSensorChooser : INotifyPropertyChanged + { + private readonly object lockObject = new object(); + private readonly ContextEventWrapper kinectChangedContextWrapper = new ContextEventWrapper(ContextSynchronizationMethod.Post); + private readonly ContextEventWrapper propertyChangedContextWrapper = new ContextEventWrapper(ContextSynchronizationMethod.Post); + private readonly Dictionary> changedHandlers = new Dictionary>(); + private bool isStarted; + private string requiredConnectionId; + + public event EventHandler KinectChanged + { + add => this.kinectChangedContextWrapper.AddHandler(value); + remove => this.kinectChangedContextWrapper.RemoveHandler(value); + } + + public event PropertyChangedEventHandler PropertyChanged + { + add + { + lock (this.lockObject) + { + EventHandler originalHandler = (EventHandler) ((sender, args) => value(sender, args)); + this.changedHandlers[value] = originalHandler; + this.propertyChangedContextWrapper.AddHandler(originalHandler); + } + } + remove + { + lock (this.lockObject) + { + EventHandler changedHandler = this.changedHandlers[value]; + this.changedHandlers.Remove(value); + this.propertyChangedContextWrapper.RemoveHandler(changedHandler); + } + } + } + + public string RequiredConnectionId + { + get => this.requiredConnectionId; + set + { + if (value == this.requiredConnectionId) + return; + using (CallbackLock callbackLock = new CallbackLock(this.lockObject)) + { + if (value == this.requiredConnectionId) + return; + this.requiredConnectionId = value; + if (this.requiredConnectionId == null || this.Kinect != null && this.Kinect.DeviceConnectionId == this.requiredConnectionId) + return; + this.TryFindAndStartKinect(callbackLock); + } + } + } + + public KinectSensor Kinect { get; private set; } + + public ChooserStatus Status { get; private set; } + + public void Start() + { + if (this.isStarted) + return; + using (CallbackLock callbackLock = new CallbackLock(this.lockObject)) + { + if (this.isStarted) + return; + this.isStarted = true; + KinectSensor.KinectSensors.StatusChanged += new EventHandler(this.KinectSensorsOnStatusChanged); + this.TryFindAndStartKinect(callbackLock); + } + } + + public void Stop() + { + if (!this.isStarted) + return; + using (CallbackLock callbackLock = new CallbackLock(this.lockObject)) + { + if (!this.isStarted) + return; + this.isStarted = false; + KinectSensor.KinectSensors.StatusChanged -= new EventHandler(this.KinectSensorsOnStatusChanged); + this.SetSensorAndStatus(callbackLock, (KinectSensor) null, ChooserStatus.None); + } + } + + public void TryResolveConflict() + { + using (CallbackLock callbackLock = new CallbackLock(this.lockObject)) + this.TryFindAndStartKinect(callbackLock); + } + + private static ChooserStatus GetErrorStatusFromSensor(KinectSensor sensor) + { + switch (sensor.Status) + { + case KinectStatus.Undefined: + return ChooserStatus.SensorError; + case KinectStatus.Disconnected: + return ChooserStatus.SensorError; + case KinectStatus.Connected: + return ChooserStatus.None; + case KinectStatus.Initializing: + return ChooserStatus.SensorInitializing; + case KinectStatus.Error: + return ChooserStatus.SensorError; + case KinectStatus.NotPowered: + return ChooserStatus.SensorNotPowered; + case KinectStatus.NotReady: + return ChooserStatus.SensorError; + case KinectStatus.DeviceNotGenuine: + return ChooserStatus.SensorNotGenuine; + case KinectStatus.DeviceNotSupported: + return ChooserStatus.SensorNotSupported; + case KinectStatus.InsufficientBandwidth: + return ChooserStatus.SensorInsufficientBandwidth; + default: + throw new ArgumentOutOfRangeException(nameof (sensor)); + } + } + + private void KinectSensorsOnStatusChanged(object sender, StatusChangedEventArgs e) + { + if (e == null || e.Sensor != this.Kinect && this.Kinect != null) + return; + using (CallbackLock callbackLock = new CallbackLock(this.lockObject)) + { + if (e.Sensor != this.Kinect && this.Kinect != null) + return; + this.TryFindAndStartKinect(callbackLock); + } + } + + private void SetSensorAndStatus( + CallbackLock callbackLock, + KinectSensor newKinect, + ChooserStatus newChooserStatus) + { + KinectSensor oldKinect = this.Kinect; + if (oldKinect != newKinect) + { + if (oldKinect != null) + oldKinect.Stop(); + this.Kinect = newKinect; + callbackLock.LockExit += (LockExitEventHandler) (() => this.kinectChangedContextWrapper.Invoke((object) this, new KinectChangedEventArgs(oldKinect, newKinect))); + callbackLock.LockExit += (LockExitEventHandler) (() => this.RaisePropertyChanged("Kinect")); + } + if (this.Status == newChooserStatus) + return; + this.Status = newChooserStatus; + callbackLock.LockExit += (LockExitEventHandler) (() => this.RaisePropertyChanged("Status")); + } + + private void TryFindAndStartKinect(CallbackLock callbackLock) + { + if (!this.isStarted || this.Kinect != null && this.Kinect.Status == KinectStatus.Connected && (this.requiredConnectionId == null || this.Kinect.DeviceConnectionId == this.requiredConnectionId)) + return; + KinectSensor newKinect = (KinectSensor) null; + ChooserStatus newChooserStatus = ChooserStatus.None; + if (KinectSensor.KinectSensors.Count == 0) + { + newChooserStatus = ChooserStatus.NoAvailableSensors; + } + else + { + foreach (KinectSensor kinectSensor in (ReadOnlyCollection) KinectSensor.KinectSensors) + { + if (this.requiredConnectionId != null && kinectSensor.DeviceConnectionId != this.requiredConnectionId) + newChooserStatus |= ChooserStatus.NoAvailableSensors; + else if (kinectSensor.Status != KinectStatus.Connected) + newChooserStatus |= KinectSensorChooser.GetErrorStatusFromSensor(kinectSensor); + else if (kinectSensor.IsRunning) + { + newChooserStatus |= ChooserStatus.NoAvailableSensors; + } + else + { + try + { + kinectSensor.Start(); + } + catch (IOException ex) + { + newChooserStatus |= ChooserStatus.SensorConflict; + continue; + } + catch (InvalidOperationException ex) + { + newChooserStatus |= ChooserStatus.SensorConflict; + continue; + } + newChooserStatus = ChooserStatus.SensorStarted; + newKinect = kinectSensor; + break; + } + } + } + this.SetSensorAndStatus(callbackLock, newKinect, newChooserStatus); + } + + private void RaisePropertyChanged(string propertyName) => this.propertyChangedContextWrapper.Invoke((object) this, new PropertyChangedEventArgs(propertyName)); + } +} diff --git a/src/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs b/src/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs new file mode 100644 index 0000000..b41b8e7 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs @@ -0,0 +1,306 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.KinectSensorChooserUI +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.CodeDom.Compiler; +using System.ComponentModel; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Markup; +using System.Windows.Navigation; +using System.Windows.Threading; + +namespace Microsoft.Kinect.Toolkit +{ + public partial class KinectSensorChooserUI : UserControl, IComponentConnector + { + public static readonly DependencyProperty IsListeningProperty = DependencyProperty.Register(nameof (IsListening), typeof (bool), typeof (KinectSensorChooserUI), new PropertyMetadata((object) false)); + public static readonly DependencyProperty KinectSensorChooserProperty = DependencyProperty.Register(nameof (KinectSensorChooser), typeof (KinectSensorChooser), typeof (KinectSensorChooserUI), new PropertyMetadata((PropertyChangedCallback) null)); + public static readonly DependencyProperty VisualStateProperty = DependencyProperty.Register(nameof (VisualState), typeof (string), typeof (KinectSensorChooserUI), new PropertyMetadata((object) null, (PropertyChangedCallback) ((o, args) => ((KinectSensorChooserUI) o).OnVisualstateChanged((string) args.NewValue)))); + private readonly DispatcherTimer popupCloseCheck; + private bool suppressPopupOnFocus; + private Window parentWindow; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid layoutRoot; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal VisualStateGroup SensorStatusStates; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal System.Windows.VisualState Stopped; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal System.Windows.VisualState Initializing; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal System.Windows.VisualState AllSetListening; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal System.Windows.VisualState NoAvailableSensors; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal System.Windows.VisualState Error; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal System.Windows.VisualState AllSetNotListening; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid initializingContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid allSetNotListeningContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid allSetListeningContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid noAvailableSensorsContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid errorContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Popup expandedPopup; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid popupGrid; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid expandedInitializingContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid expandedAllSetNotListeningContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid expandedAllSetListeningContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid expandedNoAvailableSensorsContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Grid expandedErrorContent; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal TextBlock MessageTextBlock; + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] + internal Hyperlink TellMeMoreLink; + private bool _contentLoaded; + + public KinectSensorChooserUI() + { + this.Loaded += new RoutedEventHandler(this.OnLoaded); + this.Unloaded += new RoutedEventHandler(this.OnUnloaded); + this.InitializeComponent(); + this.popupCloseCheck = new DispatcherTimer(TimeSpan.FromMilliseconds(1000.0), DispatcherPriority.Normal, new EventHandler(this.OnPopupCloseCheckFired), this.Dispatcher); + KinectSensorChooserUIViewModel target = new KinectSensorChooserUIViewModel(); + this.layoutRoot.DataContext = (object) target; + Binding binding1 = new Binding(nameof (VisualState)) + { + Source = (object) target + }; + this.SetBinding(KinectSensorChooserUI.VisualStateProperty, (BindingBase) binding1); + Binding binding2 = new Binding(nameof (KinectSensorChooser)) + { + Source = (object) this + }; + BindingOperations.SetBinding((DependencyObject) target, KinectSensorChooserUIViewModel.KinectSensorChooserProperty, (BindingBase) binding2); + Binding binding3 = new Binding(nameof (IsListening)) + { + Source = (object) this + }; + BindingOperations.SetBinding((DependencyObject) target, KinectSensorChooserUIViewModel.IsListeningProperty, (BindingBase) binding3); + this.expandedPopup.LayoutUpdated += new EventHandler(this.ExpandedPopupOnLayoutUpdated); + } + + public bool IsListening + { + get => (bool) this.GetValue(KinectSensorChooserUI.IsListeningProperty); + set => this.SetValue(KinectSensorChooserUI.IsListeningProperty, (object) value); + } + + public KinectSensorChooser KinectSensorChooser + { + get => (KinectSensorChooser) this.GetValue(KinectSensorChooserUI.KinectSensorChooserProperty); + set => this.SetValue(KinectSensorChooserUI.KinectSensorChooserProperty, (object) value); + } + + public string VisualState + { + get => (string) this.GetValue(KinectSensorChooserUI.VisualStateProperty); + set => this.SetValue(KinectSensorChooserUI.VisualStateProperty, (object) value); + } + + private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) + { + this.parentWindow = Window.GetWindow((DependencyObject) this); + if (this.parentWindow == null) + return; + this.parentWindow.Deactivated += new EventHandler(this.ParentWindowOnDeactivated); + } + + private void OnUnloaded(object sender, RoutedEventArgs routedEventArgs) + { + if (this.parentWindow == null) + return; + this.parentWindow.Deactivated -= new EventHandler(this.ParentWindowOnDeactivated); + } + + private void ParentWindowOnDeactivated(object sender, EventArgs eventArgs) => this.ClosePopup(); + + private void ClosePopup() => this.expandedPopup.IsOpen = false; + + private void OpenPopup() => this.expandedPopup.IsOpen = true; + + private void OnRootGridGotKeyboardFocus(object sender, RoutedEventArgs e) + { + if (this.suppressPopupOnFocus) + return; + this.OpenPopup(); + } + + private void OnRootGridMouseEnter(object sender, MouseEventArgs e) => this.OpenPopup(); + + private void ExpandedPopupOnLayoutUpdated(object sender, EventArgs eventArgs) => this.expandedPopup.VerticalOffset = (this.popupGrid.ActualHeight - this.layoutRoot.ActualHeight - 1.0) / 2.0; + + private void ExpandedPopupOnOpened(object sender, EventArgs eventArgs) + { + this.popupCloseCheck.Stop(); + if (this.layoutRoot.IsKeyboardFocusWithin) + Keyboard.Focus((IInputElement) this.popupGrid); + else + this.popupCloseCheck.Start(); + } + + private void OnExpandedPopupMouseLeave(object sender, MouseEventArgs e) => this.ClosePopup(); + + private void OnPopupCloseCheckFired(object sender, EventArgs e) + { + this.popupCloseCheck.Stop(); + if (!this.expandedPopup.IsOpen || this.popupGrid.IsMouseOver || this.popupGrid.IsKeyboardFocusWithin) + return; + this.ClosePopup(); + } + + private void OnPopupGridGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) + { + FrameworkElement oldFocus = e.OldFocus as FrameworkElement; + if (e.NewFocus as FrameworkElement != this.popupGrid || oldFocus == this.layoutRoot) + return; + this.suppressPopupOnFocus = true; + this.layoutRoot.Focusable = false; + e.Handled = true; + FocusNavigationDirection focusNavigationDirection = (Keyboard.Modifiers & ModifierKeys.Shift) != ModifierKeys.None ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next; + this.ClosePopup(); + this.MoveFocus(new TraversalRequest(focusNavigationDirection)); + this.layoutRoot.Focusable = true; + this.suppressPopupOnFocus = false; + } + + private void OnVisualstateChanged(string newState) => VisualStateManager.GoToState((FrameworkElement) this, newState, true); + + private void TellMeMoreLinkRequestNavigate(object sender, RequestNavigateEventArgs e) + { + if (e.OriginalSource is Hyperlink originalSource) + { + try + { + Process.Start(new ProcessStartInfo(originalSource.NavigateUri.ToString())); + } + catch (Win32Exception ex) + { + int num = (int) MessageBox.Show(string.Format((IFormatProvider) CultureInfo.CurrentCulture, Microsoft.Kinect.Toolkit.Properties.Resources.NoDefaultBrowserAvailable, (object) originalSource.NavigateUri)); + } + this.ClosePopup(); + } + e.Handled = true; + } + + [DebuggerNonUserCode] + [GeneratedCode("PresentationBuildTasks", "4.0.0.0")] + public void InitializeComponent() + { + if (this._contentLoaded) + return; + this._contentLoaded = true; + Application.LoadComponent((object) this, new Uri("/Microsoft.Kinect.Toolkit;component/kinectsensorchooserui.xaml", UriKind.Relative)); + } + + [DebuggerNonUserCode] + [GeneratedCode("PresentationBuildTasks", "4.0.0.0")] + [EditorBrowsable(EditorBrowsableState.Never)] + [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")] + void IComponentConnector.Connect(int connectionId, object target) + { + switch (connectionId) + { + case 1: + this.layoutRoot = (Grid) target; + this.layoutRoot.MouseEnter += new MouseEventHandler(this.OnRootGridMouseEnter); + this.layoutRoot.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(this.OnRootGridGotKeyboardFocus); + break; + case 2: + this.SensorStatusStates = (VisualStateGroup) target; + break; + case 3: + this.Stopped = (System.Windows.VisualState) target; + break; + case 4: + this.Initializing = (System.Windows.VisualState) target; + break; + case 5: + this.AllSetListening = (System.Windows.VisualState) target; + break; + case 6: + this.NoAvailableSensors = (System.Windows.VisualState) target; + break; + case 7: + this.Error = (System.Windows.VisualState) target; + break; + case 8: + this.AllSetNotListening = (System.Windows.VisualState) target; + break; + case 9: + this.initializingContent = (Grid) target; + break; + case 10: + this.allSetNotListeningContent = (Grid) target; + break; + case 11: + this.allSetListeningContent = (Grid) target; + break; + case 12: + this.noAvailableSensorsContent = (Grid) target; + break; + case 13: + this.errorContent = (Grid) target; + break; + case 14: + this.expandedPopup = (Popup) target; + this.expandedPopup.Opened += new EventHandler(this.ExpandedPopupOnOpened); + this.expandedPopup.MouseLeave += new MouseEventHandler(this.OnExpandedPopupMouseLeave); + break; + case 15: + this.popupGrid = (Grid) target; + this.popupGrid.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(this.OnPopupGridGotKeyboardFocus); + break; + case 16: + this.expandedInitializingContent = (Grid) target; + break; + case 17: + this.expandedAllSetNotListeningContent = (Grid) target; + break; + case 18: + this.expandedAllSetListeningContent = (Grid) target; + break; + case 19: + this.expandedNoAvailableSensorsContent = (Grid) target; + break; + case 20: + this.expandedErrorContent = (Grid) target; + break; + case 21: + this.MessageTextBlock = (TextBlock) target; + break; + case 22: + this.TellMeMoreLink = (Hyperlink) target; + this.TellMeMoreLink.RequestNavigate += new RequestNavigateEventHandler(this.TellMeMoreLinkRequestNavigate); + break; + default: + this._contentLoaded = true; + break; + } + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/KinectSensorChooserUIViewModel.cs b/src/Microsoft.Kinect.Toolkit/KinectSensorChooserUIViewModel.cs new file mode 100644 index 0000000..dacdb3e --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/KinectSensorChooserUIViewModel.cs @@ -0,0 +1,209 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.KinectSensorChooserUIViewModel +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Windows; +using System.Windows.Data; +using System.Windows.Input; + +namespace Microsoft.Kinect.Toolkit +{ + public class KinectSensorChooserUIViewModel : DependencyObject + { + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")] + private static readonly DependencyPropertyKey MessagePropertyKey = DependencyProperty.RegisterReadOnly(nameof (Message), typeof (string), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((object) string.Empty)); + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")] + private static readonly DependencyPropertyKey MoreInformationPropertyKey = DependencyProperty.RegisterReadOnly(nameof (MoreInformation), typeof (string), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((object) string.Empty)); + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")] + private static readonly DependencyPropertyKey MoreInformationUriPropertyKey = DependencyProperty.RegisterReadOnly(nameof (MoreInformationUri), typeof (Uri), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((PropertyChangedCallback) null)); + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")] + private static readonly DependencyPropertyKey MoreInformationVisibilityPropertyKey = DependencyProperty.RegisterReadOnly(nameof (MoreInformationVisibility), typeof (Visibility), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((object) Visibility.Collapsed)); + public static readonly DependencyProperty IsListeningProperty = DependencyProperty.Register(nameof (IsListening), typeof (bool), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((object) false, (PropertyChangedCallback) ((o, args) => ((KinectSensorChooserUIViewModel) o).IsListeningChanged()))); + public static readonly DependencyProperty KinectSensorChooserProperty = DependencyProperty.Register(nameof (KinectSensorChooser), typeof (KinectSensorChooser), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((object) null, (PropertyChangedCallback) ((o, args) => ((KinectSensorChooserUIViewModel) o).OnKinectKinectSensorChooserChanged((KinectSensorChooser) args.NewValue)))); + public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(nameof (Status), typeof (ChooserStatus), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((object) ChooserStatus.None, (PropertyChangedCallback) ((o, args) => ((KinectSensorChooserUIViewModel) o).OnStatusChanged()))); + public static readonly DependencyProperty VisualStateProperty = DependencyProperty.Register(nameof (VisualState), typeof (string), typeof (KinectSensorChooserUIViewModel), new PropertyMetadata((PropertyChangedCallback) null)); + public static readonly DependencyProperty MessageProperty = KinectSensorChooserUIViewModel.MessagePropertyKey.DependencyProperty; + public static readonly DependencyProperty MoreInformationProperty = KinectSensorChooserUIViewModel.MoreInformationPropertyKey.DependencyProperty; + public static readonly DependencyProperty MoreInformationUriProperty = KinectSensorChooserUIViewModel.MoreInformationUriPropertyKey.DependencyProperty; + public static readonly DependencyProperty MoreInformationVisibilityProperty = KinectSensorChooserUIViewModel.MoreInformationVisibilityPropertyKey.DependencyProperty; + private RelayCommand retryCommand; + + public bool IsListening + { + get => (bool) this.GetValue(KinectSensorChooserUIViewModel.IsListeningProperty); + set => this.SetValue(KinectSensorChooserUIViewModel.IsListeningProperty, (object) value); + } + + public KinectSensorChooser KinectSensorChooser + { + get => (KinectSensorChooser) this.GetValue(KinectSensorChooserUIViewModel.KinectSensorChooserProperty); + set => this.SetValue(KinectSensorChooserUIViewModel.KinectSensorChooserProperty, (object) value); + } + + public string Message + { + get => (string) this.GetValue(KinectSensorChooserUIViewModel.MessageProperty); + private set => this.SetValue(KinectSensorChooserUIViewModel.MessagePropertyKey, (object) value); + } + + public string MoreInformation + { + get => (string) this.GetValue(KinectSensorChooserUIViewModel.MoreInformationProperty); + private set => this.SetValue(KinectSensorChooserUIViewModel.MoreInformationPropertyKey, (object) value); + } + + public Uri MoreInformationUri + { + get => (Uri) this.GetValue(KinectSensorChooserUIViewModel.MoreInformationUriProperty); + private set => this.SetValue(KinectSensorChooserUIViewModel.MoreInformationUriPropertyKey, (object) value); + } + + public Visibility MoreInformationVisibility + { + get => (Visibility) this.GetValue(KinectSensorChooserUIViewModel.MoreInformationVisibilityProperty); + private set => this.SetValue(KinectSensorChooserUIViewModel.MoreInformationVisibilityPropertyKey, (object) value); + } + + public ICommand RetryCommand + { + get + { + if (this.retryCommand == null) + this.retryCommand = new RelayCommand(new Action(this.Retry), new Func(this.CanRetry)); + return (ICommand) this.retryCommand; + } + } + + public ChooserStatus Status + { + get => (ChooserStatus) this.GetValue(KinectSensorChooserUIViewModel.StatusProperty); + set => this.SetValue(KinectSensorChooserUIViewModel.StatusProperty, (object) value); + } + + public string VisualState + { + get => (string) this.GetValue(KinectSensorChooserUIViewModel.VisualStateProperty); + set => this.SetValue(KinectSensorChooserUIViewModel.VisualStateProperty, (object) value); + } + + private bool CanRetry() => (this.Status & ChooserStatus.SensorConflict) != ChooserStatus.None || this.Status == ChooserStatus.NoAvailableSensors; + + private void IsListeningChanged() => this.UpdateState(); + + private void OnKinectKinectSensorChooserChanged(KinectSensorChooser newValue) + { + if (newValue != null) + { + Binding binding = new Binding("Status") + { + Source = (object) newValue + }; + BindingOperations.SetBinding((DependencyObject) this, KinectSensorChooserUIViewModel.StatusProperty, (BindingBase) binding); + } + else + BindingOperations.ClearBinding((DependencyObject) this, KinectSensorChooserUIViewModel.StatusProperty); + } + + private void OnStatusChanged() => this.UpdateState(); + + private void Retry() + { + if (this.KinectSensorChooser == null) + return; + this.KinectSensorChooser.TryResolveConflict(); + } + + private void UpdateState() + { + string str1 = (string) null; + Uri uri = (Uri) null; + string str2; + string str3; + if ((this.Status & ChooserStatus.SensorStarted) != ChooserStatus.None) + { + if (this.IsListening) + { + str2 = "AllSetListening"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageAllSetListening; + } + else + { + str2 = "AllSetNotListening"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageAllSet; + } + } + else if ((this.Status & ChooserStatus.SensorInitializing) != ChooserStatus.None) + { + str2 = "Initializing"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageInitializing; + } + else if ((this.Status & ChooserStatus.SensorConflict) != ChooserStatus.None) + { + str2 = "Error"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageConflict; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationConflict; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239812"); + } + else if ((this.Status & ChooserStatus.SensorNotGenuine) != ChooserStatus.None) + { + str2 = "Error"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageNotGenuine; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationNotGenuine; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239813"); + } + else if ((this.Status & ChooserStatus.SensorNotSupported) != ChooserStatus.None) + { + str2 = "Error"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageNotSupported; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationNotSupported; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239814"); + } + else if ((this.Status & ChooserStatus.SensorError) != ChooserStatus.None) + { + str2 = "Error"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageError; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationError; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239817"); + } + else if ((this.Status & ChooserStatus.SensorInsufficientBandwidth) != ChooserStatus.None) + { + str2 = "Error"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageInsufficientBandwidth; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationInsufficientBandwidth; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239818"); + } + else if ((this.Status & ChooserStatus.SensorNotPowered) != ChooserStatus.None) + { + str2 = "Error"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageNotPowered; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationNotPowered; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239819"); + } + else if ((this.Status & ChooserStatus.NoAvailableSensors) != ChooserStatus.None) + { + str2 = "NoAvailableSensors"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageNoAvailableSensors; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationNoAvailableSensors; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239815"); + } + else + { + str2 = "Stopped"; + str3 = Microsoft.Kinect.Toolkit.Properties.Resources.MessageNoAvailableSensors; + str1 = Microsoft.Kinect.Toolkit.Properties.Resources.MoreInformationNoAvailableSensors; + uri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239815"); + } + this.Message = str3; + this.MoreInformation = str1; + this.MoreInformationUri = uri; + this.MoreInformationVisibility = uri == (Uri) null ? Visibility.Collapsed : Visibility.Visible; + if (this.retryCommand != null) + this.retryCommand.InvokeCanExecuteChanged(); + this.VisualState = str2; + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/LockExitEventHandler.cs b/src/Microsoft.Kinect.Toolkit/LockExitEventHandler.cs new file mode 100644 index 0000000..e1e4c82 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/LockExitEventHandler.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.LockExitEventHandler +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +namespace Microsoft.Kinect.Toolkit +{ + public delegate void LockExitEventHandler(); +} diff --git a/src/Microsoft.Kinect.Toolkit/Microsoft.Kinect.Toolkit.csproj b/src/Microsoft.Kinect.Toolkit/Microsoft.Kinect.Toolkit.csproj new file mode 100644 index 0000000..2befa43 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/Microsoft.Kinect.Toolkit.csproj @@ -0,0 +1,19 @@ + + + + + net6.0-windows + 1.8.0.0 + true + ..\..\lib + + + + none + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Kinect.Toolkit/Properties/Resources.cs b/src/Microsoft.Kinect.Toolkit/Properties/Resources.cs new file mode 100644 index 0000000..4cd6587 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/Properties/Resources.cs @@ -0,0 +1,86 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.Properties.Resources +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System.CodeDom.Compiler; +using System.ComponentModel; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Resources; +using System.Runtime.CompilerServices; + +namespace Microsoft.Kinect.Toolkit.Properties +{ + [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [DebuggerNonUserCode] + [CompilerGenerated] + internal class Resources + { + private static ResourceManager resourceMan; + private static CultureInfo resourceCulture; + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static ResourceManager ResourceManager + { + get + { + if (Microsoft.Kinect.Toolkit.Properties.Resources.resourceMan == null) + Microsoft.Kinect.Toolkit.Properties.Resources.resourceMan = new ResourceManager("Microsoft.Kinect.Toolkit.Properties.Resources", typeof (Microsoft.Kinect.Toolkit.Properties.Resources).Assembly); + return Microsoft.Kinect.Toolkit.Properties.Resources.resourceMan; + } + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static CultureInfo Culture + { + get => Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture; + set => Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture = value; + } + + internal static string DelegateCommandCastException => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (DelegateCommandCastException), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageAllSet => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageAllSet), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageAllSetListening => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageAllSetListening), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageConflict => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageConflict), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageError => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageError), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageInitializing => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageInitializing), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageInsufficientBandwidth => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageInsufficientBandwidth), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageNoAvailableSensors => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageNoAvailableSensors), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageNotGenuine => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageNotGenuine), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageNotPowered => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageNotPowered), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MessageNotSupported => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MessageNotSupported), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MoreInformationConflict => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MoreInformationConflict), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MoreInformationError => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MoreInformationError), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MoreInformationInsufficientBandwidth => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MoreInformationInsufficientBandwidth), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MoreInformationNoAvailableSensors => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MoreInformationNoAvailableSensors), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MoreInformationNotGenuine => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MoreInformationNotGenuine), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MoreInformationNotPowered => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MoreInformationNotPowered), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string MoreInformationNotSupported => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (MoreInformationNotSupported), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + + internal static string NoDefaultBrowserAvailable => Microsoft.Kinect.Toolkit.Properties.Resources.ResourceManager.GetString(nameof (NoDefaultBrowserAvailable), Microsoft.Kinect.Toolkit.Properties.Resources.resourceCulture); + } +} diff --git a/src/Microsoft.Kinect.Toolkit/Properties/Resources.resx b/src/Microsoft.Kinect.Toolkit/Properties/Resources.resx new file mode 100644 index 0000000..1c6ba56 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/Properties/Resources.resx @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Parameter of type {0} not of of expected type {1} + + + This sensor is not genuine! + + + The Kinect Sensor is plugged into the computer with its USB connection, but the power plug appears to be not powered. + + + The Kinect Sensor is plugged in, however an error has occurred. For steps to resolve, please click the "Help" link. + + + All set! + + + This application needs a genuine Kinect for Windows sensor in order to function. Please plug one into the PC. + + + Initializing... + + + Kinect required + + + The Kinect Sensor needs the majority of the USB Bandwidth of a USB Controller. If other devices are in contention for that bandwidth, the Kinect Sensor may not be able to function. + + + Plug my power cord in! + + + Too many USB devices! Please unplug one or more. + + + Oops, there is an error. + + + This application needs a Kinect for Windows sensor in order to function. However, another application is using the Kinect Sensor. + + + Kinect for Xbox not supported. + + + This application needs a Kinect for Windows sensor in order to function. Please plug one into the PC. + + + This application needs a Kinect for Windows sensor in order to function. Please plug one into the PC. + + + Kinect is listening + + + Unable to launch the default web browser. Trying to navigate to: {0} + + + This Kinect is being used by another application. + + \ No newline at end of file diff --git a/src/Microsoft.Kinect.Toolkit/Properties/Settings.cs b/src/Microsoft.Kinect.Toolkit/Properties/Settings.cs new file mode 100644 index 0000000..8783096 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/Properties/Settings.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.Properties.Settings +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System.CodeDom.Compiler; +using System.Configuration; +using System.Runtime.CompilerServices; + +namespace Microsoft.Kinect.Toolkit.Properties +{ + [CompilerGenerated] + [GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] + internal sealed class Settings : ApplicationSettingsBase + { + private static Settings defaultInstance = (Settings) SettingsBase.Synchronized((SettingsBase) new Settings()); + + public static Settings Default => Settings.defaultInstance; + } +} diff --git a/src/Microsoft.Kinect.Toolkit/RelayCommand.cs b/src/Microsoft.Kinect.Toolkit/RelayCommand.cs new file mode 100644 index 0000000..1992cce --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/RelayCommand.cs @@ -0,0 +1,59 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.RelayCommand +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.Windows.Input; + +namespace Microsoft.Kinect.Toolkit +{ + public class RelayCommand : ICommand + { + private Action executeDelegate; + private Func canExecuteDelegate; + private EventHandler canExecuteEventhandler; + + public RelayCommand(Action executeDelegate, Func canExecuteDelegate) + { + if (executeDelegate == null) + throw new ArgumentNullException(nameof (executeDelegate)); + this.canExecuteDelegate = canExecuteDelegate; + this.executeDelegate = executeDelegate; + } + + public RelayCommand(Action executeDelegate) + : this(executeDelegate, (Func) null) + { + } + + public event EventHandler CanExecuteChanged + { + add + { + this.canExecuteEventhandler += value; + CommandManager.RequerySuggested += value; + } + remove + { + this.canExecuteEventhandler -= value; + CommandManager.RequerySuggested -= value; + } + } + + public bool CanExecute(object parameter) => this.canExecuteDelegate == null || this.canExecuteDelegate(); + + public void Execute(object parameter) => this.executeDelegate(); + + public void InvokeCanExecuteChanged() + { + if (this.canExecuteDelegate == null) + return; + EventHandler executeEventhandler = this.canExecuteEventhandler; + if (executeEventhandler == null) + return; + executeEventhandler((object) this, EventArgs.Empty); + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/RelayCommand`1.cs b/src/Microsoft.Kinect.Toolkit/RelayCommand`1.cs new file mode 100644 index 0000000..c5f5833 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/RelayCommand`1.cs @@ -0,0 +1,76 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.RelayCommand`1 +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.Globalization; +using System.Windows.Input; + +namespace Microsoft.Kinect.Toolkit +{ + public class RelayCommand : ICommand where T : class + { + private Action executeDelegate; + private Predicate canExecuteDelegate; + private EventHandler canExecuteEventhandler; + + public RelayCommand(Action executeDelegate, Predicate canExecuteDelegate) + { + if (executeDelegate == null) + throw new ArgumentNullException(nameof (executeDelegate)); + this.canExecuteDelegate = canExecuteDelegate; + this.executeDelegate = executeDelegate; + } + + public RelayCommand(Action executeDelegate) + : this(executeDelegate, (Predicate) null) + { + } + + public event EventHandler CanExecuteChanged + { + add + { + this.canExecuteEventhandler += value; + CommandManager.RequerySuggested += value; + } + remove + { + this.canExecuteEventhandler -= value; + CommandManager.RequerySuggested -= value; + } + } + + public bool CanExecute(object parameter) + { + if (parameter == null) + throw new ArgumentNullException(nameof (parameter)); + if (this.canExecuteDelegate == null) + return true; + if (!(parameter is T obj)) + throw new InvalidCastException(string.Format((IFormatProvider) CultureInfo.InvariantCulture, Microsoft.Kinect.Toolkit.Properties.Resources.DelegateCommandCastException, (object) parameter.GetType().FullName, (object) typeof (T).FullName)); + return this.canExecuteDelegate(obj); + } + + public void Execute(object parameter) + { + if (parameter == null) + throw new ArgumentNullException(nameof (parameter)); + if (!(parameter is T obj)) + throw new InvalidCastException(string.Format((IFormatProvider) CultureInfo.InvariantCulture, Microsoft.Kinect.Toolkit.Properties.Resources.DelegateCommandCastException, (object) parameter.GetType().FullName, (object) typeof (T).FullName)); + this.executeDelegate(obj); + } + + public void InvokeCanExecuteChanged() + { + if (this.canExecuteDelegate == null) + return; + EventHandler executeEventhandler = this.canExecuteEventhandler; + if (executeEventhandler == null) + return; + executeEventhandler((object) this, EventArgs.Empty); + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/ThreadSafeCollection`1.cs b/src/Microsoft.Kinect.Toolkit/ThreadSafeCollection`1.cs new file mode 100644 index 0000000..37c8013 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/ThreadSafeCollection`1.cs @@ -0,0 +1,183 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Toolkit.ThreadSafeCollection`1 +// Assembly: Microsoft.Kinect.Toolkit, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null +// MVID: 4B38B75B-8556-4BDB-9D68-753B7C4809E2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.Toolkit.dll + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Kinect.Toolkit +{ + public sealed class ThreadSafeCollection : IList, ICollection, IEnumerable, IEnumerable + { + private readonly object lockObject; + private readonly List list = new List(); + + public ThreadSafeCollection() + : this(new object()) + { + } + + public ThreadSafeCollection(object existingLock) => this.lockObject = existingLock; + + public int Count + { + get + { + lock (this.lockObject) + return this.list.Count; + } + } + + public bool IsReadOnly + { + get + { + lock (this.lockObject) + return false; + } + } + + public T this[int index] + { + get + { + lock (this.lockObject) + return this.list[index]; + } + set + { + lock (this.lockObject) + this.list[index] = value; + } + } + + public void Add(T item) + { + lock (this.lockObject) + this.list.Add(item); + } + + public void Clear() + { + lock (this.lockObject) + this.list.Clear(); + } + + public bool Contains(T item) + { + lock (this.lockObject) + return this.list.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + lock (this.lockObject) + this.list.CopyTo(array, arrayIndex); + } + + public void CopyTo(T[] array) + { + lock (this.lockObject) + this.list.CopyTo(array); + } + + public void AddRange(IEnumerable collection) + { + lock (this.lockObject) + this.list.AddRange(collection); + } + + public int IndexOf(T item) + { + lock (this.lockObject) + return this.list.IndexOf(item); + } + + public void Insert(int index, T item) + { + lock (this.lockObject) + this.list.Insert(index, item); + } + + public void RemoveAt(int index) + { + lock (this.lockObject) + this.list.RemoveAt(index); + } + + public bool Remove(T item) + { + lock (this.lockObject) + return this.list.Remove(item); + } + + IEnumerator IEnumerable.GetEnumerator() + { + lock (this.lockObject) + return this.NewEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + lock (this.lockObject) + return (IEnumerator) this.NewEnumerator(); + } + + private IEnumerator NewEnumerator() => (IEnumerator) new ThreadSafeCollection.ThreadSafeEnumerator(this); + + private class ThreadSafeEnumerator : IEnumerator, IDisposable, IEnumerator + { + private readonly ThreadSafeCollection collection; + private readonly IEnumerator enumerator; + + public ThreadSafeEnumerator(ThreadSafeCollection collection) + { + lock (collection.lockObject) + { + this.collection = new ThreadSafeCollection(); + this.collection.AddRange((IEnumerable) collection); + this.enumerator = (IEnumerator) this.collection.list.GetEnumerator(); + } + } + + public T Current + { + get + { + lock (this.collection.lockObject) + return this.enumerator.Current; + } + } + + object IEnumerator.Current + { + get + { + lock (this.collection.lockObject) + return (object) this.enumerator.Current; + } + } + + public void Dispose() + { + lock (this.collection.lockObject) + this.enumerator.Dispose(); + } + + public bool MoveNext() + { + lock (this.collection.lockObject) + return this.enumerator.MoveNext(); + } + + public void Reset() + { + lock (this.collection.lockObject) + this.enumerator.Reset(); + } + } + } +} diff --git a/src/Microsoft.Kinect.Toolkit/kinectsensorchooserui.xaml b/src/Microsoft.Kinect.Toolkit/kinectsensorchooserui.xaml new file mode 100644 index 0000000..8b0f148 --- /dev/null +++ b/src/Microsoft.Kinect.Toolkit/kinectsensorchooserui.xaml @@ -0,0 +1,479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Help + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Kinect/AllFramesReadyEventArgs.cs b/src/Microsoft.Kinect/AllFramesReadyEventArgs.cs new file mode 100644 index 0000000..9862208 --- /dev/null +++ b/src/Microsoft.Kinect/AllFramesReadyEventArgs.cs @@ -0,0 +1,51 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.AllFramesReadyEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + public sealed class AllFramesReadyEventArgs : EventArgs + { + private readonly ColorImageFrameReadyEventArgs _colorArgs; + private readonly DepthImageFrameReadyEventArgs _depthArgs; + private readonly SkeletonFrameReadyEventArgs _skeletonArgs; + + internal AllFramesReadyEventArgs( + ColorImageFrameReadyEventArgs colorArgs, + DepthImageFrameReadyEventArgs depthArgs, + SkeletonFrameReadyEventArgs skeletonArgs) + { + this._colorArgs = colorArgs; + this._depthArgs = depthArgs; + this._skeletonArgs = skeletonArgs; + } + + public ColorImageFrame OpenColorImageFrame() + { + if (this._colorArgs == null) + return (ColorImageFrame) null; + KinectEtwProvider.EventWriteManagedOpenFrameFromAllFramesEventInfo(0); + return this._colorArgs.OpenColorImageFrame(); + } + + public DepthImageFrame OpenDepthImageFrame() + { + if (this._depthArgs == null) + return (DepthImageFrame) null; + KinectEtwProvider.EventWriteManagedOpenFrameFromAllFramesEventInfo(1); + return this._depthArgs.OpenDepthImageFrame(); + } + + public SkeletonFrame OpenSkeletonFrame() + { + if (this._skeletonArgs == null) + return (SkeletonFrame) null; + KinectEtwProvider.EventWriteManagedOpenFrameFromAllFramesEventInfo(2); + return this._skeletonArgs.OpenSkeletonFrame(); + } + } +} diff --git a/src/Microsoft.Kinect/AutoLock.cs b/src/Microsoft.Kinect/AutoLock.cs new file mode 100644 index 0000000..02dfb25 --- /dev/null +++ b/src/Microsoft.Kinect/AutoLock.cs @@ -0,0 +1,75 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.AutoLock +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Threading; + +namespace Microsoft.Kinect +{ + internal struct AutoLock : IDisposable + { + private readonly ReaderWriterLockSlim _lock; + private AutoLock.AutoLockMode _lockMode; + + public AutoLock( + ReaderWriterLockSlim readerWriterLock, + AutoLock.AutoLockMode initialAutoLockMode) + { + this._lock = readerWriterLock; + this._lockMode = initialAutoLockMode; + switch (this._lockMode) + { + case AutoLock.AutoLockMode.Read: + this._lock.EnterReadLock(); + break; + case AutoLock.AutoLockMode.UpgradeableRead: + this._lock.EnterUpgradeableReadLock(); + break; + case AutoLock.AutoLockMode.Write: + this._lock.EnterWriteLock(); + break; + default: + throw new ArgumentOutOfRangeException(nameof (initialAutoLockMode)); + } + } + + public AutoLock UpgradeToWrite() + { + if (this._lockMode != AutoLock.AutoLockMode.UpgradeableRead) + throw new InvalidOperationException(); + return new AutoLock(this._lock, AutoLock.AutoLockMode.Write); + } + + public void Dispose() + { + switch (this._lockMode) + { + case AutoLock.AutoLockMode.None: + this._lockMode = AutoLock.AutoLockMode.None; + break; + case AutoLock.AutoLockMode.Read: + this._lock.ExitReadLock(); + goto case AutoLock.AutoLockMode.None; + case AutoLock.AutoLockMode.UpgradeableRead: + this._lock.ExitUpgradeableReadLock(); + goto case AutoLock.AutoLockMode.None; + case AutoLock.AutoLockMode.Write: + this._lock.ExitWriteLock(); + goto case AutoLock.AutoLockMode.None; + default: + throw new InvalidOperationException(); + } + } + + internal enum AutoLockMode + { + None, + Read, + UpgradeableRead, + Write, + } + } +} diff --git a/src/Microsoft.Kinect/BacklightCompensationMode.cs b/src/Microsoft.Kinect/BacklightCompensationMode.cs new file mode 100644 index 0000000..cf7db04 --- /dev/null +++ b/src/Microsoft.Kinect/BacklightCompensationMode.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.BacklightCompensationMode +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum BacklightCompensationMode + { + AverageBrightness = 0, + CenterPriority = 1, + LowlightsPriority = 2, + CenterOnly = 4, + } +} diff --git a/src/Microsoft.Kinect/BeamAngleChangedEventArgs.cs b/src/Microsoft.Kinect/BeamAngleChangedEventArgs.cs new file mode 100644 index 0000000..0959545 --- /dev/null +++ b/src/Microsoft.Kinect/BeamAngleChangedEventArgs.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.BeamAngleChangedEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + public sealed class BeamAngleChangedEventArgs : EventArgs + { + internal BeamAngleChangedEventArgs() + { + } + + public double Angle { get; internal set; } + } +} diff --git a/src/Microsoft.Kinect/BeamAngleMode.cs b/src/Microsoft.Kinect/BeamAngleMode.cs new file mode 100644 index 0000000..96b5e2f --- /dev/null +++ b/src/Microsoft.Kinect/BeamAngleMode.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.BeamAngleMode +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum BeamAngleMode + { + Automatic, + Adaptive, + Manual, + } +} diff --git a/src/Microsoft.Kinect/BoneOrientation.cs b/src/Microsoft.Kinect/BoneOrientation.cs new file mode 100644 index 0000000..6340425 --- /dev/null +++ b/src/Microsoft.Kinect/BoneOrientation.cs @@ -0,0 +1,85 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.BoneOrientation +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; + +namespace Microsoft.Kinect +{ + public class BoneOrientation + { + private static readonly JointType[] c_parents = new JointType[20] + { + JointType.HipCenter, + JointType.HipCenter, + JointType.Spine, + JointType.ShoulderCenter, + JointType.ShoulderCenter, + JointType.ShoulderLeft, + JointType.ElbowLeft, + JointType.WristLeft, + JointType.ShoulderCenter, + JointType.ShoulderRight, + JointType.ElbowRight, + JointType.WristRight, + JointType.HipCenter, + JointType.HipLeft, + JointType.KneeLeft, + JointType.AnkleLeft, + JointType.HipCenter, + JointType.HipRight, + JointType.KneeRight, + JointType.AnkleRight + }; + + public BoneOrientation(JointType jointType) + { + this.EndJoint = jointType; + this.StartJoint = BoneOrientation.c_parents[(int) jointType]; + this.HierarchicalRotation = new BoneRotation(); + this.AbsoluteRotation = new BoneRotation(); + this.SetDefaults(); + } + + internal void SetDefaults() + { + this.HierarchicalRotation.Matrix = Matrix4.Identity; + this.HierarchicalRotation.Quaternion = new Vector4() + { + W = 1f + }; + this.AbsoluteRotation.Matrix = Matrix4.Identity; + this.AbsoluteRotation.Quaternion = new Vector4() + { + W = 1f + }; + } + + internal void CopyFrom( + ref _NUI_SKELETON_BONE_ORIENTATION nativeBoneOrientation) + { + this.HierarchicalRotation.Matrix = Matrix4.CopyFrom(ref nativeBoneOrientation.hierarchicalRotation.rotationMatrix); + this.HierarchicalRotation.Quaternion = Vector4.CopyFrom(ref nativeBoneOrientation.hierarchicalRotation.rotationQuaternion); + this.AbsoluteRotation.Matrix = Matrix4.CopyFrom(ref nativeBoneOrientation.absoluteRotation.rotationMatrix); + this.AbsoluteRotation.Quaternion = Vector4.CopyFrom(ref nativeBoneOrientation.absoluteRotation.rotationQuaternion); + } + + internal void CopyFrom(BoneOrientation sourceBoneOrientation) + { + this.HierarchicalRotation.Matrix = sourceBoneOrientation.HierarchicalRotation.Matrix; + this.HierarchicalRotation.Quaternion = sourceBoneOrientation.HierarchicalRotation.Quaternion; + this.AbsoluteRotation.Matrix = sourceBoneOrientation.AbsoluteRotation.Matrix; + this.AbsoluteRotation.Quaternion = sourceBoneOrientation.AbsoluteRotation.Quaternion; + } + + public JointType EndJoint { get; internal set; } + + public JointType StartJoint { get; internal set; } + + public BoneRotation HierarchicalRotation { get; set; } + + public BoneRotation AbsoluteRotation { get; set; } + } +} diff --git a/src/Microsoft.Kinect/BoneOrientationCollection.cs b/src/Microsoft.Kinect/BoneOrientationCollection.cs new file mode 100644 index 0000000..8a91d08 --- /dev/null +++ b/src/Microsoft.Kinect/BoneOrientationCollection.cs @@ -0,0 +1,76 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.BoneOrientationCollection +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace Microsoft.Kinect +{ + public class BoneOrientationCollection : IEnumerable, IEnumerable + { + private readonly BoneOrientation[] _boneOrientations; + private bool _isValid; + [XmlIgnore] + [NonSerialized] + private readonly Skeleton _skeletonBackReference; + + internal BoneOrientationCollection(Skeleton backReference) + { + this._boneOrientations = new BoneOrientation[Skeleton.JointTypeValues.Length]; + foreach (JointType jointTypeValue in Skeleton.JointTypeValues) + this._boneOrientations[(int) jointTypeValue] = new BoneOrientation(jointTypeValue); + this._skeletonBackReference = backReference; + } + + public int Count => this._boneOrientations.Length; + + internal bool IsValid + { + get => this._isValid; + set => this._isValid = value; + } + + public BoneOrientation this[JointType jointType] + { + get + { + this.Recalculate(); + return this._boneOrientations[(int) jointType]; + } + set + { + if (value == null || value.EndJoint != jointType) + throw new ArgumentException(Resources.IncorrectJointType); + this.Recalculate(); + this._isValid = true; + this._boneOrientations[(int) jointType] = value; + } + } + + public IEnumerator GetEnumerator() + { + this.Recalculate(); + return this._boneOrientations.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + this.Recalculate(); + return ((IEnumerable) this._boneOrientations).GetEnumerator(); + } + + internal void Recalculate() + { + if (this._isValid || this._skeletonBackReference == null) + return; + this._isValid = this._skeletonBackReference.CalculateBoneOrientations(this._boneOrientations); + } + + internal void Invalidate() => this._isValid = false; + } +} diff --git a/src/Microsoft.Kinect/BoneRotation.cs b/src/Microsoft.Kinect/BoneRotation.cs new file mode 100644 index 0000000..eba4270 --- /dev/null +++ b/src/Microsoft.Kinect/BoneRotation.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.BoneRotation +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public class BoneRotation + { + public Matrix4 Matrix { get; set; } + + public Vector4 Quaternion { get; set; } + } +} diff --git a/src/Microsoft.Kinect/ColorCameraSettings.cs b/src/Microsoft.Kinect/ColorCameraSettings.cs new file mode 100644 index 0000000..561c383 --- /dev/null +++ b/src/Microsoft.Kinect/ColorCameraSettings.cs @@ -0,0 +1,302 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ColorCameraSettings +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System.ComponentModel; + +namespace Microsoft.Kinect +{ + public sealed class ColorCameraSettings : INotifyPropertyChanged + { + private readonly NuiColorCameraSettings _colorCameraSettings; + + internal ColorCameraSettings(KinectSensor mainNui) => this._colorCameraSettings = mainNui.NuiSensor.NuiGetColorCameraSettings(); + + public bool AutoExposure + { + get => this._colorCameraSettings.GetAutoExposure(); + set + { + if (value == this.AutoExposure) + return; + this._colorCameraSettings.SetAutoExposure(value); + this.NotifyPropertyChanged(nameof (AutoExposure)); + } + } + + public double ExposureTime + { + get => this._colorCameraSettings.GetExposureTime(); + set + { + if (value.Equals(this.ExposureTime)) + return; + this._colorCameraSettings.SetExposureTime(value); + this.NotifyPropertyChanged(nameof (ExposureTime)); + } + } + + public double MinExposureTime => this._colorCameraSettings.GetMinExposureTime(); + + public double MaxExposureTime => this._colorCameraSettings.GetMaxExposureTime(); + + public double FrameInterval + { + get => this._colorCameraSettings.GetFrameInterval(); + set + { + if (value.Equals(this.FrameInterval)) + return; + this._colorCameraSettings.SetFrameInterval(value); + this.NotifyPropertyChanged(nameof (FrameInterval)); + } + } + + public double MinFrameInterval => this._colorCameraSettings.GetMinFrameInterval(); + + public double MaxFrameInterval => this._colorCameraSettings.GetMaxFrameInterval(); + + public double Brightness + { + get => this._colorCameraSettings.GetBrightness(); + set + { + if (value.Equals(this.Brightness)) + return; + this._colorCameraSettings.SetBrightness(value); + this.NotifyPropertyChanged(nameof (Brightness)); + } + } + + public double MinBrightness => this._colorCameraSettings.GetMinBrightness(); + + public double MaxBrightness => this._colorCameraSettings.GetMaxBrightness(); + + public BacklightCompensationMode BacklightCompensationMode + { + get => (BacklightCompensationMode) this._colorCameraSettings.GetBacklightCompensationMode(); + set + { + if (value == this.BacklightCompensationMode) + return; + this._colorCameraSettings.SetBacklightCompensationMode((_NUI_BACKLIGHT_COMPENSATION_MODE) value); + this.NotifyPropertyChanged(nameof (BacklightCompensationMode)); + } + } + + public PowerLineFrequency PowerLineFrequency + { + get => (PowerLineFrequency) this._colorCameraSettings.GetPowerLineFrequency(); + set + { + if (value == this.PowerLineFrequency) + return; + this._colorCameraSettings.SetPowerLineFrequency((_NUI_POWER_LINE_FREQUENCY) value); + this.NotifyPropertyChanged(nameof (PowerLineFrequency)); + } + } + + public double Gain + { + get => this._colorCameraSettings.GetGain(); + set + { + if (value.Equals(this.Gain)) + return; + this._colorCameraSettings.SetGain(value); + this.NotifyPropertyChanged(nameof (Gain)); + } + } + + public double MinGain => this._colorCameraSettings.GetMinGain(); + + public double MaxGain => this._colorCameraSettings.GetMaxGain(); + + public bool AutoWhiteBalance + { + get => this._colorCameraSettings.GetAutoWhiteBalance(); + set + { + if (value == this.AutoWhiteBalance) + return; + this._colorCameraSettings.SetAutoWhiteBalance(value); + this.NotifyPropertyChanged(nameof (AutoWhiteBalance)); + } + } + + public int WhiteBalance + { + get => this._colorCameraSettings.GetWhiteBalance(); + set + { + if (value == this.WhiteBalance) + return; + this._colorCameraSettings.SetWhiteBalance(value); + this.NotifyPropertyChanged(nameof (WhiteBalance)); + } + } + + public int MinWhiteBalance => this._colorCameraSettings.GetMinWhiteBalance(); + + public int MaxWhiteBalance => this._colorCameraSettings.GetMaxWhiteBalance(); + + public double Contrast + { + get => this._colorCameraSettings.GetContrast(); + set + { + if (value.Equals(this.Contrast)) + return; + this._colorCameraSettings.SetContrast(value); + this.NotifyPropertyChanged(nameof (Contrast)); + } + } + + public double MinContrast => this._colorCameraSettings.GetMinContrast(); + + public double MaxContrast => this._colorCameraSettings.GetMaxContrast(); + + public double Hue + { + get => this._colorCameraSettings.GetHue(); + set + { + if (value.Equals(this.Hue)) + return; + this._colorCameraSettings.SetHue(value); + this.NotifyPropertyChanged(nameof (Hue)); + } + } + + public double MinHue => this._colorCameraSettings.GetMinHue(); + + public double MaxHue => this._colorCameraSettings.GetMaxHue(); + + public double Saturation + { + get => this._colorCameraSettings.GetSaturation(); + set + { + if (value.Equals(this.Saturation)) + return; + this._colorCameraSettings.SetSaturation(value); + this.NotifyPropertyChanged(nameof (Saturation)); + } + } + + public double MinSaturation => this._colorCameraSettings.GetMinSaturation(); + + public double MaxSaturation => this._colorCameraSettings.GetMaxSaturation(); + + public double Gamma + { + get => this._colorCameraSettings.GetGamma(); + set + { + if (value.Equals(this.Gamma)) + return; + this._colorCameraSettings.SetGamma(value); + this.NotifyPropertyChanged(nameof (Gamma)); + } + } + + public double MinGamma => this._colorCameraSettings.GetMinGamma(); + + public double MaxGamma => this._colorCameraSettings.GetMaxGamma(); + + public double Sharpness + { + get => this._colorCameraSettings.GetSharpness(); + set + { + if (value.Equals(this.Sharpness)) + return; + this._colorCameraSettings.SetSharpness(value); + this.NotifyPropertyChanged(nameof (Sharpness)); + } + } + + public double MinSharpness => this._colorCameraSettings.GetMinSharpness(); + + public double MaxSharpness => this._colorCameraSettings.GetMaxSharpness(); + + public void ResetToDefault() + { + bool autoExposure = this.AutoExposure; + bool autoWhiteBalance = this.AutoWhiteBalance; + BacklightCompensationMode compensationMode = this.BacklightCompensationMode; + double brightness = this.Brightness; + double contrast = this.Contrast; + double exposureTime = this.ExposureTime; + double frameInterval = this.FrameInterval; + double gain = this.Gain; + double gamma = this.Gamma; + double hue = this.Hue; + PowerLineFrequency powerLineFrequency = this.PowerLineFrequency; + double saturation = this.Saturation; + double sharpness = this.Sharpness; + int whiteBalance = this.WhiteBalance; + this._colorCameraSettings.ResetCameraSettingsToDefault(); + this.CheckAndTriggerIfChanged(autoExposure, this.AutoExposure, "AutoExposure"); + this.CheckAndTriggerIfChanged(autoWhiteBalance, this.AutoWhiteBalance, "AutoWhiteBalance"); + this.CheckAndTriggerIfChanged(compensationMode, this.BacklightCompensationMode, "BacklightCompensationMode"); + this.CheckAndTriggerIfChanged(brightness, this.Brightness, "Brightness"); + this.CheckAndTriggerIfChanged(contrast, this.Contrast, "Contrast"); + this.CheckAndTriggerIfChanged(exposureTime, this.ExposureTime, "ExposureTime"); + this.CheckAndTriggerIfChanged(frameInterval, this.FrameInterval, "FrameInterval"); + this.CheckAndTriggerIfChanged(gain, this.Gain, "Gain"); + this.CheckAndTriggerIfChanged(gamma, this.Gamma, "Gamma"); + this.CheckAndTriggerIfChanged(hue, this.Hue, "Hue"); + this.CheckAndTriggerIfChanged(powerLineFrequency, this.PowerLineFrequency, "PowerLineFrequency"); + this.CheckAndTriggerIfChanged(saturation, this.Saturation, "Saturation"); + this.CheckAndTriggerIfChanged(sharpness, this.Sharpness, "Sharpness"); + this.CheckAndTriggerIfChanged((double) whiteBalance, (double) this.WhiteBalance, "WhiteBalance"); + } + + private void CheckAndTriggerIfChanged(double oldValue, double newValue, string propertyName) + { + if (oldValue.Equals(newValue)) + return; + this.NotifyPropertyChanged(propertyName); + } + + private void CheckAndTriggerIfChanged(bool oldValue, bool newValue, string propertyName) + { + if (oldValue == newValue) + return; + this.NotifyPropertyChanged(propertyName); + } + + private void CheckAndTriggerIfChanged( + PowerLineFrequency oldValue, + PowerLineFrequency newValue, + string propertyName) + { + if (oldValue == newValue) + return; + this.NotifyPropertyChanged(propertyName); + } + + private void CheckAndTriggerIfChanged( + BacklightCompensationMode oldValue, + BacklightCompensationMode newValue, + string propertyName) + { + if (oldValue == newValue) + return; + this.NotifyPropertyChanged(propertyName); + } + + public event PropertyChangedEventHandler PropertyChanged; + + private void NotifyPropertyChanged(string propertyName) + { + if (this.PropertyChanged == null) + return; + this.PropertyChanged((object) this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/src/Microsoft.Kinect/ColorImageFormat.cs b/src/Microsoft.Kinect/ColorImageFormat.cs new file mode 100644 index 0000000..0fe6926 --- /dev/null +++ b/src/Microsoft.Kinect/ColorImageFormat.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ColorImageFormat +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum ColorImageFormat + { + Undefined, + RgbResolution640x480Fps30, + RgbResolution1280x960Fps12, + YuvResolution640x480Fps15, + RawYuvResolution640x480Fps15, + InfraredResolution640x480Fps30, + RawBayerResolution640x480Fps30, + RawBayerResolution1280x960Fps12, + } +} diff --git a/src/Microsoft.Kinect/ColorImageFrame.cs b/src/Microsoft.Kinect/ColorImageFrame.cs new file mode 100644 index 0000000..8830aab --- /dev/null +++ b/src/Microsoft.Kinect/ColorImageFrame.cs @@ -0,0 +1,92 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ColorImageFrame +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + public sealed class ColorImageFrame : ImageFrame + { + private readonly ColorImageStream _colorImageStream; + private DataPool.Entry _frameData; + private readonly object _dataAccessLock = new object(); + + private ColorImageFrame( + ColorImageStream colorImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags, + DataPool.Entry pixelData) + : base(pixelData.Value1, pixelData.Value2, frameNumber, timestamp, frameFlags) + { + this._colorImageStream = colorImageStream; + this._frameData = pixelData; + this.Format = ColorImageStream.LookUpColorImageFormat(pixelData.Value1, pixelData.Value2); + } + + internal static ColorImageFrame Create( + ColorImageStream colorImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags) + { + ColorImageFrame colorImageFrame = (ColorImageFrame) null; + DataPool.Entry pixelData = colorImageStream.LockPixelData(frameNumber); + if (pixelData != null) + colorImageFrame = new ColorImageFrame(colorImageStream, frameNumber, timestamp, frameFlags, pixelData); + return colorImageFrame; + } + + public ColorImageFormat Format { get; private set; } + + public override int PixelDataLength => this.Width * this.Height * this.BytesPerPixel; + + public byte[] GetRawPixelData() => this._frameData.Value3; + + public unsafe void CopyPixelDataTo(byte[] pixelData) + { + if (pixelData == null) + throw new ArgumentNullException(nameof (pixelData)); + if (pixelData.Length != this.PixelDataLength) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (pixelData)); + lock (this._dataAccessLock) + { + if (this._frameData == null) + throw new ObjectDisposedException(nameof (ColorImageFrame)); + fixed (byte* source = this._frameData.Value3) + Marshal.Copy((IntPtr) (void*) source, pixelData, 0, this.PixelDataLength); + } + } + + public void CopyPixelDataTo(IntPtr pixelData, int pixelDataLength) + { + if (pixelData == IntPtr.Zero) + throw new ArgumentNullException(nameof (pixelData)); + if (pixelDataLength != this.PixelDataLength) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (pixelDataLength)); + lock (this._dataAccessLock) + { + if (this._frameData == null) + throw new ObjectDisposedException(nameof (ColorImageFrame)); + Marshal.Copy(this._frameData.Value3, 0, pixelData, pixelDataLength); + } + } + + protected override void Dispose(bool disposing) + { + if (!disposing) + return; + lock (this._dataAccessLock) + { + this._colorImageStream.UnlockPixelData(this._frameData); + this._frameData = (DataPool.Entry) null; + } + } + + internal override ImageStream SourceStream => (ImageStream) this._colorImageStream; + } +} diff --git a/src/Microsoft.Kinect/ColorImageFrameReadyEventArgs.cs b/src/Microsoft.Kinect/ColorImageFrameReadyEventArgs.cs new file mode 100644 index 0000000..5e68063 --- /dev/null +++ b/src/Microsoft.Kinect/ColorImageFrameReadyEventArgs.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ColorImageFrameReadyEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + public sealed class ColorImageFrameReadyEventArgs : EventArgs + { + private readonly ColorImageStream _colorImageStream; + private readonly int _frameNumber; + private readonly long _timestamp; + private readonly ImageFrameFlags _frameFlags; + private bool _isInvalid; + + private ColorImageFrameReadyEventArgs( + ColorImageStream colorImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags, + bool isInvalid) + { + this._colorImageStream = colorImageStream; + this._frameNumber = frameNumber; + this._timestamp = timestamp; + this._frameFlags = frameFlags; + this._isInvalid = isInvalid; + } + + internal static ColorImageFrameReadyEventArgs Create( + ColorImageStream colorImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags) + { + return new ColorImageFrameReadyEventArgs(colorImageStream, frameNumber, timestamp, frameFlags, false); + } + + internal static ColorImageFrameReadyEventArgs CreateInvalid() => new ColorImageFrameReadyEventArgs((ColorImageStream) null, 0, 0L, ImageFrameFlags.NUI_IMAGE_FRAME_FLAG_NONE, true); + + public ColorImageFrame OpenColorImageFrame() + { + if (this._isInvalid) + return (ColorImageFrame) null; + KinectEtwProvider.EventWriteManagedOpenFrameFromEventInfo(0); + ColorImageFrame colorImageFrame = ColorImageFrame.Create(this._colorImageStream, this._frameNumber, this._timestamp, this._frameFlags); + if (colorImageFrame == null) + this._isInvalid = true; + return colorImageFrame; + } + } +} diff --git a/src/Microsoft.Kinect/ColorImagePoint.cs b/src/Microsoft.Kinect/ColorImagePoint.cs new file mode 100644 index 0000000..e647844 --- /dev/null +++ b/src/Microsoft.Kinect/ColorImagePoint.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ColorImagePoint +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Diagnostics; + +namespace Microsoft.Kinect +{ + [DebuggerDisplay("X:{X} Y:{Y}")] + public struct ColorImagePoint + { + public int X { get; set; } + + public int Y { get; set; } + + public override int GetHashCode() => this.X.GetHashCode() + this.Y.GetHashCode(); + + public override bool Equals(object obj) => obj is ColorImagePoint imagePoint && this.Equals(imagePoint); + + public bool Equals(ColorImagePoint imagePoint) => this.X == imagePoint.X && this.Y == imagePoint.Y; + + public static bool operator ==(ColorImagePoint imagePoint1, ColorImagePoint imagePoint2) => imagePoint1.Equals(imagePoint2); + + public static bool operator !=(ColorImagePoint imagePoint1, ColorImagePoint imagePoint2) => !imagePoint1.Equals(imagePoint2); + } +} diff --git a/src/Microsoft.Kinect/ColorImageStream.cs b/src/Microsoft.Kinect/ColorImageStream.cs new file mode 100644 index 0000000..4bd04f1 --- /dev/null +++ b/src/Microsoft.Kinect/ColorImageStream.cs @@ -0,0 +1,229 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ColorImageStream +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + public sealed class ColorImageStream : ImageStream + { + private ImageType _imageType; + private ColorImageFormat _colorImageFormat; + private readonly DataPool _colorDataPool; + private ColorCameraSettings _cameraSettings; + + private float ScaleValue(float value) => this.Format == ColorImageFormat.RgbResolution1280x960Fps12 || this.Format == ColorImageFormat.RawBayerResolution1280x960Fps12 ? 2f * value : value; + + public float NominalFocalLengthInPixels => this.ScaleValue(531.15f); + + public float NominalInverseFocalLengthInPixels => 1f / this.NominalFocalLengthInPixels; + + public float NominalDiagonalFieldOfView => this.ScaleValue(73.9f); + + public float NominalHorizontalFieldOfView => this.ScaleValue(62f); + + public float NominalVerticalFieldOfView => this.ScaleValue(48.6f); + + public ColorCameraSettings CameraSettings + { + get + { + if (this._cameraSettings == null) + this._cameraSettings = new ColorCameraSettings(this.Sensor); + return this._cameraSettings; + } + } + + internal ColorImageStream(KinectSensor mainNui) + : base(mainNui) + { + this._colorDataPool = new DataPool(this.BufferCount); + this.Format = ColorImageFormat.RgbResolution640x480Fps30; + } + + public void Enable() => this.Enable(ColorImageFormat.RgbResolution640x480Fps30); + + public void Enable(ColorImageFormat format) + { + if (format == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (format)); + if (this.Sensor.IsRunning && this.IsEnabled && this.Format == format) + return; + this.Format = format; + this.InternalEnable(); + } + + public ColorImageFormat Format + { + get => this._colorImageFormat; + private set + { + this._colorImageFormat = value; + switch (this._colorImageFormat) + { + case ColorImageFormat.RgbResolution640x480Fps30: + case ColorImageFormat.RgbResolution1280x960Fps12: + this._imageType = ImageType.Color; + this.FrameBytesPerPixel = 4; + break; + case ColorImageFormat.YuvResolution640x480Fps15: + this._imageType = ImageType.ColorYuv; + this.FrameBytesPerPixel = 4; + break; + case ColorImageFormat.RawYuvResolution640x480Fps15: + this._imageType = ImageType.ColorYuvRaw; + this.FrameBytesPerPixel = 2; + break; + case ColorImageFormat.InfraredResolution640x480Fps30: + this._imageType = ImageType.ColorInfrared; + this.FrameBytesPerPixel = 2; + break; + case ColorImageFormat.RawBayerResolution640x480Fps30: + case ColorImageFormat.RawBayerResolution1280x960Fps12: + this._imageType = ImageType.ColorBayer; + this.FrameBytesPerPixel = 1; + break; + default: + throw new ArgumentException("Invalid ColorImageFormat.", nameof (value)); + } + this.Resolution = ColorImageStream.LookUpImageResolution(this.Format); + this.FillHeightWidth(); + this.FramePixelDataLength = this.FrameWidth * this.FrameHeight * this.FrameBytesPerPixel; + } + } + + public ColorImageFrame OpenNextFrame(int millisecondsWait) + { + ColorImageFrame colorImageFrame = (ColorImageFrame) null; + if (!this.Sensor.IsRunning) + throw new InvalidOperationException(Resources.SensorMustBeRunning); + if (!this.IsEnabled) + throw new InvalidOperationException(Resources.ColorStreamMustBeEnabled); + if (this.Sensor.HasColorInvocations) + throw new InvalidOperationException(Resources.CannotPollAndUseEvents); + KinectEtwProvider.EventWriteManagedOpenNextFrameInfo(0, millisecondsWait); + int frameNumber; + long timestamp; + ImageFrameFlags frameFlags; + if (this.TryGetNextFrameInternal(millisecondsWait, out frameNumber, out timestamp, out frameFlags)) + colorImageFrame = ColorImageFrame.Create(this, frameNumber, timestamp, frameFlags); + return colorImageFrame; + } + + internal override ImageType ImageType => this._imageType; + + internal override void StorePixels( + int frameNumber, + _NUI_LOCKED_RECT lockedRect, + ImageType imageType, + ImageResolution resolution, + IntPtr nativeStreamHandle, + ref _NUI_IMAGE_FRAME pNativeFrame) + { + DataPool.Entry entry = this._colorDataPool.CheckOutFreeEntryForUpdate(); + entry.Key = frameNumber; + entry.Value1 = imageType; + entry.Value2 = resolution; + int width; + int height; + ImageStream.ResolutionToHeightWidth(resolution, out width, out height); + int bytesPerPixel = ImageStream.ImageTypeToBytesPerPixel(imageType); + int length = width * height * bytesPerPixel; + if (entry.Value3 == null || entry.Value3.Length != length) + entry.Value3 = new byte[length]; + if (length == lockedRect.size) + Marshal.Copy(lockedRect.pBits, entry.Value3, 0, entry.Value3.Length); + this._colorDataPool.CheckInEntryForUpdate(entry); + } + + internal DataPool.Entry LockPixelData( + int frameNumber) + { + DataPool.Entry entry; + this._colorDataPool.TryLockEntry(frameNumber, out entry); + return entry; + } + + internal void UnlockPixelData( + DataPool.Entry entry) + { + this._colorDataPool.UnlockEntry(entry); + } + + internal static ImageResolution LookUpImageResolution(ColorImageFormat format) + { + switch (format) + { + case ColorImageFormat.RgbResolution640x480Fps30: + case ColorImageFormat.YuvResolution640x480Fps15: + case ColorImageFormat.RawYuvResolution640x480Fps15: + case ColorImageFormat.InfraredResolution640x480Fps30: + case ColorImageFormat.RawBayerResolution640x480Fps30: + return ImageResolution.Resolution640x480; + case ColorImageFormat.RgbResolution1280x960Fps12: + case ColorImageFormat.RawBayerResolution1280x960Fps12: + return ImageResolution.Resolution1280x960; + default: + return ImageResolution.Invalid; + } + } + + internal static ColorImageFormat LookUpColorImageFormat( + ImageType imageType, + ImageResolution imageResolution) + { + switch (imageType) + { + case ImageType.Color: + switch (imageResolution) + { + case ImageResolution.Resolution640x480: + return ColorImageFormat.RgbResolution640x480Fps30; + case ImageResolution.Resolution1280x960: + return ColorImageFormat.RgbResolution1280x960Fps12; + } + break; + case ImageType.ColorYuv: + if (imageResolution == ImageResolution.Resolution640x480) + return ColorImageFormat.YuvResolution640x480Fps15; + break; + case ImageType.ColorYuvRaw: + if (imageResolution == ImageResolution.Resolution640x480) + return ColorImageFormat.RawYuvResolution640x480Fps15; + break; + case ImageType.ColorInfrared: + if (imageResolution == ImageResolution.Resolution640x480) + return ColorImageFormat.InfraredResolution640x480Fps30; + break; + case ImageType.ColorBayer: + switch (imageResolution) + { + case ImageResolution.Resolution640x480: + return ColorImageFormat.RawBayerResolution640x480Fps30; + case ImageResolution.Resolution1280x960: + return ColorImageFormat.RawBayerResolution1280x960Fps12; + } + break; + } + throw new InvalidOperationException(); + } + + internal static int LookUpPixelDataLength(ColorImageFormat format) + { + switch (ColorImageStream.LookUpImageResolution(format)) + { + case ImageResolution.Resolution640x480: + return 307200; + case ImageResolution.Resolution1280x960: + return 1228800; + default: + return 0; + } + } + } +} diff --git a/src/Microsoft.Kinect/ContextEventHandler`1.cs b/src/Microsoft.Kinect/ContextEventHandler`1.cs new file mode 100644 index 0000000..208f7c6 --- /dev/null +++ b/src/Microsoft.Kinect/ContextEventHandler`1.cs @@ -0,0 +1,182 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ContextEventHandler`1 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; + +namespace Microsoft.Kinect +{ + internal class ContextEventHandler : IDisposable where T : EventArgs + { + private readonly ThreadSafeList.ContextHandlerPair> _actualHandlers; + private readonly ContextEventHandler.ContextSynchronizationMethod _method; + private bool _isDisposed; + + public ContextEventHandler( + ContextEventHandler.ContextSynchronizationMethod method = ContextEventHandler.ContextSynchronizationMethod.Post) + { + this._isDisposed = false; + this._method = method; + this._actualHandlers = new ThreadSafeList.ContextHandlerPair>(); + } + + public bool HasHandlers => this._actualHandlers.Count > 0; + + public void AddHandler(EventHandler originalHandler) + { + if (originalHandler == null) + return; + this._actualHandlers.Add(new ContextEventHandler.ContextHandlerPair(originalHandler, new ContextEventHandler.SynchronizationContextIdentifier(SynchronizationContext.Current))); + } + + public void RemoveHandler(EventHandler originalHandler) + { + ContextEventHandler.SynchronizationContextIdentifier contextIdentifier = new ContextEventHandler.SynchronizationContextIdentifier(SynchronizationContext.Current); + ContextEventHandler.ContextHandlerPair contextHandlerPair = (ContextEventHandler.ContextHandlerPair) null; + foreach (ContextEventHandler.ContextHandlerPair actualHandler in (IEnumerable.ContextHandlerPair>) this._actualHandlers) + { + EventHandler handler = actualHandler.Handler; + ContextEventHandler.SynchronizationContextIdentifier contextId = actualHandler.ContextId; + if (contextIdentifier == contextId && handler == originalHandler) + { + contextHandlerPair = actualHandler; + break; + } + } + if (contextHandlerPair == null) + return; + this._actualHandlers.Remove(contextHandlerPair); + } + + public void Invoke(object sender, T eventArgs) + { + if (!this.HasHandlers) + return; + foreach (ContextEventHandler.ContextHandlerPair actualHandler in (IEnumerable.ContextHandlerPair>) this._actualHandlers) + { + EventHandler handler = actualHandler.Handler; + SynchronizationContext context = actualHandler.ContextId.Context; + if (context == null) + handler(sender, eventArgs); + else if (this._method == ContextEventHandler.ContextSynchronizationMethod.Post) + context.Post(new SendOrPostCallback(this.SendOrPostDelegate), (object) new ContextEventHandler.ContextEventHandlerArgsWrapper(handler, sender, eventArgs)); + else if (this._method == ContextEventHandler.ContextSynchronizationMethod.Send) + context.Send(new SendOrPostCallback(this.SendOrPostDelegate), (object) new ContextEventHandler.ContextEventHandlerArgsWrapper(handler, sender, eventArgs)); + } + } + + public void Dispose() + { + this._isDisposed = true; + this._actualHandlers.Clear(); + } + + private void SendOrPostDelegate(object state) + { + if (this._isDisposed) + return; + ContextEventHandler.ContextEventHandlerArgsWrapper handlerArgsWrapper = (ContextEventHandler.ContextEventHandlerArgsWrapper) state; + handlerArgsWrapper.Handler(handlerArgsWrapper.Sender, handlerArgsWrapper.Args); + } + + internal enum ContextSynchronizationMethod + { + Send, + Post, + } + + private class ContextEventHandlerArgsWrapper + { + public ContextEventHandlerArgsWrapper(EventHandler handler, object sender, T args) + { + this.Handler = handler; + this.Sender = sender; + this.Args = args; + } + + public EventHandler Handler { get; private set; } + + public object Sender { get; private set; } + + public T Args { get; private set; } + } + + private class SynchronizationContextIdentifier + { + private const string DispatcherFieldName = "_dispatcher"; + private const string DispatcherSynchronizationContextName = "DispatcherSynchronizationContext"; + private object _dispatcherObject; + + public SynchronizationContextIdentifier(SynchronizationContext context) + { + this.Context = context; + if (object.ReferenceEquals((object) context, (object) null)) + return; + Type type = context.GetType(); + if (!("DispatcherSynchronizationContext" == type.Name)) + return; + FieldInfo field = type.GetField("_dispatcher", BindingFlags.Instance | BindingFlags.NonPublic); + if (!(field != (FieldInfo) null)) + return; + this._dispatcherObject = field.GetValue((object) context); + } + + public override int GetHashCode() + { + if (!object.ReferenceEquals(this._dispatcherObject, (object) null)) + return this._dispatcherObject.GetHashCode(); + return !object.ReferenceEquals((object) this.Context, (object) null) ? this.Context.GetHashCode() : 0; + } + + public override bool Equals(object obj) + { + ContextEventHandler.SynchronizationContextIdentifier contextIdentifier = obj as ContextEventHandler.SynchronizationContextIdentifier; + return !object.ReferenceEquals((object) contextIdentifier, (object) null) && this.Equals(contextIdentifier); + } + + public bool Equals( + ContextEventHandler.SynchronizationContextIdentifier contextId) + { + if (object.ReferenceEquals((object) contextId, (object) null)) + return false; + return this._dispatcherObject == null && contextId._dispatcherObject == null ? this.Context == contextId.Context : this._dispatcherObject == contextId._dispatcherObject; + } + + public static bool operator ==( + ContextEventHandler.SynchronizationContextIdentifier contextId1, + ContextEventHandler.SynchronizationContextIdentifier contextId2) + { + return !object.ReferenceEquals((object) contextId1, (object) null) && !object.ReferenceEquals((object) contextId2, (object) null) && contextId1.Equals(contextId2); + } + + public static bool operator !=( + ContextEventHandler.SynchronizationContextIdentifier contextId1, + ContextEventHandler.SynchronizationContextIdentifier contextId2) + { + return object.ReferenceEquals((object) contextId1, (object) null) || object.ReferenceEquals((object) contextId2, (object) null) || !contextId1.Equals(contextId2); + } + + public SynchronizationContext Context { get; private set; } + } + + private class ContextHandlerPair + { + public ContextHandlerPair( + EventHandler handler, + ContextEventHandler.SynchronizationContextIdentifier contextId) + { + this.Handler = handler; + this.ContextId = contextId; + } + + public ContextEventHandler.SynchronizationContextIdentifier ContextId { get; private set; } + + public EventHandler Handler { get; private set; } + } + } +} diff --git a/src/Microsoft.Kinect/CoordinateMapper.cs b/src/Microsoft.Kinect/CoordinateMapper.cs new file mode 100644 index 0000000..a4a195a --- /dev/null +++ b/src/Microsoft.Kinect/CoordinateMapper.cs @@ -0,0 +1,274 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.CoordinateMapper +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; + +namespace Microsoft.Kinect +{ + public sealed class CoordinateMapper : INotifyPropertyChanged + { + private readonly NuiCoordinateMapper _coordinateMapper; + + public CoordinateMapper(IEnumerable parameters) + { + this._coordinateMapper = new NuiCoordinateMapper(parameters.ToArray()); + this._coordinateMapper.RelationalParametersChanged += new EventHandler(this.CoordinateMapper_RelationalParametersChanged); + } + + private void CoordinateMapper_RelationalParametersChanged(object sender, EventArgs e) + { + if (this.PropertyChanged == null) + return; + this.PropertyChanged((object) this, new PropertyChangedEventArgs("ColorToDepthRelationalParameters")); + } + + public ReadOnlyCollection ColorToDepthRelationalParameters => new ReadOnlyCollection((IList) ((IEnumerable) this._coordinateMapper.GetColorToDepthRelationalParameters()).ToList()); + + public event PropertyChangedEventHandler PropertyChanged; + + public CoordinateMapper(KinectSensor sensor) + { + this._coordinateMapper = sensor != null ? sensor.NuiSensor.NuiGetCoordinateMapper() : throw new ArgumentNullException(nameof (sensor)); + this._coordinateMapper.RelationalParametersChanged += new EventHandler(this.CoordinateMapper_RelationalParametersChanged); + } + + private static _Vector4 ManagedNuiTransformDepthImageToSkeleton( + float fDepthX, + float fDepthY, + int depthPixelDatum) + { + KinectEtwProvider.EventWriteManagedNuiTransformDepthImageToSkeletonStart(); + float num1 = (float) depthPixelDatum / 1000f; + float num2 = (float) ((double) (fDepthX - 0.5f) * (0.003501000115647912 * (double) num1) * 320.0); + float num3 = (float) ((double) (0.5f - fDepthY) * (0.003501000115647912 * (double) num1) * 240.0); + _Vector4 skeleton; + skeleton.x = num2; + skeleton.y = num3; + skeleton.z = num1; + skeleton.w = 1f; + KinectEtwProvider.EventWriteManagedNuiTransformDepthImageToSkeletonEnd(); + return skeleton; + } + + internal static void ManagedNuiTransformSkeletonToDepthImage( + _Vector4 vPoint, + out float pfDepthX, + out float pfDepthY, + out float pfDepthValue) + { + KinectEtwProvider.EventWriteManagedNuiTransformSkeletonToDepthImageStart(); + if ((double) vPoint.z > 1.4012984643248171E-45) + { + pfDepthX = (float) (0.5 + (double) vPoint.x * 285.6300048828125 / ((double) vPoint.z * 320.0)); + pfDepthY = (float) (0.5 - (double) vPoint.y * 285.6300048828125 / ((double) vPoint.z * 240.0)); + pfDepthValue = vPoint.z * 1000f; + } + else + { + pfDepthX = 0.0f; + pfDepthY = 0.0f; + pfDepthValue = 0.0f; + } + KinectEtwProvider.EventWriteManagedNuiTransformSkeletonToDepthImageEnd(); + } + + internal static ImageType ImageTypeFromColorImageFormat(ColorImageFormat colorImageFormat) => colorImageFormat != ColorImageFormat.InfraredResolution640x480Fps30 ? ImageType.Color : ImageType.ColorInfrared; + + public void MapColorFrameToDepthFrame( + ColorImageFormat colorImageFormat, + DepthImageFormat depthImageFormat, + DepthImagePixel[] depthPixels, + DepthImagePoint[] depthPoints) + { + ImageType eColorType = CoordinateMapper.ImageTypeFromColorImageFormat(colorImageFormat); + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (colorImageFormat)); + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (depthImageFormat)); + if (depthPixels == null) + throw new ArgumentNullException(nameof (depthPixels)); + if (depthPixels.Length != DepthImageStream.LookUpPixelDataLength(depthImageFormat)) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (depthPixels)); + if (depthPoints == null) + throw new ArgumentNullException(nameof (depthPoints)); + if (depthPoints.Length != ColorImageStream.LookUpPixelDataLength(colorImageFormat)) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (depthPoints)); + this._coordinateMapper.MapColorFrameToDepthFrame((_NUI_IMAGE_TYPE) eColorType, (_NUI_IMAGE_RESOLUTION) ColorImageStream.LookUpImageResolution(colorImageFormat), (_NUI_IMAGE_RESOLUTION) DepthImageStream.LookUpImageResolution(depthImageFormat), depthPixels, depthPoints); + } + + public void MapColorFrameToSkeletonFrame( + ColorImageFormat colorImageFormat, + DepthImageFormat depthImageFormat, + DepthImagePixel[] depthPixels, + SkeletonPoint[] skeletonPoints) + { + ImageType eColorType = CoordinateMapper.ImageTypeFromColorImageFormat(colorImageFormat); + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (colorImageFormat)); + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (depthImageFormat)); + if (depthPixels == null) + throw new ArgumentNullException(nameof (depthPixels)); + if (depthPixels.Length != DepthImageStream.LookUpPixelDataLength(depthImageFormat)) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (depthPixels)); + if (skeletonPoints == null) + throw new ArgumentNullException(nameof (skeletonPoints)); + if (skeletonPoints.Length != ColorImageStream.LookUpPixelDataLength(colorImageFormat)) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (skeletonPoints)); + this._coordinateMapper.MapColorFrameToSkeletonFrame((_NUI_IMAGE_TYPE) eColorType, (_NUI_IMAGE_RESOLUTION) ColorImageStream.LookUpImageResolution(colorImageFormat), (_NUI_IMAGE_RESOLUTION) DepthImageStream.LookUpImageResolution(depthImageFormat), depthPixels, skeletonPoints); + } + + public void MapDepthFrameToColorFrame( + DepthImageFormat depthImageFormat, + DepthImagePixel[] depthPixels, + ColorImageFormat colorImageFormat, + ColorImagePoint[] colorPoints) + { + ImageType eColorType = CoordinateMapper.ImageTypeFromColorImageFormat(colorImageFormat); + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (depthImageFormat)); + if (depthPixels == null) + throw new ArgumentNullException(nameof (depthPixels)); + if (depthPixels.Length != DepthImageStream.LookUpPixelDataLength(depthImageFormat)) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (depthPixels)); + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (colorImageFormat)); + if (colorPoints == null) + throw new ArgumentNullException(nameof (colorPoints)); + if (colorPoints.Length != depthPixels.Length) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (colorPoints)); + KinectEtwProvider.EventWriteMapDepthFrameToColorFrameStart(); + this._coordinateMapper.MapDepthFrameToColorFrame((_NUI_IMAGE_RESOLUTION) DepthImageStream.LookUpImageResolution(depthImageFormat), depthPixels, (_NUI_IMAGE_TYPE) eColorType, (_NUI_IMAGE_RESOLUTION) ColorImageStream.LookUpImageResolution(colorImageFormat), colorPoints); + KinectEtwProvider.EventWriteMapDepthFrameToColorFrameEnd(); + } + + public void MapDepthFrameToSkeletonFrame( + DepthImageFormat depthImageFormat, + DepthImagePixel[] depthPixels, + SkeletonPoint[] skeletonPoints) + { + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (depthImageFormat)); + if (depthPixels == null) + throw new ArgumentNullException(nameof (depthPixels)); + if (depthPixels.Length != DepthImageStream.LookUpPixelDataLength(depthImageFormat)) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (depthPixels)); + if (skeletonPoints == null) + throw new ArgumentNullException(nameof (skeletonPoints)); + if (depthPixels.Length != skeletonPoints.Length) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (skeletonPoints)); + this._coordinateMapper.MapDepthFrameToSkeletonFrame((_NUI_IMAGE_RESOLUTION) DepthImageStream.LookUpImageResolution(depthImageFormat), depthPixels, skeletonPoints); + } + + public ColorImagePoint MapDepthPointToColorPoint( + DepthImageFormat depthImageFormat, + DepthImagePoint depthPoint, + ColorImageFormat colorImageFormat) + { + ImageType eColorType = CoordinateMapper.ImageTypeFromColorImageFormat(colorImageFormat); + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (depthImageFormat)); + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (colorImageFormat)); + KinectEtwProvider.EventWriteMapDepthToColorImagePointStart(); + _NUI_DEPTH_IMAGE_POINT depthPoint1 = new _NUI_DEPTH_IMAGE_POINT() + { + x = depthPoint.X, + y = depthPoint.Y, + depth = depthPoint.Depth + }; + _NUI_COLOR_IMAGE_POINT colorPoint; + this._coordinateMapper.MapDepthPointToColorPoint((_NUI_IMAGE_RESOLUTION) DepthImageStream.LookUpImageResolution(depthImageFormat), ref depthPoint1, (_NUI_IMAGE_TYPE) eColorType, (_NUI_IMAGE_RESOLUTION) ColorImageStream.LookUpImageResolution(colorImageFormat), out colorPoint); + KinectEtwProvider.EventWriteMapDepthToColorImagePointEnd(); + return new ColorImagePoint() + { + X = colorPoint.x, + Y = colorPoint.y + }; + } + + public SkeletonPoint MapDepthPointToSkeletonPoint( + DepthImageFormat depthImageFormat, + DepthImagePoint depthImagePoint) + { + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (depthImageFormat)); + KinectEtwProvider.EventWriteMapDepthToSkeletonPointStart(); + int width; + int height; + ImageStream.ResolutionToHeightWidth(DepthImageStream.LookUpImageResolution(depthImageFormat), out width, out height); + _Vector4 skeleton = CoordinateMapper.ManagedNuiTransformDepthImageToSkeleton((float) depthImagePoint.X / (float) width, (float) depthImagePoint.Y / (float) height, depthImagePoint.Depth); + SkeletonPoint skeletonPoint = new SkeletonPoint() + { + X = skeleton.x, + Y = skeleton.y, + Z = skeleton.z + }; + KinectEtwProvider.EventWriteMapDepthToSkeletonPointEnd(); + return skeletonPoint; + } + + public ColorImagePoint MapSkeletonPointToColorPoint( + SkeletonPoint skeletonPoint, + ColorImageFormat colorImageFormat) + { + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (colorImageFormat)); + KinectEtwProvider.EventWriteMapSkeletonPointToColorStart(); + _Vector4 vPoint; + vPoint.x = skeletonPoint.X; + vPoint.y = skeletonPoint.Y; + vPoint.z = skeletonPoint.Z; + vPoint.w = 1f; + float pfDepthX; + float pfDepthY; + float pfDepthValue; + CoordinateMapper.ManagedNuiTransformSkeletonToDepthImage(vPoint, out pfDepthX, out pfDepthY, out pfDepthValue); + ColorImagePoint colorPoint = this.MapDepthPointToColorPoint(DepthImageFormat.Resolution640x480Fps30, new DepthImagePoint() + { + X = (int) ((double) pfDepthX * 640.0), + Y = (int) ((double) pfDepthY * 480.0), + Depth = (int) pfDepthValue + }, colorImageFormat); + KinectEtwProvider.EventWriteMapSkeletonPointToColorEnd(); + return colorPoint; + } + + public DepthImagePoint MapSkeletonPointToDepthPoint( + SkeletonPoint skeletonPoint, + DepthImageFormat depthImageFormat) + { + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (depthImageFormat)); + KinectEtwProvider.EventWriteMapSkeletonPointToDepthStart(); + _Vector4 vPoint; + vPoint.x = skeletonPoint.X; + vPoint.y = skeletonPoint.Y; + vPoint.z = skeletonPoint.Z; + vPoint.w = 1f; + float pfDepthX; + float pfDepthY; + float pfDepthValue; + CoordinateMapper.ManagedNuiTransformSkeletonToDepthImage(vPoint, out pfDepthX, out pfDepthY, out pfDepthValue); + int width; + int height; + ImageStream.ResolutionToHeightWidth(DepthImageStream.LookUpImageResolution(depthImageFormat), out width, out height); + DepthImagePoint depthPoint = new DepthImagePoint() + { + X = (int) ((double) pfDepthX * (double) width + 0.5), + Y = (int) ((double) pfDepthY * (double) height + 0.5), + Depth = (int) ((double) pfDepthValue + 0.5) + }; + KinectEtwProvider.EventWriteMapSkeletonPointToDepthEnd(); + return depthPoint; + } + } +} diff --git a/src/Microsoft.Kinect/DMO_MEDIA_TYPE.cs b/src/Microsoft.Kinect/DMO_MEDIA_TYPE.cs new file mode 100644 index 0000000..4806d4b --- /dev/null +++ b/src/Microsoft.Kinect/DMO_MEDIA_TYPE.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DMO_MEDIA_TYPE +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [ComVisible(true)] + [StructLayout(LayoutKind.Sequential)] + internal sealed class DMO_MEDIA_TYPE : IDisposable + { + public static readonly Guid MEDIATYPE_Audio = new Guid("73647561-0000-0010-8000-00AA00389B71"); + public static readonly Guid MEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71"); + public static readonly Guid MEDIASUBTYPE_WAVE = new Guid("e436eb8b-524f-11ce-9f53-0020af0ba770"); + public static readonly Guid FORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a"); + public Guid majortype; + public Guid subtype; + public bool bFixedSizeSamples; + public bool bTemporalCompression; + public int lSampleSize; + public Guid formattype; + public object pUnk; + public int cbFormat; + public IntPtr pbFormat; + + public DMO_MEDIA_TYPE() => this.pbFormat = IntPtr.Zero; + + public void SetFormat(WAVEFORMATEX fmt) + { + this.pbFormat = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof (WAVEFORMATEX))); + if (this.pbFormat == IntPtr.Zero) + throw new OutOfMemoryException(); + Marshal.StructureToPtr((object) fmt, this.pbFormat, true); + } + + ~DMO_MEDIA_TYPE() => this.Dispose(false); + + public void Dispose() + { + GC.SuppressFinalize((object) this); + this.Dispose(true); + } + + private void Dispose(bool disposing) + { + if (this.pbFormat != IntPtr.Zero) + Marshal.FreeCoTaskMem(this.pbFormat); + this.pbFormat = IntPtr.Zero; + } + } +} diff --git a/src/Microsoft.Kinect/DMO_OUTPUT_DATA_BUFFER.cs b/src/Microsoft.Kinect/DMO_OUTPUT_DATA_BUFFER.cs new file mode 100644 index 0000000..19163be --- /dev/null +++ b/src/Microsoft.Kinect/DMO_OUTPUT_DATA_BUFFER.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DMO_OUTPUT_DATA_BUFFER +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [ComVisible(true)] + internal struct DMO_OUTPUT_DATA_BUFFER + { + public IntPtr Buffer; + public uint Status; + public long Timestamp; + public long Timelength; + } +} diff --git a/src/Microsoft.Kinect/DataPool`4.cs b/src/Microsoft.Kinect/DataPool`4.cs new file mode 100644 index 0000000..83a1f18 --- /dev/null +++ b/src/Microsoft.Kinect/DataPool`4.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DataPool`4 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + internal class DataPool : DataPool + { + public DataPool(int length) + : base(length) + { + } + } +} diff --git a/src/Microsoft.Kinect/DataPool`5.cs b/src/Microsoft.Kinect/DataPool`5.cs new file mode 100644 index 0000000..194aa21 --- /dev/null +++ b/src/Microsoft.Kinect/DataPool`5.cs @@ -0,0 +1,114 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DataPool`5 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + internal class DataPool + { + private readonly DataPool.EntryPrivate[] _dataPool; + private int _nextPoolEntry; + private readonly object _dataPoolLock = new object(); + + public DataPool(int length) + { + this._dataPool = length >= 0 ? new DataPool.EntryPrivate[length] : throw new ArgumentOutOfRangeException(nameof (length)); + for (int index = 0; index < this._dataPool.Length; ++index) + { + this._dataPool[index] = new DataPool.EntryPrivate(); + this._dataPool[index].IsInPool = true; + this._dataPool[index].IsValid = true; + } + } + + public DataPool.Entry CheckOutFreeEntryForUpdate() + { + lock (this._dataPoolLock) + { + int nextPoolEntry = this._nextPoolEntry; + this._nextPoolEntry = (this._nextPoolEntry + 1) % this._dataPool.Length; + DataPool.EntryPrivate entryPrivate = this._dataPool[nextPoolEntry]; + if (!entryPrivate.IsValid || entryPrivate.IsLocked) + { + entryPrivate.IsInPool = false; + entryPrivate = new DataPool.EntryPrivate(); + entryPrivate.IsInPool = true; + entryPrivate.IsValid = true; + this._dataPool[nextPoolEntry] = entryPrivate; + } + entryPrivate.IsValid = false; + return (DataPool.Entry) entryPrivate; + } + } + + public void CheckInEntryForUpdate(DataPool.Entry entry) + { + lock (this._dataPoolLock) + { + DataPool.EntryPrivate entryPrivate = (DataPool.EntryPrivate) entry; + if (!entryPrivate.IsInPool || entryPrivate.IsLocked || entryPrivate.IsValid) + return; + entryPrivate.IsValid = true; + } + } + + public bool TryLockEntry(K key, out DataPool.Entry entry) + { + entry = (DataPool.Entry) null; + if ((object) key == null) + throw new ArgumentNullException(nameof (key)); + lock (this._dataPoolLock) + { + for (int index = 0; index < this._dataPool.Length; ++index) + { + if (this._dataPool[index].IsValid && this._dataPool[index].Key.Equals((object) key)) + { + DataPool.EntryPrivate entryPrivate = this._dataPool[index]; + entryPrivate.AddRef(); + entry = (DataPool.Entry) entryPrivate; + break; + } + } + } + return entry != null; + } + + public void UnlockEntry(DataPool.Entry entry) + { + lock (this._dataPoolLock) + ((DataPool.EntryPrivate) entry).Release(); + } + + public abstract class Entry + { + public K Key { get; set; } + + public V1 Value1 { get; set; } + + public V2 Value2 { get; set; } + + public V3 Value3 { get; set; } + + public V4 Value4 { get; set; } + } + + private class EntryPrivate : DataPool.Entry + { + private int _refCount; + + public void AddRef() => ++this._refCount; + + public void Release() => --this._refCount; + + public bool IsLocked => this._refCount > 0; + + public bool IsInPool { get; set; } + + public bool IsValid { get; set; } + } + } +} diff --git a/src/Microsoft.Kinect/DepthImageFormat.cs b/src/Microsoft.Kinect/DepthImageFormat.cs new file mode 100644 index 0000000..35b1e56 --- /dev/null +++ b/src/Microsoft.Kinect/DepthImageFormat.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DepthImageFormat +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum DepthImageFormat + { + Undefined, + Resolution640x480Fps30, + Resolution320x240Fps30, + Resolution80x60Fps30, + } +} diff --git a/src/Microsoft.Kinect/DepthImageFrame.cs b/src/Microsoft.Kinect/DepthImageFrame.cs new file mode 100644 index 0000000..e8713d4 --- /dev/null +++ b/src/Microsoft.Kinect/DepthImageFrame.cs @@ -0,0 +1,151 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DepthImageFrame +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + public sealed class DepthImageFrame : ImageFrame + { + public const int PlayerIndexBitmask = 7; + public const int PlayerIndexBitmaskWidth = 3; + private readonly DepthImageStream _depthImageStream; + private DataPool.Entry _frameData; + private readonly object _dataAccessLock = new object(); + + private DepthImageFrame( + DepthImageStream depthImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags, + DataPool.Entry pixelData) + : base(pixelData.Value1, pixelData.Value2, frameNumber, timestamp, frameFlags) + { + this._depthImageStream = depthImageStream; + this._frameData = pixelData; + this.Format = DepthImageStream.LookUpDepthImageFormat(pixelData.Value1, pixelData.Value2); + } + + internal static DepthImageFrame Create( + DepthImageStream depthImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags) + { + DepthImageFrame depthImageFrame = (DepthImageFrame) null; + DataPool.Entry pixelData = depthImageStream.LockPixelData(frameNumber); + if (pixelData != null) + depthImageFrame = new DepthImageFrame(depthImageStream, frameNumber, timestamp, frameFlags, pixelData); + return depthImageFrame; + } + + public DepthImageFormat Format { get; private set; } + + public DepthRange Range => !this.FrameFlags.HasFlag((Enum) ImageFrameFlags.NUI_IMAGE_FRAME_FLAG_NEAR_MODE_ENABLED) ? DepthRange.Default : DepthRange.Near; + + public int MaxDepth => this.Range != DepthRange.Near ? 4000 : 3000; + + public int MinDepth => this.Range != DepthRange.Near ? 800 : 400; + + public override int PixelDataLength => DepthImageStream.LookUpPixelDataLength(this.Format); + + public IDepthFilter DepthFilter => this._depthImageStream.Sensor.NuiSensor.GetDepthFilterForTimestamp(this.Timestamp); + + public DepthImagePixel[] GetRawPixelData() => this._frameData.Value4; + + private void CopyPixelDataTo(T[] pixelData, Action copyFunction) + { + if (pixelData == null) + throw new ArgumentNullException(nameof (pixelData)); + if (pixelData.Length != this.PixelDataLength) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (pixelData)); + this.CopyPixelDataTo(pixelData, pixelData.Length, copyFunction); + } + + private void CopyPixelDataTo(T pixelData, int pixelDataLength, Action copyFunction) + { + if (pixelDataLength != this.PixelDataLength) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof (pixelDataLength)); + lock (this._dataAccessLock) + { + if (this._frameData == null) + throw new ObjectDisposedException(nameof (DepthImageFrame)); + copyFunction(pixelData, pixelDataLength); + } + } + + public unsafe void CopyPixelDataTo(short[] pixelData) => this.CopyPixelDataTo(pixelData, (Action) ((data, length) => + { + fixed (short* source = this._frameData.Value3) + Marshal.Copy((IntPtr) (void*) source, data, 0, length); + })); + + public unsafe void CopyDepthImagePixelDataTo(DepthImagePixel[] pixelData) => this.CopyPixelDataTo(pixelData, (Action) ((data, length) => + { + fixed (DepthImagePixel* source = this._frameData.Value4) + fixed (DepthImagePixel* destination = data) + NativeMethods.CopyMemory((IntPtr) (void*) destination, (IntPtr) (void*) source, length * sizeof (DepthImagePixel)); + })); + + public void CopyPixelDataTo(IntPtr pixelData, int pixelDataLength) + { + if (pixelData == IntPtr.Zero) + throw new ArgumentNullException(nameof (pixelData)); + this.CopyPixelDataTo(pixelData, pixelDataLength, (Action) ((data, length) => Marshal.Copy(this._frameData.Value3, 0, data, length))); + } + + public unsafe void CopyDepthImagePixelDataTo(IntPtr pixelData, int pixelDataLength) + { + if (pixelData == IntPtr.Zero) + throw new ArgumentNullException(nameof (pixelData)); + this.CopyPixelDataTo(pixelData, pixelDataLength, (Action) ((data, length) => + { + fixed (DepthImagePixel* source = this._frameData.Value4) + NativeMethods.CopyMemory(data, (IntPtr) (void*) source, length * sizeof (DepthImagePixel)); + })); + } + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapDepthPointToColorPoint", false)] + public ColorImagePoint MapToColorImagePoint( + int depthX, + int depthY, + ColorImageFormat colorImageFormat) + { + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (colorImageFormat)); + short depthPixelValue = 0; + if (depthX >= 0 && depthX < this.Width && depthY >= 0 && depthY < this.Height) + depthPixelValue = this._frameData.Value3[depthY * this.Width + depthX]; + return this._depthImageStream.Sensor.MapDepthToColorImagePoint(this.Format, depthX, depthY, depthPixelValue, colorImageFormat); + } + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapSkeletonPointToDepthPoint", false)] + public DepthImagePoint MapFromSkeletonPoint(SkeletonPoint skeletonPoint) => this._depthImageStream.Sensor.MapSkeletonPointToDepth(skeletonPoint, this.Format); + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapDepthPointToSkeletonPoint", false)] + public SkeletonPoint MapToSkeletonPoint(int depthX, int depthY) + { + short depthPixelValue = 0; + if (depthX >= 0 && depthX < this.Width && depthY >= 0 && depthY < this.Height) + depthPixelValue = this._frameData.Value3[depthY * this.Width + depthX]; + return this._depthImageStream.Sensor.MapDepthToSkeletonPoint(this.Format, depthX, depthY, depthPixelValue); + } + + protected override void Dispose(bool disposing) + { + if (!disposing) + return; + lock (this._dataAccessLock) + { + this._depthImageStream.UnlockPixelData(this._frameData); + this._frameData = (DataPool.Entry) null; + } + } + + internal override ImageStream SourceStream => (ImageStream) this._depthImageStream; + } +} diff --git a/src/Microsoft.Kinect/DepthImageFrameReadyEventArgs.cs b/src/Microsoft.Kinect/DepthImageFrameReadyEventArgs.cs new file mode 100644 index 0000000..32355ba --- /dev/null +++ b/src/Microsoft.Kinect/DepthImageFrameReadyEventArgs.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DepthImageFrameReadyEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + public sealed class DepthImageFrameReadyEventArgs : EventArgs + { + private readonly DepthImageStream _depthImageStream; + private readonly int _frameNumber; + private readonly long _timestamp; + private readonly ImageFrameFlags _frameFlags; + private bool _isInvalid; + + private DepthImageFrameReadyEventArgs( + DepthImageStream depthImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags, + bool isInvalid) + { + this._depthImageStream = depthImageStream; + this._frameNumber = frameNumber; + this._timestamp = timestamp; + this._frameFlags = frameFlags; + this._isInvalid = isInvalid; + } + + internal static DepthImageFrameReadyEventArgs Create( + DepthImageStream depthImageStream, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags) + { + return new DepthImageFrameReadyEventArgs(depthImageStream, frameNumber, timestamp, frameFlags, false); + } + + internal static DepthImageFrameReadyEventArgs CreateInvalid() => new DepthImageFrameReadyEventArgs((DepthImageStream) null, 0, 0L, ImageFrameFlags.NUI_IMAGE_FRAME_FLAG_NONE, true); + + public DepthImageFrame OpenDepthImageFrame() + { + if (this._isInvalid) + return (DepthImageFrame) null; + KinectEtwProvider.EventWriteManagedOpenFrameFromEventInfo(1); + DepthImageFrame depthImageFrame = DepthImageFrame.Create(this._depthImageStream, this._frameNumber, this._timestamp, this._frameFlags); + if (depthImageFrame == null) + this._isInvalid = true; + return depthImageFrame; + } + } +} diff --git a/src/Microsoft.Kinect/DepthImagePixel.cs b/src/Microsoft.Kinect/DepthImagePixel.cs new file mode 100644 index 0000000..dbaf6d8 --- /dev/null +++ b/src/Microsoft.Kinect/DepthImagePixel.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DepthImagePixel +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public struct DepthImagePixel + { + private const int _UnknownDepth = 0; + + public short PlayerIndex { get; set; } + + public short Depth { get; set; } + + public override int GetHashCode() => this.Depth.GetHashCode() + this.PlayerIndex.GetHashCode(); + + public override bool Equals(object obj) => obj is DepthImagePixel pixel && this.Equals(pixel); + + public bool Equals(DepthImagePixel pixel) => (int) this.Depth == (int) pixel.Depth && (int) this.PlayerIndex == (int) pixel.PlayerIndex; + + public static bool operator ==(DepthImagePixel pixel1, DepthImagePixel pixel2) => pixel1.Equals(pixel2); + + public static bool operator !=(DepthImagePixel pixel1, DepthImagePixel pixel2) => !pixel1.Equals(pixel2); + + public bool IsKnownDepth => this.Depth != (short) 0; + } +} diff --git a/src/Microsoft.Kinect/DepthImagePoint.cs b/src/Microsoft.Kinect/DepthImagePoint.cs new file mode 100644 index 0000000..8f36fbb --- /dev/null +++ b/src/Microsoft.Kinect/DepthImagePoint.cs @@ -0,0 +1,51 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DepthImagePoint +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Diagnostics; + +namespace Microsoft.Kinect +{ + [DebuggerDisplay("X:{X} Y:{Y} Depth:{Depth} PlayerIndex:{PlayerIndex}")] + public struct DepthImagePoint + { + private int _x; + private int _y; + private int _depth; + private int _playerIndex; + + public int X + { + get => this._x; + set => this._x = value; + } + + public int Y + { + get => this._y; + set => this._y = value; + } + + public int Depth + { + get => this._depth; + set => this._depth = value; + } + + [Obsolete("The player index property is reserved. Do not use.")] + public int PlayerIndex => 0; + + public override int GetHashCode() => this.X.GetHashCode() + this.Y.GetHashCode() + this.Depth.GetHashCode(); + + public override bool Equals(object obj) => obj is DepthImagePoint imagePoint && this.Equals(imagePoint); + + public bool Equals(DepthImagePoint imagePoint) => this.X == imagePoint.X && this.Y == imagePoint.Y && this.Depth == imagePoint.Depth; + + public static bool operator ==(DepthImagePoint imagePoint1, DepthImagePoint imagePoint2) => imagePoint1.Equals(imagePoint2); + + public static bool operator !=(DepthImagePoint imagePoint1, DepthImagePoint imagePoint2) => !imagePoint1.Equals(imagePoint2); + } +} diff --git a/src/Microsoft.Kinect/DepthImageStream.cs b/src/Microsoft.Kinect/DepthImageStream.cs new file mode 100644 index 0000000..4e48f96 --- /dev/null +++ b/src/Microsoft.Kinect/DepthImageStream.cs @@ -0,0 +1,245 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DepthImageStream +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + public sealed class DepthImageStream : ImageStream + { + internal const int _DefaultMinDepth = 800; + internal const int _DefaultMaxDepth = 4000; + internal const int _NearMinDepth = 400; + internal const int _NearMaxDepth = 3000; + private const int _TooNearDepth = 0; + private const int _TooFarDepth = 4095; + private const int _UnknownDepth = -1; + private const int DepthBytesPerPixelConstant = 2; + private DepthRange _range; + private int _minDepth; + private int _maxDepth; + private DepthImageFormat _depthImageFormat; + private readonly DataPool _depthDataPool; + + private float ScaleValue(float value) + { + switch (this.Format) + { + case DepthImageFormat.Resolution640x480Fps30: + return 2f * value; + case DepthImageFormat.Resolution320x240Fps30: + return value; + case DepthImageFormat.Resolution80x60Fps30: + return 0.25f * value; + default: + return value; + } + } + + public float NominalFocalLengthInPixels => this.ScaleValue(285.63f); + + public float NominalInverseFocalLengthInPixels => 1f / this.NominalFocalLengthInPixels; + + public float NominalDiagonalFieldOfView => this.ScaleValue(70f); + + public float NominalHorizontalFieldOfView => this.ScaleValue(58.5f); + + public float NominalVerticalFieldOfView => this.ScaleValue(45.6f); + + internal DepthImageStream(KinectSensor mainNui) + : base(mainNui, ImageStreamFlags.NUI_IMAGE_STREAM_FLAG_SUPPRESS_NO_FRAME_DATA | ImageStreamFlags.NUI_IMAGE_STREAM_FLAG_DISTINCT_OVERFLOW_DEPTH_VALUES) + { + this.Range = DepthRange.Default; + this._depthDataPool = new DataPool(this.BufferCount); + this.Format = DepthImageFormat.Resolution640x480Fps30; + this.FrameBytesPerPixel = 2; + } + + public void Enable() => this.Enable(DepthImageFormat.Resolution640x480Fps30); + + public void Enable(DepthImageFormat format) + { + if (format == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof (format)); + if (this.Sensor.IsRunning && this.IsEnabled && this.Format == format) + return; + this.Format = format; + this.InternalEnable(); + } + + public DepthRange Range + { + get => this._range; + set + { + switch (value) + { + case DepthRange.Default: + this.ImageStreamFlags &= ~ImageStreamFlags.NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE; + this._range = value; + this._minDepth = 800; + this._maxDepth = 4000; + break; + case DepthRange.Near: + this.ImageStreamFlags |= ImageStreamFlags.NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE; + this._range = value; + this._minDepth = 400; + this._maxDepth = 3000; + break; + default: + throw new ArgumentOutOfRangeException(Resources.UnexpectedDepthRange); + } + } + } + + public DepthImageFormat Format + { + get => this._depthImageFormat; + private set + { + this._depthImageFormat = value; + this.Resolution = DepthImageStream.LookUpImageResolution(this._depthImageFormat); + this.FillHeightWidth(); + this.FramePixelDataLength = this.FrameWidth * this.FrameHeight; + } + } + + public int TooNearDepth => 0; + + public int TooFarDepth => 4095; + + public int UnknownDepth => -1; + + public int MinDepth => this._minDepth; + + public int MaxDepth => this._maxDepth; + + public DepthImageFrame OpenNextFrame(int millisecondsWait) + { + DepthImageFrame depthImageFrame = (DepthImageFrame) null; + if (!this.Sensor.IsRunning) + throw new InvalidOperationException(Resources.SensorMustBeRunning); + if (!this.IsEnabled) + throw new InvalidOperationException(Resources.DepthStreamMustBeEnabled); + if (this.Sensor.HasDepthInvocations) + throw new InvalidOperationException(Resources.CannotPollAndUseEvents); + KinectEtwProvider.EventWriteManagedOpenNextFrameInfo(1, millisecondsWait); + int frameNumber; + long timestamp; + ImageFrameFlags frameFlags; + if (this.TryGetNextFrameInternal(millisecondsWait, out frameNumber, out timestamp, out frameFlags)) + depthImageFrame = DepthImageFrame.Create(this, frameNumber, timestamp, frameFlags); + return depthImageFrame; + } + + internal override ImageType ImageType => this.Sensor.SkeletonStream.IsEnabled ? ImageType.DepthAndPlayerIndex : ImageType.Depth; + + internal override unsafe void StorePixels( + int frameNumber, + _NUI_LOCKED_RECT lockedRect, + ImageType imageType, + ImageResolution resolution, + IntPtr nativeStreamHandle, + ref _NUI_IMAGE_FRAME pNativeFrame) + { + DataPool.Entry entry = this._depthDataPool.CheckOutFreeEntryForUpdate(); + entry.Key = frameNumber; + entry.Value1 = imageType; + entry.Value2 = resolution; + int width; + int height; + ImageStream.ResolutionToHeightWidth(resolution, out width, out height); + int length = width * height; + if (entry.Value3 == null || entry.Value3.Length != length) + entry.Value3 = new short[length]; + if (entry.Value4 == null || entry.Value4.Length != length) + entry.Value4 = new DepthImagePixel[length]; + if (length * 2 == lockedRect.size) + Marshal.Copy(lockedRect.pBits, entry.Value3, 0, entry.Value3.Length); + bool nearMode; + INuiFrameTexture ppTexture; + this.Sensor.NuiSensor.NuiImageFrameGetDepthImagePixelFrameTexture(nativeStreamHandle, ref pNativeFrame, out nearMode, out ppTexture); + pNativeFrame.dwFrameFlags |= nearMode ? 131072U : 0U; + if (ppTexture != null) + { + _NUI_LOCKED_RECT pLockedRect = new _NUI_LOCKED_RECT(); + tagRECT pRect = new tagRECT(); + KinectExceptionHelper.CheckHr(ppTexture.LockRect(0U, ref pLockedRect, ref pRect, 0U)); + fixed (DepthImagePixel* destination = entry.Value4) + NativeMethods.CopyMemory((IntPtr) (void*) destination, pLockedRect.pBits, length * sizeof (DepthImagePixel)); + } + this._depthDataPool.CheckInEntryForUpdate(entry); + } + + internal DataPool.Entry LockPixelData( + int frameNumber) + { + DataPool.Entry entry; + this._depthDataPool.TryLockEntry(frameNumber, out entry); + return entry; + } + + internal void UnlockPixelData( + DataPool.Entry entry) + { + this._depthDataPool.UnlockEntry(entry); + } + + internal static ImageResolution LookUpImageResolution(DepthImageFormat format) + { + switch (format) + { + case DepthImageFormat.Resolution640x480Fps30: + return ImageResolution.Resolution640x480; + case DepthImageFormat.Resolution320x240Fps30: + return ImageResolution.Resolution320x240; + case DepthImageFormat.Resolution80x60Fps30: + return ImageResolution.Resolution80x60; + default: + return ImageResolution.Invalid; + } + } + + internal static DepthImageFormat LookUpDepthImageFormat( + ImageType imageType, + ImageResolution imageResolution) + { + switch (imageType) + { + case ImageType.DepthAndPlayerIndex: + case ImageType.Depth: + switch (imageResolution) + { + case ImageResolution.Resolution80x60: + return DepthImageFormat.Resolution80x60Fps30; + case ImageResolution.Resolution320x240: + return DepthImageFormat.Resolution320x240Fps30; + case ImageResolution.Resolution640x480: + return DepthImageFormat.Resolution640x480Fps30; + } + break; + } + throw new InvalidOperationException(); + } + + internal static int LookUpPixelDataLength(DepthImageFormat format) + { + switch (format) + { + case DepthImageFormat.Resolution640x480Fps30: + return 307200; + case DepthImageFormat.Resolution320x240Fps30: + return 76800; + case DepthImageFormat.Resolution80x60Fps30: + return 4800; + default: + return 0; + } + } + } +} diff --git a/src/Microsoft.Kinect/DepthRange.cs b/src/Microsoft.Kinect/DepthRange.cs new file mode 100644 index 0000000..98264c5 --- /dev/null +++ b/src/Microsoft.Kinect/DepthRange.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DepthRange +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum DepthRange + { + Default, + Near, + } +} diff --git a/src/Microsoft.Kinect/DmoAudioWrapper.cs b/src/Microsoft.Kinect/DmoAudioWrapper.cs new file mode 100644 index 0000000..82ee995 --- /dev/null +++ b/src/Microsoft.Kinect/DmoAudioWrapper.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.DmoAudioWrapper +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Globalization; +using System.Threading; + +namespace Microsoft.Kinect +{ + internal class DmoAudioWrapper : INativeAudioWrapper + { + private readonly KinectSensor _sensor; + + public DmoAudioWrapper(KinectSensor sensor) => this._sensor = sensor; + + public object CreateDmoInstance() => this._sensor == null || this._sensor.NuiSensor == null ? (object) null : (object) this._sensor.NuiSensor.NuiGetAudioSource(); + + public void DestroyDmoInstance(object dmo) + { + } + + public void GetMicrophoneArrayDevices(MicrophoneArrayDevice[] deviceBuffer, ref int count) => NativeMethods.NuiGetMicrophoneArrayDevices(deviceBuffer, deviceBuffer != null ? deviceBuffer.Length : 0, ref count); + + public void GetSpeakerDevices(SpeakerDevice[] deviceBuffer, ref int count) => NativeMethods.NuiGetSpeakerDevices(deviceBuffer, deviceBuffer != null ? deviceBuffer.Length : 0, ref count); + + public bool MatchAudioDeviceToSensor(MicrophoneArrayDevice device) + { + if (this._sensor == null || this._sensor.NuiSensor == null) + return false; + string str = this._sensor.NuiSensor.NuiAudioArrayId(); + string deviceId = device.DeviceID; + if (str == null || deviceId == null) + return false; + string[] strArray1 = str.ToUpper(CultureInfo.InvariantCulture).Split('\\'); + string[] strArray2 = deviceId.ToUpper(CultureInfo.InvariantCulture).Split('#'); + return strArray1.Length > 2 && strArray2.Length > 2 && strArray1[1] == strArray2[1] && strArray1[2] == strArray2[2]; + } + + public ManualResetEvent CreateStreamStopEvent() => new ManualResetEvent(false); + } +} diff --git a/src/Microsoft.Kinect/EchoCancellationMode.cs b/src/Microsoft.Kinect/EchoCancellationMode.cs new file mode 100644 index 0000000..07663be --- /dev/null +++ b/src/Microsoft.Kinect/EchoCancellationMode.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.EchoCancellationMode +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum EchoCancellationMode + { + None, + CancellationOnly, + CancellationAndSuppression, + } +} diff --git a/src/Microsoft.Kinect/EventDescriptor.cs b/src/Microsoft.Kinect/EventDescriptor.cs new file mode 100644 index 0000000..96e6a3e --- /dev/null +++ b/src/Microsoft.Kinect/EventDescriptor.cs @@ -0,0 +1,30 @@ +using System.Diagnostics.Tracing; + +namespace Microsoft.Kinect +{ + internal struct EventDescriptor + { + public readonly int id; + public readonly byte version; + public readonly byte channel; + public readonly byte level; + public readonly byte opcode; + public readonly int task; + public readonly long keywords; + + public EventDescriptor(int id, byte version, byte channel, byte level, byte opcode, int task, long keywords) + { + this.id = id; + this.version = version; + this.channel = channel; + this.level = level; + this.opcode = opcode; + this.task = task; + this.keywords = keywords; + } + + public EventLevel Level => (EventLevel)level; + + public EventKeywords Keywords => (EventKeywords)keywords; + } +} \ No newline at end of file diff --git a/src/Microsoft.Kinect/EventProviderVersionTwo.cs b/src/Microsoft.Kinect/EventProviderVersionTwo.cs new file mode 100644 index 0000000..1d20c31 --- /dev/null +++ b/src/Microsoft.Kinect/EventProviderVersionTwo.cs @@ -0,0 +1,536 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.EventProviderVersionTwo +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +// Adapted to .NET Core + +using System; +using System.Diagnostics.Eventing; +using System.Diagnostics.Tracing; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [EventSource(Guid = "53eb7889-836a-4f06-838e-0be45cca7f78")] + internal unsafe class EventProviderVersionTwo : EventSource + { + internal bool TemplateEventDescriptor(ref EventDescriptor eventDescriptor) + { + if (!this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + return true; + this.WriteEventCore(eventDescriptor.id, 0, null); + return true; + } + + internal unsafe bool TemplateFrameData( + ref EventDescriptor eventDescriptor, + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 4]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&streamId); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&width); + eventDataPtr[1].Size = 8; + eventDataPtr[2].DataPointer = new IntPtr(&height); + eventDataPtr[2].Size = 8; + eventDataPtr[3].DataPointer = new IntPtr(&frameNumber); + eventDataPtr[3].Size = 8; + this.WriteEventCore(eventDescriptor.id, 4, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateProcessFrameData( + ref EventDescriptor eventDescriptor, + IntPtr frameOverlapId, + uint streamId) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&frameOverlapId); + eventDataPtr->Size = sizeof(IntPtr); + eventDataPtr[1].DataPointer = new IntPtr(&streamId); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateFrameLifecycleData( + ref EventDescriptor eventDescriptor, + uint streamType, + int bufferIndex, + int frameNumber) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 3]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&streamType); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&bufferIndex); + eventDataPtr[1].Size = 4; + eventDataPtr[2].DataPointer = new IntPtr(&frameNumber); + eventDataPtr[2].Size = 4; + this.WriteEventCore(eventDescriptor.id, 3, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateAllFramesReadyData( + ref EventDescriptor eventDescriptor, + long colorFrameTimestamp, + long depthFrameTimestamp, + long skeletonFrameTimestamp) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 3]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&colorFrameTimestamp); + eventDataPtr->Size = 8; + eventDataPtr[1].DataPointer = new IntPtr(&depthFrameTimestamp); + eventDataPtr[1].Size = 8; + eventDataPtr[2].DataPointer = new IntPtr(&skeletonFrameTimestamp); + eventDataPtr[2].Size = 8; + this.WriteEventCore(eventDescriptor.id, 3, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateFrameReadyData(ref EventDescriptor eventDescriptor, long timestamp) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(×tamp); + eventDataPtr->Size = 8; + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateStreamTypeOnly( + ref EventDescriptor eventDescriptor, + uint streamType) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&streamType); + eventDataPtr->Size = 4; + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateFrameStateData( + ref EventDescriptor eventDescriptor, + uint streamType, + int frameNumber, + uint state) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 3]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&streamType); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&frameNumber); + eventDataPtr[1].Size = 4; + eventDataPtr[2].DataPointer = new IntPtr(&state); + eventDataPtr[2].Size = 4; + this.WriteEventCore(eventDescriptor.id, 3, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateFrameDroppedData( + ref EventDescriptor eventDescriptor, + uint streamType, + int frameNumber) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&streamType); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&frameNumber); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateNuiImageStreamOpenData( + ref EventDescriptor eventDescriptor, + IntPtr hStream, + uint imageType, + uint imageResolution, + uint imageFrameFlags, + IntPtr hNextFrameEvent) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 5]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&hStream); + eventDataPtr->Size = sizeof(IntPtr); + eventDataPtr[1].DataPointer = new IntPtr(&imageType); + eventDataPtr[1].Size = 4; + eventDataPtr[2].DataPointer = new IntPtr(&imageResolution); + eventDataPtr[2].Size = 4; + eventDataPtr[3].DataPointer = new IntPtr(&imageFrameFlags); + eventDataPtr[3].Size = 4; + eventDataPtr[4].DataPointer = new IntPtr(&hNextFrameEvent); + eventDataPtr[4].Size = sizeof(IntPtr); + this.WriteEventCore(eventDescriptor.id, 5, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateNuiInitializeData( + ref EventDescriptor eventDescriptor, + string deviceId, + string processName, + uint flags) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 3]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + fixed (char* chPtr1 = deviceId) + fixed (char* chPtr2 = processName) + { + eventDataPtr->DataPointer = new IntPtr(chPtr1); + eventDataPtr->Size = ((deviceId.Length + 1) * 2); + eventDataPtr[1].DataPointer = new IntPtr(chPtr2); + eventDataPtr[1].Size = ((processName.Length + 1) * 2); + eventDataPtr[2].DataPointer = new IntPtr(&flags); + eventDataPtr[2].Size = 4; + this.WriteEventCore(eventDescriptor.id, 3, eventDataPtr); + } + } + return flag; + } + + internal unsafe bool TemplateNuiSkeletonTrackingData( + ref EventDescriptor eventDescriptor, + IntPtr hNextFrameEvent, + uint dwFlags) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&hNextFrameEvent); + eventDataPtr->Size = sizeof(IntPtr); + eventDataPtr[1].DataPointer = new IntPtr(&dwFlags); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateNuiTransformSmoothParams( + ref EventDescriptor eventDescriptor, + float smoothing, + float correction, + float prediction, + float jitterRadius, + float maxDeviationRadius) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 5]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&smoothing); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&correction); + eventDataPtr[1].Size = 4; + eventDataPtr[2].DataPointer = new IntPtr(&prediction); + eventDataPtr[2].Size = 4; + eventDataPtr[3].DataPointer = new IntPtr(&jitterRadius); + eventDataPtr[3].Size = 4; + eventDataPtr[4].DataPointer = new IntPtr(&maxDeviationRadius); + eventDataPtr[4].Size = 4; + this.WriteEventCore(eventDescriptor.id, 5, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateNuiSkeletonSetTrackedSkeletonsData( + ref EventDescriptor eventDescriptor, + uint skeleton1, + uint skeleton2) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&skeleton1); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&skeleton2); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateNuiSetFrameEndEventData( + ref EventDescriptor eventDescriptor, + IntPtr hEvent, + uint dwFrameEventFlag) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&hEvent); + eventDataPtr->Size = sizeof(IntPtr); + eventDataPtr[1].DataPointer = new IntPtr(&dwFrameEventFlag); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateNuiImageStreamGetNextFrameData( + ref EventDescriptor eventDescriptor, + IntPtr hStream, + uint dwMillisecondsToWait) + { + bool nextFrameData = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&hStream); + eventDataPtr->Size = sizeof(IntPtr); + eventDataPtr[1].DataPointer = new IntPtr(&dwMillisecondsToWait); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return nextFrameData; + } + + internal unsafe bool TemplateNuiSkeletonGetNextFrameData( + ref EventDescriptor eventDescriptor, + uint dwMillisecondsToWait) + { + bool nextFrameData = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&dwMillisecondsToWait); + eventDataPtr->Size = 4; + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + return nextFrameData; + } + + internal unsafe bool TemplateKinectIdStringData( + ref EventDescriptor eventDescriptor, + string kinectId) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + fixed (char* chPtr = kinectId) + { + eventDataPtr->DataPointer = new IntPtr(chPtr); + eventDataPtr->Size = ((kinectId.Length + 1) * 2); + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + } + return flag; + } + + internal unsafe bool TemplateNuiCreateSensorByIndexData( + ref EventDescriptor eventDescriptor, + int index) + { + bool sensorByIndexData = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&index); + eventDataPtr->Size = 4; + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + return sensorByIndexData; + } + + internal unsafe bool TemplateNuiCreateSensorByIdData( + ref EventDescriptor eventDescriptor, + string strInstanceId) + { + bool sensorByIdData = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + fixed (char* chPtr = strInstanceId) + { + eventDataPtr->DataPointer = new IntPtr(chPtr); + eventDataPtr->Size = ((strInstanceId.Length + 1) * 2); + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + } + return sensorByIdData; + } + + internal unsafe bool TemplateNuiImageStreamSetImageFrameFlagsData( + ref EventDescriptor eventDescriptor, + IntPtr hStream, + uint dwImageFrameFlags) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&hStream); + eventDataPtr->Size = sizeof(IntPtr); + eventDataPtr[1].DataPointer = new IntPtr(&dwImageFrameFlags); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateAudioAngleData(ref EventDescriptor eventDescriptor, double dAngle) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&dAngle); + eventDataPtr->Size = 8; + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateAudioPropertyData( + ref EventDescriptor eventDescriptor, + uint pid, + uint value) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&pid); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&value); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateManagedFramesReadyRegistrationData( + ref EventDescriptor eventDescriptor, + int type) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&type); + eventDataPtr->Size = 4; + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateManagedImageStreamData( + ref EventDescriptor eventDescriptor, + int type) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&type); + eventDataPtr->Size = 4; + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateManagedOpenNextFrameData( + ref EventDescriptor eventDescriptor, + int streamType, + int millisecondsWait) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData) * 2]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + eventDataPtr->DataPointer = new IntPtr(&streamType); + eventDataPtr->Size = 4; + eventDataPtr[1].DataPointer = new IntPtr(&millisecondsWait); + eventDataPtr[1].Size = 4; + this.WriteEventCore(eventDescriptor.id, 2, eventDataPtr); + } + return flag; + } + + internal unsafe bool TemplateKinectSensorStartData( + ref EventDescriptor eventDescriptor, + string deviceID) + { + bool flag = true; + if (this.IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords)) + { + byte* data = stackalloc byte[sizeof(EventProviderVersionTwo.EventData)]; + EventProviderVersionTwo.EventData* eventDataPtr = (EventProviderVersionTwo.EventData*)data; + fixed (char* chPtr = deviceID) + { + eventDataPtr->DataPointer = new IntPtr(chPtr); + eventDataPtr->Size = ((deviceID.Length + 1) * 2); + this.WriteEventCore(eventDescriptor.id, 1, eventDataPtr); + } + } + return flag; + } + } +} diff --git a/src/Microsoft.Kinect/FrameEdges.cs b/src/Microsoft.Kinect/FrameEdges.cs new file mode 100644 index 0000000..a86afca --- /dev/null +++ b/src/Microsoft.Kinect/FrameEdges.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.FrameEdges +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + [Flags] + public enum FrameEdges + { + None = 0, + Right = 1, + Left = 2, + Top = 4, + Bottom = 8, + } +} diff --git a/src/Microsoft.Kinect/IDepthFilter.cs b/src/Microsoft.Kinect/IDepthFilter.cs new file mode 100644 index 0000000..8b38ec7 --- /dev/null +++ b/src/Microsoft.Kinect/IDepthFilter.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.IDepthFilter +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public interface IDepthFilter + { + object NativeObject { get; set; } + + bool ProcessFrame(long timestamp, int width, int height, DepthImagePixel[] pixelData); + } +} diff --git a/src/Microsoft.Kinect/IMediaBuffer.cs b/src/Microsoft.Kinect/IMediaBuffer.cs new file mode 100644 index 0000000..27615e0 --- /dev/null +++ b/src/Microsoft.Kinect/IMediaBuffer.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.IMediaBuffer +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [ComVisible(true)] + [Guid("59eff8b9-938c-4a26-82f2-95cb84cdc837")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface IMediaBuffer + { + void SetLength(uint ulLength); + + void GetMaxLength(out uint pcbMaxLength); + + void GetBufferAndLength([Out] IntPtr pBuffer, out uint cbLength); + } +} diff --git a/src/Microsoft.Kinect/IMediaObject.cs b/src/Microsoft.Kinect/IMediaObject.cs new file mode 100644 index 0000000..3bb8764 --- /dev/null +++ b/src/Microsoft.Kinect/IMediaObject.cs @@ -0,0 +1,72 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.IMediaObject +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [ComVisible(true)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("d8ad0f58-5494-4102-97c5-ec798e59bcf4")] + [ComImport] + internal interface IMediaObject + { + void GetStreamCount(out int pcInputStreams, out int pcOutputStreams); + + void GetInputStreamInfo(int dwInputStreamIndex, out int pdwFlags); + + void GetOutputStreamInfo(int dwOutputStreamIndex, out int pdwFlags); + + void GetInputType(int dwInputStreamIndex, int dwTypeIndex, out DMO_MEDIA_TYPE pmt); + + void GetOutputType(int dwOutputStreamIndex, int dwTypeIndex, out DMO_MEDIA_TYPE pmt); + + void SetInputType(int dwInputStreamIndex, DMO_MEDIA_TYPE pmt, int dwFlags); + + void SetOutputType(int dwOutputStreamIndex, DMO_MEDIA_TYPE pmt, int dwFlags); + + void GetInputCurrentType(int dwInputStreamIndex, out DMO_MEDIA_TYPE pmt); + + void GetOutputCurrentType(int dwOutputStreamIndex, out DMO_MEDIA_TYPE pmt); + + void GetInputSizeInfo( + int dwInputStreamIndex, + out int pcbSize, + out int pcbMaxLookahead, + out int pcbAlignment); + + void GetOutputSizeInfo(int dwOutputStreamIndex, out int pcbSize, out int pcbAlignment); + + void GetInputMaxLatency(int dwInputStreamIndex, out long prtMaxLatency); + + void SetInputMaxLatency(int dwInputStreamIndex, long rtMaxLatency); + + void Flush(); + + void Discontinuity(int dwInputStreamIndex); + + void AllocateStreamingResources(); + + void FreeStreamingResources(); + + void GetInputStatus(int dwInputStreamIndex, out int dwFlags); + + void ProcessInput( + int dwInputStreamIndex, + IMediaBuffer pBuffer, + int dwFlags, + long rtTimestamp, + long rtTimelength); + + void ProcessOutput( + int dwFlags, + int cOutputBufferCount, + [MarshalAs(UnmanagedType.LPArray)] DMO_OUTPUT_DATA_BUFFER[] pOutputBuffers, + out int pdwStatus); + + void Lock(long bLock); + } +} diff --git a/src/Microsoft.Kinect/INativeAudioWrapper.cs b/src/Microsoft.Kinect/INativeAudioWrapper.cs new file mode 100644 index 0000000..b823524 --- /dev/null +++ b/src/Microsoft.Kinect/INativeAudioWrapper.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.INativeAudioWrapper +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Threading; + +namespace Microsoft.Kinect +{ + internal interface INativeAudioWrapper + { + object CreateDmoInstance(); + + void DestroyDmoInstance(object dmo); + + void GetMicrophoneArrayDevices(MicrophoneArrayDevice[] deviceBuffer, ref int count); + + void GetSpeakerDevices(SpeakerDevice[] deviceBuffer, ref int count); + + bool MatchAudioDeviceToSensor(MicrophoneArrayDevice device); + + ManualResetEvent CreateStreamStopEvent(); + } +} diff --git a/src/Microsoft.Kinect/INuiAudioBeam.cs b/src/Microsoft.Kinect/INuiAudioBeam.cs new file mode 100644 index 0000000..91ef174 --- /dev/null +++ b/src/Microsoft.Kinect/INuiAudioBeam.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.INuiAudioBeam +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [Guid("8C3CEBFA-A35D-497E-BC9A-E9752A8155E0")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComVisible(true)] + [ComImport] + internal interface INuiAudioBeam + { + void GetBeam(out double angle); + + void SetBeam(double angle); + + void GetPosition(out double angle, out double confidence); + } +} diff --git a/src/Microsoft.Kinect/IPropertyStore.cs b/src/Microsoft.Kinect/IPropertyStore.cs new file mode 100644 index 0000000..523264d --- /dev/null +++ b/src/Microsoft.Kinect/IPropertyStore.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.IPropertyStore +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface IPropertyStore + { + void GetCount(out uint cProps); + + void GetAt([In] uint iProp, out PROPERTYKEY pkey); + + void GetValue([In] ref PROPERTYKEY key, out object pv); + + void SetValue([In] ref PROPERTYKEY key, [In] ref object pv); + + void Commit(); + } +} diff --git a/src/Microsoft.Kinect/Identifiers.cs b/src/Microsoft.Kinect/Identifiers.cs new file mode 100644 index 0000000..c48e6dd --- /dev/null +++ b/src/Microsoft.Kinect/Identifiers.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Identifiers +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + internal class Identifiers + { + public const string IID_IMediaBuffer = "59eff8b9-938c-4a26-82f2-95cb84cdc837"; + public const string IID_IMediaObject = "d8ad0f58-5494-4102-97c5-ec798e59bcf4"; + } +} diff --git a/src/Microsoft.Kinect/ImageFrame.cs b/src/Microsoft.Kinect/ImageFrame.cs new file mode 100644 index 0000000..91bb66b --- /dev/null +++ b/src/Microsoft.Kinect/ImageFrame.cs @@ -0,0 +1,69 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ImageFrame +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Diagnostics; +using System.Globalization; +using System.Threading; + +namespace Microsoft.Kinect +{ + public abstract class ImageFrame : IDisposable + { + private int _isDisposed; + + internal ImageFrame( + ImageType imageType, + ImageResolution imageResolution, + int frameNumber, + long timestamp, + ImageFrameFlags frameFlags) + { + int width; + int height; + ImageStream.ResolutionToHeightWidth(imageResolution, out width, out height); + int bytesPerPixel = ImageStream.ImageTypeToBytesPerPixel(imageType); + this.Width = width; + this.Height = height; + this.BytesPerPixel = bytesPerPixel; + this.FrameNumber = frameNumber; + this.Timestamp = timestamp; + this.FrameFlags = frameFlags; + } + + public long Timestamp { get; private set; } + + public int FrameNumber { get; private set; } + + public int Width { get; private set; } + + public int Height { get; private set; } + + public int BytesPerPixel { get; private set; } + + public abstract int PixelDataLength { get; } + + public void Dispose() + { + if (Interlocked.Exchange(ref this._isDisposed, 1) != 0) + return; + this.Dispose(true); + GC.SuppressFinalize((object) this); + } + + ~ImageFrame() + { + Debugger.Log(0, "Performance", string.Format((IFormatProvider) CultureInfo.InvariantCulture, "{0}\n", (object) Resources.ImageFrameNotDisposed)); + this.Dispose(false); + } + + protected abstract void Dispose(bool disposing); + + internal abstract ImageStream SourceStream { get; } + + internal ImageFrameFlags FrameFlags { get; private set; } + } +} diff --git a/src/Microsoft.Kinect/ImageFrameFlags.cs b/src/Microsoft.Kinect/ImageFrameFlags.cs new file mode 100644 index 0000000..2eb50b5 --- /dev/null +++ b/src/Microsoft.Kinect/ImageFrameFlags.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ImageFrameFlags +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + [Flags] + internal enum ImageFrameFlags : uint + { + NUI_IMAGE_FRAME_FLAG_NONE = 0, + NUI_IMAGE_FRAME_FLAG_NEAR_MODE_ENABLED = 131072, // 0x00020000 + } +} diff --git a/src/Microsoft.Kinect/ImageResolution.cs b/src/Microsoft.Kinect/ImageResolution.cs new file mode 100644 index 0000000..3e3c3c9 --- /dev/null +++ b/src/Microsoft.Kinect/ImageResolution.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ImageResolution +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + internal enum ImageResolution + { + Invalid = -1, // 0xFFFFFFFF + Resolution80x60 = 0, + Resolution320x240 = 1, + Resolution640x480 = 2, + Resolution1280x960 = 3, + } +} diff --git a/src/Microsoft.Kinect/ImageStream.cs b/src/Microsoft.Kinect/ImageStream.cs new file mode 100644 index 0000000..00bf48f --- /dev/null +++ b/src/Microsoft.Kinect/ImageStream.cs @@ -0,0 +1,234 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ImageStream +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Threading; + +namespace Microsoft.Kinect +{ + public abstract class ImageStream + { + internal ManualResetEvent NextFrameEvent = new ManualResetEvent(false); + private bool _capturing; + private IntPtr _nativeStreamHandle; + private ImageStreamFlags _imageStreamFlags; + private readonly object _nativeStreamInitLock = new object(); + + internal ImageStream(KinectSensor sensor, ImageStreamFlags imageStreamFlags = ImageStreamFlags.NUI_IMAGE_STREAM_FLAG_SUPPRESS_NO_FRAME_DATA) + { + this.Sensor = sensor; + this.BufferCount = 2; + this.IsEnabled = false; + this._imageStreamFlags = imageStreamFlags; + } + + public int FrameWidth { get; private set; } + + public int FrameHeight { get; private set; } + + public int FrameBytesPerPixel { get; protected set; } + + public int FramePixelDataLength { get; protected set; } + + internal KinectSensor Sensor { get; private set; } + + internal int BufferCount { get; private set; } + + internal ImageResolution Resolution { get; set; } + + internal abstract ImageType ImageType { get; } + + public bool IsEnabled { get; private set; } + + internal void InternalEnable() + { + if (this.Sensor.IsRunning) + this.Open(); + this.IsEnabled = true; + } + + public void Disable() + { + KinectEtwProvider.EventWriteManagedImageStreamDisabledInfo(this is ColorImageStream ? 0 : 1); + if (!this.IsEnabled) + return; + if (this.Sensor.IsRunning) + this.Close(); + this.IsEnabled = false; + } + + internal void Start() + { + if (!this.IsEnabled) + return; + this.Open(); + } + + internal void Stop() + { + if (!this._capturing) + return; + this.Close(); + } + + internal void FillHeightWidth() + { + int width; + int height; + ImageStream.ResolutionToHeightWidth(this.Resolution, out width, out height); + this.FrameWidth = width; + this.FrameHeight = height; + } + + internal static void ResolutionToHeightWidth( + ImageResolution resolution, + out int width, + out int height) + { + switch (resolution) + { + case ImageResolution.Resolution80x60: + width = 80; + height = 60; + break; + case ImageResolution.Resolution320x240: + width = 320; + height = 240; + break; + case ImageResolution.Resolution640x480: + width = 640; + height = 480; + break; + case ImageResolution.Resolution1280x960: + width = 1280; + height = 960; + break; + default: + throw new InvalidOperationException(); + } + } + + internal static int ImageTypeToBytesPerPixel(ImageType imageType) + { + switch (imageType) + { + case ImageType.DepthAndPlayerIndex: + case ImageType.ColorYuvRaw: + case ImageType.Depth: + case ImageType.ColorInfrared: + return 2; + case ImageType.Color: + case ImageType.ColorYuv: + return 4; + case ImageType.ColorBayer: + return 1; + default: + throw new InvalidOperationException(); + } + } + + internal ImageStreamFlags ImageStreamFlags + { + get + { + if (this._capturing && this.Sensor.IsRunning) + this._imageStreamFlags = (ImageStreamFlags) this.Sensor.NuiSensor.NuiImageStreamGetImageFrameFlags(this._nativeStreamHandle); + return this._imageStreamFlags; + } + set + { + if (this._capturing && this.Sensor.IsRunning) + this.Sensor.NuiSensor.NuiImageStreamSetImageFrameFlags(this._nativeStreamHandle, (uint) value); + this._imageStreamFlags = value; + } + } + + private void Open() + { + lock (this._nativeStreamInitLock) + { + this.NextFrameEvent.Reset(); + this.Sensor.NuiSensor.NuiImageStreamOpen((_NUI_IMAGE_TYPE) this.ImageType, (_NUI_IMAGE_RESOLUTION) this.Resolution, (uint) this.ImageStreamFlags, (uint) this.BufferCount, this.NextFrameEvent.SafeWaitHandle.DangerousGetHandle(), out this._nativeStreamHandle); + } + this._capturing = true; + } + + private void Close() => this._capturing = false; + + internal abstract void StorePixels( + int frameNumber, + _NUI_LOCKED_RECT lockedRect, + ImageType imageType, + ImageResolution resolution, + IntPtr nativeStreamHandle, + ref _NUI_IMAGE_FRAME pNativeFrame); + + internal bool TryGetNextFrameInternal( + int millisecondsWait, + out int frameNumber, + out long timestamp, + out ImageFrameFlags frameFlags) + { + frameNumber = 0; + timestamp = 0L; + frameFlags = ImageFrameFlags.NUI_IMAGE_FRAME_FLAG_NONE; + lock (this._nativeStreamInitLock) + { + if (this._nativeStreamHandle == IntPtr.Zero) + throw new InvalidOperationException(Resources.NativeStreamCantBeZero); + _NUI_IMAGE_FRAME pImageFrame; + int nextFrameNoThrow = this.Sensor.NuiSensor.NuiImageStreamGetNextFrameNoThrow(this._nativeStreamHandle, (uint) millisecondsWait, out pImageFrame); + if (nextFrameNoThrow < 0) + { + this.NextFrameEvent.Reset(); + return false; + } + if (nextFrameNoThrow == 0) + { + if (pImageFrame.pFrameTexture != null) + { + try + { + INuiFrameTexture pFrameTexture = pImageFrame.pFrameTexture; + _NUI_SURFACE_DESC pDesc = new _NUI_SURFACE_DESC(); + KinectExceptionHelper.CheckHr(pFrameTexture.GetLevelDesc(0U, ref pDesc)); + ImageType imageType = this.ImageType; + ImageResolution resolution = this.Resolution; + if (pImageFrame.eImageType != (_NUI_IMAGE_TYPE) imageType || pImageFrame.eResolution != (_NUI_IMAGE_RESOLUTION) resolution) + return false; + _NUI_LOCKED_RECT pLockedRect = new _NUI_LOCKED_RECT(); + tagRECT pRect = new tagRECT(); + KinectExceptionHelper.CheckHr(pFrameTexture.LockRect(0U, ref pLockedRect, ref pRect, 0U)); + frameNumber = (int) pImageFrame.dwFrameNumber; + timestamp = pImageFrame.liTimeStamp.QuadPart; + this.StorePixels(frameNumber, pLockedRect, imageType, resolution, this._nativeStreamHandle, ref pImageFrame); + KinectExceptionHelper.CheckHr(pFrameTexture.UnlockRect(0U)); + frameFlags = (ImageFrameFlags) pImageFrame.dwFrameFlags; + return true; + } + finally + { + this.Sensor.NuiSensor.NuiImageStreamReleaseFrame(this._nativeStreamHandle, ref pImageFrame); + } + } + } + return false; + } + } + + internal void Dispose() + { + this.Close(); + lock (this._nativeStreamInitLock) + { + if (this.NextFrameEvent == null) + return; + this.NextFrameEvent.Close(); + } + } + } +} diff --git a/src/Microsoft.Kinect/ImageStreamFlags.cs b/src/Microsoft.Kinect/ImageStreamFlags.cs new file mode 100644 index 0000000..42a7ff8 --- /dev/null +++ b/src/Microsoft.Kinect/ImageStreamFlags.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ImageStreamFlags +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + [Flags] + internal enum ImageStreamFlags : uint + { + NUI_IMAGE_STREAM_FLAG_NONE = 0, + NUI_IMAGE_STREAM_FLAG_SUPPRESS_NO_FRAME_DATA = 65536, // 0x00010000 + NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE = 131072, // 0x00020000 + NUI_IMAGE_STREAM_FLAG_DISTINCT_OVERFLOW_DEPTH_VALUES = 262144, // 0x00040000 + } +} diff --git a/src/Microsoft.Kinect/ImageType.cs b/src/Microsoft.Kinect/ImageType.cs new file mode 100644 index 0000000..87428f7 --- /dev/null +++ b/src/Microsoft.Kinect/ImageType.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ImageType +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + internal enum ImageType + { + DepthAndPlayerIndex, + Color, + ColorYuv, + ColorYuvRaw, + Depth, + ColorInfrared, + ColorBayer, + } +} diff --git a/src/Microsoft.Kinect/InternalStatusChangedEventArgs.cs b/src/Microsoft.Kinect/InternalStatusChangedEventArgs.cs new file mode 100644 index 0000000..6368611 --- /dev/null +++ b/src/Microsoft.Kinect/InternalStatusChangedEventArgs.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.InternalStatusChangedEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + internal class InternalStatusChangedEventArgs : EventArgs + { + public string DeviceConnectionId { get; set; } + + public string UniqueKinectId { get; set; } + + public KinectStatus KinectStatus { get; set; } + } +} diff --git a/src/Microsoft.Kinect/Interop/INuiAudioBeam.cs b/src/Microsoft.Kinect/Interop/INuiAudioBeam.cs new file mode 100644 index 0000000..5c497c9 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/INuiAudioBeam.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.INuiAudioBeam +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [Guid("8C3CEBFA-A35D-497E-BC9A-E9752A8155E0")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface INuiAudioBeam + { + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetBeam(out double angle); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetBeam([In] double angle); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetPosition(out double angle, out double confidence); + } +} diff --git a/src/Microsoft.Kinect/Interop/INuiColorCameraSettings.cs b/src/Microsoft.Kinect/Interop/INuiColorCameraSettings.cs new file mode 100644 index 0000000..3be617c --- /dev/null +++ b/src/Microsoft.Kinect/Interop/INuiColorCameraSettings.cs @@ -0,0 +1,215 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.INuiColorCameraSettings +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [Guid("00A4B392-E315-470C-90B7-F7B4C3CE00C4")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface INuiColorCameraSettings + { + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetAutoWhiteBalance([In] int AutoWhiteBalanceEnabled); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetAutoWhiteBalance(out int pAutoWhiteBalanceEnabled); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetWhiteBalance([In] int WhiteBalance); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetWhiteBalance(out int pWhiteBalance); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinWhiteBalance(out int pWhiteBalance); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxWhiteBalance(out int pWhiteBalance); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetContrast([In] double Contrast); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetContrast(out double pContrast); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinContrast(out double pContrast); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxContrast(out double pContrast); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetHue([In] double Hue); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetHue(out double pHue); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinHue(out double pHue); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxHue(out double pHue); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetSaturation([In] double Saturation); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetSaturation(out double pSaturation); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinSaturation(out double pSaturation); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxSaturation(out double pSaturation); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetGamma([In] double Gamma); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetGamma(out double pGamma); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinGamma(out double pGamma); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxGamma(out double pGamma); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetSharpness([In] double Sharpness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetSharpness(out double pSharpness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinSharpness(out double pSharpness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxSharpness(out double pSharpness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetAutoExposure([In] int AutoExposureEnabled); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetAutoExposure(out int pAutoExposureEnabled); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetExposureTime([In] double ExposureTime); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetExposureTime(out double pExposureTime); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinExposureTime(out double pExposureTime); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxExposureTime(out double pExposureTime); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetFrameInterval([In] double FrameInterval); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetFrameInterval(out double pFrameInterval); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinFrameInterval(out double pFrameInterval); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxFrameInterval(out double pFrameInterval); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetBrightness([In] double Brightness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetBrightness(out double pBrightness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinBrightness(out double pBrightness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxBrightness(out double pBrightness); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetPowerLineFrequency([In] _NUI_POWER_LINE_FREQUENCY PowerLineFrequency); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetPowerLineFrequency(out _NUI_POWER_LINE_FREQUENCY pPowerLineFrequency); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetBacklightCompensationMode( + [In] _NUI_BACKLIGHT_COMPENSATION_MODE BacklightCompensationMode); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetBacklightCompensationMode( + out _NUI_BACKLIGHT_COMPENSATION_MODE pBacklightCompensationMode); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int SetGain([In] double Gain); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetGain(out double pGain); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMinGain(out double pGain); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetMaxGain(out double pGain); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int ResetCameraSettingsToDefault(); + } +} diff --git a/src/Microsoft.Kinect/Interop/INuiCoordinateMapper.cs b/src/Microsoft.Kinect/Interop/INuiCoordinateMapper.cs new file mode 100644 index 0000000..ac6d2cc --- /dev/null +++ b/src/Microsoft.Kinect/Interop/INuiCoordinateMapper.cs @@ -0,0 +1,100 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.INuiCoordinateMapper +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("618E3670-BA84-4405-898A-3FF64446157C")] + [ComImport] + internal interface INuiCoordinateMapper + { + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetColorToDepthRelationalParameters(out uint pDataByteCount, out IntPtr ppData); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NotifyParametersChanged( + [MarshalAs(UnmanagedType.Interface), In] INuiCoordinateMapperParametersChangedEvent pCallback); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapColorFrameToDepthFrame( + [In] _NUI_IMAGE_TYPE eColorType, + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] uint cDepthPixels, + [In] IntPtr pDepthPixels, + [In] uint cDepthPoints, + [In] IntPtr pDepthPoints); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapColorFrameToSkeletonFrame( + [In] _NUI_IMAGE_TYPE eColorType, + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] uint cDepthPixels, + [In] IntPtr pDepthPixels, + [In] uint cSkeletonPoints, + [In] IntPtr pSkeletonPoints); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapDepthFrameToColorFrame( + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] uint cDepthPixels, + [In] IntPtr pDepthPixels, + [In] _NUI_IMAGE_TYPE eColorType, + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + [In] uint cColorPoints, + [In] IntPtr pColorPoints); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapDepthFrameToSkeletonFrame( + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] uint cDepthPixels, + [In] IntPtr pDepthPixels, + [In] uint cSkeletonPoints, + [In] IntPtr pSkeletonPoints); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapDepthPointToColorPoint( + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] ref _NUI_DEPTH_IMAGE_POINT pDepthPoint, + [In] _NUI_IMAGE_TYPE eColorType, + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + out _NUI_COLOR_IMAGE_POINT pColorPoint); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapDepthPointToSkeletonPoint( + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] ref _NUI_DEPTH_IMAGE_POINT pDepthPoint, + out _Vector4 pSkeletonPoint); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapSkeletonPointToColorPoint( + [In] ref _Vector4 pSkeletonPoint, + [In] _NUI_IMAGE_TYPE eColorType, + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + out _NUI_COLOR_IMAGE_POINT pColorPoint); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int MapSkeletonPointToDepthPoint( + [In] ref _Vector4 pSkeletonPoint, + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + out _NUI_DEPTH_IMAGE_POINT pDepthPoint); + } +} diff --git a/src/Microsoft.Kinect/Interop/INuiCoordinateMapperParametersChangedEvent.cs b/src/Microsoft.Kinect/Interop/INuiCoordinateMapperParametersChangedEvent.cs new file mode 100644 index 0000000..f446a31 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/INuiCoordinateMapperParametersChangedEvent.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.INuiCoordinateMapperParametersChangedEvent +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [Guid("BABEBBEC-C71B-4EE8-9F15-FC5C6C948622")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface INuiCoordinateMapperParametersChangedEvent + { + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int Invoke(); + } +} diff --git a/src/Microsoft.Kinect/Interop/INuiDepthFilter.cs b/src/Microsoft.Kinect/Interop/INuiDepthFilter.cs new file mode 100644 index 0000000..8ed9b61 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/INuiDepthFilter.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.INuiDepthFilter +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [Guid("1D7C07DD-2304-49BB-9B7F-2FDC6E00C1B2")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface INuiDepthFilter + { + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int ProcessFrame( + [In] _LARGE_INTEGER liTimeStamp, + [In] uint Width, + [In] uint Height, + [In] IntPtr pDepthImagePixels, + out int pFrameModified); + } +} diff --git a/src/Microsoft.Kinect/Interop/INuiFrameTexture.cs b/src/Microsoft.Kinect/Interop/INuiFrameTexture.cs new file mode 100644 index 0000000..dffc296 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/INuiFrameTexture.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.INuiFrameTexture +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [Guid("13EA17F5-FF2E-4670-9EE5-1297A6E880D1")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + internal interface INuiFrameTexture + { + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + int BufferLen(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + int Pitch(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int LockRect(uint Level, ref _NUI_LOCKED_RECT pLockedRect, ref tagRECT pRect, uint Flags); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int GetLevelDesc(uint Level, ref _NUI_SURFACE_DESC pDesc); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int UnlockRect([In] uint Level); + } +} diff --git a/src/Microsoft.Kinect/Interop/INuiSensor.cs b/src/Microsoft.Kinect/Interop/INuiSensor.cs new file mode 100644 index 0000000..b927d10 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/INuiSensor.cs @@ -0,0 +1,186 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.INuiSensor +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("D3D9AB7B-31BA-44CA-8CC0-D42525BBEA43")] + [ComImport] + internal interface INuiSensor + { + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiInitialize([In] uint dwFlags); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void NuiShutdown(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiSetFrameEndEvent([In] IntPtr hEvent, [In] uint dwFrameEventFlag); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageStreamOpen( + [In] _NUI_IMAGE_TYPE eImageType, + [In] _NUI_IMAGE_RESOLUTION eResolution, + [In] uint dwImageFrameFlags, + [In] uint dwFrameLimit, + [In] IntPtr hNextFrameEvent, + out IntPtr phStreamHandle); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageStreamSetImageFrameFlags([In] IntPtr hStream, [In] uint dwImageFrameFlags); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageStreamGetImageFrameFlags([In] IntPtr hStream, out uint pdwImageFrameFlags); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageStreamGetNextFrame( + [In] IntPtr hStream, + [In] uint dwMillisecondsToWait, + out _NUI_IMAGE_FRAME pImageFrame); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageStreamReleaseFrame([In] IntPtr hStream, [In] ref _NUI_IMAGE_FRAME pImageFrame); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageGetColorPixelCoordinatesFromDepthPixel( + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + [In] ref _NUI_IMAGE_VIEW_AREA pcViewArea, + [In] int lDepthX, + [In] int lDepthY, + [In] ushort usDepthValue, + out int plColorX, + out int plColorY); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution( + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] ref _NUI_IMAGE_VIEW_AREA pcViewArea, + [In] int lDepthX, + [In] int lDepthY, + [In] ushort usDepthValue, + out int plColorX, + out int plColorY); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution( + [In] _NUI_IMAGE_RESOLUTION eColorResolution, + [In] _NUI_IMAGE_RESOLUTION eDepthResolution, + [In] uint cDepthValues, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] short[] pDepthValues, + uint cColorCoordinates, + [In] IntPtr pColorCoordinates); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiCameraElevationSetAngle([In] int lAngleDegrees); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiCameraElevationGetAngle(out int plAngleDegrees); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiSkeletonTrackingEnable([In] IntPtr hNextFrameEvent, [In] uint dwFlags); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiSkeletonTrackingDisable(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiSkeletonSetTrackedSkeletons([MarshalAs(UnmanagedType.LPArray, SizeConst = 2), In] uint[] TrackingIDs); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiSkeletonGetNextFrame([In] uint dwMillisecondsToWait, [In, Out] ref _NUI_SKELETON_FRAME pSkeletonFrame); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiTransformSmooth( + ref _NUI_SKELETON_FRAME pSkeletonFrame, + ref _NUI_TRANSFORM_SMOOTH_PARAMETERS pSmoothingParams); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiGetAudioSource([MarshalAs(UnmanagedType.Interface)] out INuiAudioBeam ppDmo); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + int NuiInstanceIndex(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.BStr)] + string NuiDeviceConnectionId(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.BStr)] + string NuiUniqueId(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.BStr)] + string NuiAudioArrayId(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiStatus(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint NuiInitializationFlags(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiGetCoordinateMapper([MarshalAs(UnmanagedType.Interface)] out INuiCoordinateMapper pMapping); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiImageFrameGetDepthImagePixelFrameTexture( + [In] IntPtr hStream, + [In] ref _NUI_IMAGE_FRAME pImageFrame, + out int pNearMode, + [MarshalAs(UnmanagedType.Interface)] out INuiFrameTexture ppFrameTexture); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiGetColorCameraSettings([MarshalAs(UnmanagedType.Interface)] out INuiColorCameraSettings pCameraSettings); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + int NuiGetForceInfraredEmitterOff(); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiSetForceInfraredEmitterOff([In] int fForceInfraredEmitterOff); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiAccelerometerGetCurrentReading(out _Vector4 pReading); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiSetDepthFilter([MarshalAs(UnmanagedType.Interface), In] INuiDepthFilter pDepthFilter); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiGetDepthFilter([MarshalAs(UnmanagedType.Interface)] out INuiDepthFilter ppDepthFilter); + + [MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Error)] + int NuiGetDepthFilterForTimeStamp([In] _LARGE_INTEGER liTimeStamp, [MarshalAs(UnmanagedType.Interface)] out INuiDepthFilter ppDepthFilter); + } +} diff --git a/src/Microsoft.Kinect/Interop/_LARGE_INTEGER.cs b/src/Microsoft.Kinect/Interop/_LARGE_INTEGER.cs new file mode 100644 index 0000000..a78522e --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_LARGE_INTEGER.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._LARGE_INTEGER +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct _LARGE_INTEGER + { + public long QuadPart; + } +} diff --git a/src/Microsoft.Kinect/Interop/_Matrix4.cs b/src/Microsoft.Kinect/Interop/_Matrix4.cs new file mode 100644 index 0000000..7303d29 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_Matrix4.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._Matrix4 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _Matrix4 + { + public float M11; + public float M12; + public float M13; + public float M14; + public float M21; + public float M22; + public float M23; + public float M24; + public float M31; + public float M32; + public float M33; + public float M34; + public float M41; + public float M42; + public float M43; + public float M44; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_BACKLIGHT_COMPENSATION_MODE.cs b/src/Microsoft.Kinect/Interop/_NUI_BACKLIGHT_COMPENSATION_MODE.cs new file mode 100644 index 0000000..9d00c26 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_BACKLIGHT_COMPENSATION_MODE.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_BACKLIGHT_COMPENSATION_MODE +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect.Interop +{ + internal enum _NUI_BACKLIGHT_COMPENSATION_MODE + { + NUI_BACKLIGHT_COMPENSATION_MODE_AVERAGE_BRIGHTNESS = 0, + NUI_BACKLIGHT_COMPENSATION_MODE_CENTER_PRIORITY = 1, + NUI_BACKLIGHT_COMPENSATION_MODE_LOWLIGHTS_PRIORITY = 2, + NUI_BACKLIGHT_COMPENSATION_MODE_CENTER_ONLY = 4, + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_COLOR_IMAGE_POINT.cs b/src/Microsoft.Kinect/Interop/_NUI_COLOR_IMAGE_POINT.cs new file mode 100644 index 0000000..72d5708 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_COLOR_IMAGE_POINT.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_COLOR_IMAGE_POINT +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_COLOR_IMAGE_POINT + { + public int x; + public int y; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_PIXEL.cs b/src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_PIXEL.cs new file mode 100644 index 0000000..254abdd --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_PIXEL.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_DEPTH_IMAGE_PIXEL +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 2)] + internal struct _NUI_DEPTH_IMAGE_PIXEL + { + public ushort playerIndex; + public ushort depth; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_POINT.cs b/src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_POINT.cs new file mode 100644 index 0000000..86e4b1a --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_DEPTH_IMAGE_POINT.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_DEPTH_IMAGE_POINT +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_DEPTH_IMAGE_POINT + { + public int x; + public int y; + public int depth; + public int reserved; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_IMAGE_FRAME.cs b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_FRAME.cs new file mode 100644 index 0000000..76a4a22 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_FRAME.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_IMAGE_FRAME +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct _NUI_IMAGE_FRAME + { + public _LARGE_INTEGER liTimeStamp; + public uint dwFrameNumber; + public _NUI_IMAGE_TYPE eImageType; + public _NUI_IMAGE_RESOLUTION eResolution; + [MarshalAs(UnmanagedType.Interface)] + public INuiFrameTexture pFrameTexture; + public uint dwFrameFlags; + public _NUI_IMAGE_VIEW_AREA ViewArea; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_IMAGE_RESOLUTION.cs b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_RESOLUTION.cs new file mode 100644 index 0000000..a427aa2 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_RESOLUTION.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_IMAGE_RESOLUTION +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect.Interop +{ + internal enum _NUI_IMAGE_RESOLUTION + { + NUI_IMAGE_RESOLUTION_INVALID = -1, // 0xFFFFFFFF + NUI_IMAGE_RESOLUTION_80x60 = 0, + NUI_IMAGE_RESOLUTION_320x240 = 1, + NUI_IMAGE_RESOLUTION_640x480 = 2, + NUI_IMAGE_RESOLUTION_1280x960 = 3, + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_IMAGE_TYPE.cs b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_TYPE.cs new file mode 100644 index 0000000..e00ec6d --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_TYPE.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_IMAGE_TYPE +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect.Interop +{ + internal enum _NUI_IMAGE_TYPE + { + NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX, + NUI_IMAGE_TYPE_COLOR, + NUI_IMAGE_TYPE_COLOR_YUV, + NUI_IMAGE_TYPE_COLOR_RAW_YUV, + NUI_IMAGE_TYPE_DEPTH, + NUI_IMAGE_TYPE_COLOR_INFRARED, + NUI_IMAGE_TYPE_COLOR_RAW_BAYER, + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_IMAGE_VIEW_AREA.cs b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_VIEW_AREA.cs new file mode 100644 index 0000000..dc5915f --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_IMAGE_VIEW_AREA.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_IMAGE_VIEW_AREA +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_IMAGE_VIEW_AREA + { + public int eDigitalZoom; + public int lCenterX; + public int lCenterY; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_LOCKED_RECT.cs b/src/Microsoft.Kinect/Interop/_NUI_LOCKED_RECT.cs new file mode 100644 index 0000000..5ecca42 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_LOCKED_RECT.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_LOCKED_RECT +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_LOCKED_RECT + { + public int Pitch; + public int size; + public IntPtr pBits; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_POWER_LINE_FREQUENCY.cs b/src/Microsoft.Kinect/Interop/_NUI_POWER_LINE_FREQUENCY.cs new file mode 100644 index 0000000..a7be809 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_POWER_LINE_FREQUENCY.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_POWER_LINE_FREQUENCY +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect.Interop +{ + internal enum _NUI_POWER_LINE_FREQUENCY + { + NUI_POWER_LINE_FREQUENCY_DISABLED, + NUI_POWER_LINE_FREQUENCY_50HZ, + NUI_POWER_LINE_FREQUENCY_60HZ, + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ORIENTATION.cs b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ORIENTATION.cs new file mode 100644 index 0000000..0eef742 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ORIENTATION.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SKELETON_BONE_ORIENTATION +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_SKELETON_BONE_ORIENTATION + { + public _NUI_SKELETON_POSITION_INDEX endJoint; + public _NUI_SKELETON_POSITION_INDEX startJoint; + public _NUI_SKELETON_BONE_ROTATION hierarchicalRotation; + public _NUI_SKELETON_BONE_ROTATION absoluteRotation; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ROTATION.cs b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ROTATION.cs new file mode 100644 index 0000000..3190866 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_BONE_ROTATION.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SKELETON_BONE_ROTATION +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_SKELETON_BONE_ROTATION + { + public _Matrix4 rotationMatrix; + public _Vector4 rotationQuaternion; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SKELETON_DATA.cs b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_DATA.cs new file mode 100644 index 0000000..de415b4 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_DATA.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SKELETON_DATA +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_SKELETON_DATA + { + public _NUI_SKELETON_TRACKING_STATE eTrackingState; + public uint dwTrackingID; + public uint dwEnrollmentIndex; + public uint dwUserIndex; + public _Vector4 Position; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public _Vector4[] SkeletonPositions; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public _NUI_SKELETON_POSITION_TRACKING_STATE[] eSkeletonPositionTrackingState; + public uint dwQualityFlags; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SKELETON_FRAME.cs b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_FRAME.cs new file mode 100644 index 0000000..39a0eff --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_FRAME.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SKELETON_FRAME +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct _NUI_SKELETON_FRAME + { + public _LARGE_INTEGER liTimeStamp; + public uint dwFrameNumber; + public uint dwFlags; + public _Vector4 vFloorClipPlane; + public _Vector4 vNormalToGravity; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public _NUI_SKELETON_DATA[] SkeletonData; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_INDEX.cs b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_INDEX.cs new file mode 100644 index 0000000..afa1aa0 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_INDEX.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SKELETON_POSITION_INDEX +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect.Interop +{ + internal enum _NUI_SKELETON_POSITION_INDEX + { + NUI_SKELETON_POSITION_HIP_CENTER, + NUI_SKELETON_POSITION_SPINE, + NUI_SKELETON_POSITION_SHOULDER_CENTER, + NUI_SKELETON_POSITION_HEAD, + NUI_SKELETON_POSITION_SHOULDER_LEFT, + NUI_SKELETON_POSITION_ELBOW_LEFT, + NUI_SKELETON_POSITION_WRIST_LEFT, + NUI_SKELETON_POSITION_HAND_LEFT, + NUI_SKELETON_POSITION_SHOULDER_RIGHT, + NUI_SKELETON_POSITION_ELBOW_RIGHT, + NUI_SKELETON_POSITION_WRIST_RIGHT, + NUI_SKELETON_POSITION_HAND_RIGHT, + NUI_SKELETON_POSITION_HIP_LEFT, + NUI_SKELETON_POSITION_KNEE_LEFT, + NUI_SKELETON_POSITION_ANKLE_LEFT, + NUI_SKELETON_POSITION_FOOT_LEFT, + NUI_SKELETON_POSITION_HIP_RIGHT, + NUI_SKELETON_POSITION_KNEE_RIGHT, + NUI_SKELETON_POSITION_ANKLE_RIGHT, + NUI_SKELETON_POSITION_FOOT_RIGHT, + NUI_SKELETON_POSITION_COUNT, + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_TRACKING_STATE.cs b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_TRACKING_STATE.cs new file mode 100644 index 0000000..efce031 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_POSITION_TRACKING_STATE.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SKELETON_POSITION_TRACKING_STATE +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect.Interop +{ + internal enum _NUI_SKELETON_POSITION_TRACKING_STATE + { + NUI_SKELETON_POSITION_NOT_TRACKED, + NUI_SKELETON_POSITION_INFERRED, + NUI_SKELETON_POSITION_TRACKED, + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SKELETON_TRACKING_STATE.cs b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_TRACKING_STATE.cs new file mode 100644 index 0000000..396c799 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SKELETON_TRACKING_STATE.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SKELETON_TRACKING_STATE +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect.Interop +{ + internal enum _NUI_SKELETON_TRACKING_STATE + { + NUI_SKELETON_NOT_TRACKED, + NUI_SKELETON_POSITION_ONLY, + NUI_SKELETON_TRACKED, + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_SURFACE_DESC.cs b/src/Microsoft.Kinect/Interop/_NUI_SURFACE_DESC.cs new file mode 100644 index 0000000..200de65 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_SURFACE_DESC.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_SURFACE_DESC +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_SURFACE_DESC + { + public uint Width; + public uint Height; + } +} diff --git a/src/Microsoft.Kinect/Interop/_NUI_TRANSFORM_SMOOTH_PARAMETERS.cs b/src/Microsoft.Kinect/Interop/_NUI_TRANSFORM_SMOOTH_PARAMETERS.cs new file mode 100644 index 0000000..bf27847 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_NUI_TRANSFORM_SMOOTH_PARAMETERS.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._NUI_TRANSFORM_SMOOTH_PARAMETERS +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _NUI_TRANSFORM_SMOOTH_PARAMETERS + { + public float fSmoothing; + public float fCorrection; + public float fPrediction; + public float fJitterRadius; + public float fMaxDeviationRadius; + } +} diff --git a/src/Microsoft.Kinect/Interop/_Vector4.cs b/src/Microsoft.Kinect/Interop/_Vector4.cs new file mode 100644 index 0000000..76962bd --- /dev/null +++ b/src/Microsoft.Kinect/Interop/_Vector4.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop._Vector4 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct _Vector4 + { + public float x; + public float y; + public float z; + public float w; + } +} diff --git a/src/Microsoft.Kinect/Interop/tagRECT.cs b/src/Microsoft.Kinect/Interop/tagRECT.cs new file mode 100644 index 0000000..b9c9d84 --- /dev/null +++ b/src/Microsoft.Kinect/Interop/tagRECT.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Interop.tagRECT +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect.Interop +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + internal struct tagRECT + { + public int left; + public int top; + public int right; + public int bottom; + } +} diff --git a/src/Microsoft.Kinect/Joint.cs b/src/Microsoft.Kinect/Joint.cs new file mode 100644 index 0000000..4f31b00 --- /dev/null +++ b/src/Microsoft.Kinect/Joint.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Joint +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Diagnostics; + +namespace Microsoft.Kinect +{ + [DebuggerDisplay("Position:{Position} JointType:{JointType} TrackingState:{TrackingState}")] + [Serializable] + public struct Joint + { + public SkeletonPoint Position { get; set; } + + public JointType JointType { get; internal set; } + + public JointTrackingState TrackingState { get; set; } + + public override int GetHashCode() => this.Position.GetHashCode() + this.JointType.GetHashCode() + this.TrackingState.GetHashCode(); + + public override bool Equals(object obj) => obj is Joint joint && this.Equals(joint); + + public bool Equals(Joint joint) => this.JointType == joint.JointType && this.Position == joint.Position && this.TrackingState == joint.TrackingState; + + public static bool operator ==(Joint joint1, Joint joint2) => joint1.Equals(joint2); + + public static bool operator !=(Joint joint1, Joint joint2) => !joint1.Equals(joint2); + } +} diff --git a/src/Microsoft.Kinect/JointCollection.cs b/src/Microsoft.Kinect/JointCollection.cs new file mode 100644 index 0000000..ba06732 --- /dev/null +++ b/src/Microsoft.Kinect/JointCollection.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.JointCollection +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace Microsoft.Kinect +{ + [Serializable] + public class JointCollection : IEnumerable, IEnumerable + { + private readonly Joint[] _skeletonData; + [XmlIgnore] + [NonSerialized] + private readonly Skeleton _skeletonBackReference; + + internal JointCollection(Skeleton backReference) + { + this._skeletonData = new Joint[Skeleton.JointTypeValues.Length]; + this._skeletonBackReference = backReference; + } + + public int Count => this._skeletonData.Length; + + public Joint this[JointType jointType] + { + get => this._skeletonData[(int) jointType]; + set + { + if (value.JointType != jointType) + throw new ArgumentException(Resources.IncorrectJointType); + if (this._skeletonBackReference != null) + this._skeletonBackReference.InvalidateBoneOrientations(); + this._skeletonData[(int) jointType] = value; + } + } + + public IEnumerator GetEnumerator() => this._skeletonData.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable) this._skeletonData).GetEnumerator(); + } +} diff --git a/src/Microsoft.Kinect/JointTrackingState.cs b/src/Microsoft.Kinect/JointTrackingState.cs new file mode 100644 index 0000000..1ac5017 --- /dev/null +++ b/src/Microsoft.Kinect/JointTrackingState.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.JointTrackingState +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum JointTrackingState + { + NotTracked, + Inferred, + Tracked, + } +} diff --git a/src/Microsoft.Kinect/JointType.cs b/src/Microsoft.Kinect/JointType.cs new file mode 100644 index 0000000..b4b4106 --- /dev/null +++ b/src/Microsoft.Kinect/JointType.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.JointType +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum JointType + { + HipCenter, + Spine, + ShoulderCenter, + Head, + ShoulderLeft, + ElbowLeft, + WristLeft, + HandLeft, + ShoulderRight, + ElbowRight, + WristRight, + HandRight, + HipLeft, + KneeLeft, + AnkleLeft, + FootLeft, + HipRight, + KneeRight, + AnkleRight, + FootRight, + } +} diff --git a/src/Microsoft.Kinect/KinectAudioSource.cs b/src/Microsoft.Kinect/KinectAudioSource.cs new file mode 100644 index 0000000..3e396b8 --- /dev/null +++ b/src/Microsoft.Kinect/KinectAudioSource.cs @@ -0,0 +1,425 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.KinectAudioSource +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.Kinect +{ + public sealed class KinectAudioSource + { + internal const int PID_FIRST_USABLE = 2; + internal const int MFPKEY_WMAAECMA_SYSTEM_MODE = 2; + internal const int MFPKEY_WMAAECMA_DMO_SOURCE_MODE = 3; + internal const int MFPKEY_WMAAECMA_DEVICE_INDEXES = 4; + internal const int MFPKEY_WMAAECMA_FEATURE_MODE = 5; + internal const int MFPKEY_WMAAECMA_FEATR_NS = 8; + internal const int MFPKEY_WMAAECMA_FEATR_AGC = 9; + internal const int MFPKEY_WMAAECMA_FEATR_AES = 10; + internal const int MFPKEY_WMAAECMA_FEATR_MICARR_MODE = 18; + private const double s_minBeamAngle = -50.0; + private const double s_maxBeamAngle = 50.0; + private const double s_minSoundSourceAngle = -50.0; + private const double s_maxSoundSourceAngle = 50.0; + internal const string AUDIO_CAPTURE_THREAD_NAME = "AudioCaptureThread"; + internal static readonly Guid MFPKEY_WMAAECMA_KEY_BASE = new Guid(1867695463, (short) 864, (short) 19410, new byte[8] + { + (byte) 150, + (byte) 23, + (byte) 204, + (byte) 191, + (byte) 20, + (byte) 33, + (byte) 201, + (byte) 57 + }); + internal static readonly TimeSpan DefaultReadStaleThreshold = TimeSpan.FromMilliseconds(500.0); + private readonly Dictionary _dmoProperties = new Dictionary(); + private bool _applyProperties; + private readonly INativeAudioWrapper _nativeAudioWrapper; + private readonly object _propertyLock = new object(); + private readonly object _initLock = new object(); + private KinectAudioStream _stream; + private double _soundSourceAngle; + private double _soundSourceAngleConfidence; + private double _beamAngle; + private double _manualBeamAngle; + private double _beamAngleSetValue = double.MinValue; + private KinectSensor _sensor; + private readonly ContextEventHandler _BeamAngleChangedContextHandler; + private readonly ContextEventHandler _SoundSourceAngleChangedContextHandler; + private EchoCancellationMode _echoCancellationMode; + private BeamAngleMode _beamAngleMode; + + internal INativeAudioWrapper NativeWrapper => this._nativeAudioWrapper; + + internal static PROPERTYKEY PropertyKeyFromId(int pid) => new PROPERTYKEY() + { + pid = pid, + fmtid = KinectAudioSource.MFPKEY_WMAAECMA_KEY_BASE + }; + + private void SetProperty(int pid, object value) + { + PROPERTYKEY key = KinectAudioSource.PropertyKeyFromId(pid); + lock (this._propertyLock) + { + this._dmoProperties[key] = value; + this._applyProperties = true; + } + } + + private object GetProperty(int pid) + { + object property = (object) null; + PROPERTYKEY key = new PROPERTYKEY() + { + pid = pid, + fmtid = KinectAudioSource.MFPKEY_WMAAECMA_KEY_BASE + }; + lock (this._propertyLock) + { + if (this._dmoProperties.ContainsKey(key)) + property = this._dmoProperties[key]; + } + return property; + } + + internal void ApplyPendingProperties(IPropertyStore propertyStore) + { + lock (this._propertyLock) + { + if (!this._applyProperties) + return; + foreach (PROPERTYKEY key in this._dmoProperties.Keys) + { + IPropertyStore propertyStore1 = propertyStore; + PROPERTYKEY propertykey = key; + ref PROPERTYKEY local1 = ref propertykey; + object dmoProperty = this._dmoProperties[key]; + ref object local2 = ref dmoProperty; + propertyStore1.SetValue(ref local1, ref local2); + } + this._applyProperties = false; + } + } + + private void VerifyFeatureMode() + { + if (!this.FeatureMode) + throw new InvalidOperationException(Resources.NeedFeatureMode); + } + + private int DeviceIndexes + { + get + { + object property = this.GetProperty(4); + return property == null ? 0 : (int) property; + } + set => this.SetProperty(4, (object) value); + } + + internal ushort MicrophoneIndex + { + set => this.DeviceIndexes = (int) ((long) this.DeviceIndexes & 4294901760L) | (int) value; + } + + private bool FeatureMode + { + get + { + object property = this.GetProperty(5); + return property != null && (bool) property; + } + set => this.SetProperty(5, (object) value); + } + + private KinectAudioSource._MIC_ARRAY_MODE MicArrayMode + { + set + { + this.VerifyFeatureMode(); + this.SetProperty(18, (object) (int) value); + } + } + + public event EventHandler BeamAngleChanged + { + add => this._BeamAngleChangedContextHandler.AddHandler(value); + remove => this._BeamAngleChangedContextHandler.RemoveHandler(value); + } + + public event EventHandler SoundSourceAngleChanged + { + add => this._SoundSourceAngleChangedContextHandler.AddHandler(value); + remove => this._SoundSourceAngleChangedContextHandler.RemoveHandler(value); + } + + internal KinectAudioSource(KinectSensor sensor, INativeAudioWrapper audioWrapper) + { + this._BeamAngleChangedContextHandler = new ContextEventHandler(); + this._SoundSourceAngleChangedContextHandler = new ContextEventHandler(); + this._sensor = sensor; + this._nativeAudioWrapper = audioWrapper; + this._beamAngle = 0.0; + this._manualBeamAngle = 0.0; + this._soundSourceAngle = 0.0; + this._soundSourceAngleConfidence = 0.0; + this.SetProperty(3, (object) true); + this.FeatureMode = true; + this.EchoCancellationMode = EchoCancellationMode.None; + this.EchoCancellationSpeakerIndex = this.GetDefaultSpeakerIndex(); + this.BeamAngleMode = BeamAngleMode.Automatic; + this.NoiseSuppression = true; + this.AutomaticGainControlEnabled = false; + } + + internal KinectAudioSource(KinectSensor sensor) + : this(sensor, (INativeAudioWrapper) new DmoAudioWrapper(sensor)) + { + } + + public Stream Start(TimeSpan readStaleThreshold) + { + lock (this._initLock) + { + if (this._sensor == null || !this._sensor.IsRunning) + throw new InvalidOperationException(Resources.SensorMustBeRunningForAudio); + if (this._stream != null) + this.Stop(); + if (this._stream != null) + throw new InvalidOperationException(Resources.CaptureAlreadyStarted); + this._applyProperties = true; + this._stream = new KinectAudioStream(this, readStaleThreshold); + this._stream.Start(); + } + return (Stream) this._stream; + } + + public Stream Start() => this.Start(KinectAudioSource.DefaultReadStaleThreshold); + + public void Stop() + { + lock (this._initLock) + { + if (this._stream == null) + return; + this._stream.Stop(); + this._stream.Dispose(); + this._stream = (KinectAudioStream) null; + } + } + + public static double MinBeamAngle => -50.0; + + public static double MaxBeamAngle => 50.0; + + public static double MinSoundSourceAngle => -50.0; + + public static double MaxSoundSourceAngle => 50.0; + + public EchoCancellationMode EchoCancellationMode + { + get => this._echoCancellationMode; + set + { + switch (value) + { + case EchoCancellationMode.None: + this.SetEchoCancellationMode(0, KinectAudioSource._AEC_SYSTEM_MODE.ArrayOnly); + break; + case EchoCancellationMode.CancellationOnly: + this.SetEchoCancellationMode(0, KinectAudioSource._AEC_SYSTEM_MODE.ArrayAndEchoCancellation); + break; + case EchoCancellationMode.CancellationAndSuppression: + this.SetEchoCancellationMode(1, KinectAudioSource._AEC_SYSTEM_MODE.ArrayAndEchoCancellation); + break; + default: + throw new InvalidOperationException(Resources.InvalidEchoCancellationMode); + } + this._echoCancellationMode = value; + } + } + + private void SetEchoCancellationMode( + int echoSuppression, + KinectAudioSource._AEC_SYSTEM_MODE sysMode) + { + this.VerifyFeatureMode(); + this.SetProperty(10, (object) echoSuppression); + this.SetProperty(2, (object) (int) sysMode); + } + + public BeamAngleMode BeamAngleMode + { + get => this._beamAngleMode; + set + { + switch (value) + { + case BeamAngleMode.Automatic: + this.MicArrayMode = KinectAudioSource._MIC_ARRAY_MODE.SingleBeam; + break; + case BeamAngleMode.Adaptive: + this.MicArrayMode = KinectAudioSource._MIC_ARRAY_MODE.AdaptiveBeam; + break; + case BeamAngleMode.Manual: + this.MicArrayMode = KinectAudioSource._MIC_ARRAY_MODE.ExternalBeam; + break; + default: + throw new InvalidOperationException(Resources.InvalidBeamAngleMode); + } + this._beamAngleMode = value; + } + } + + public double SoundSourceAngle => this._soundSourceAngle * 180.0 / Math.PI; + + public double SoundSourceAngleConfidence => this._soundSourceAngleConfidence; + + public int EchoCancellationSpeakerIndex + { + get => (int) (((long) this.DeviceIndexes & 4294901760L) >> 16); + set => this.DeviceIndexes = this.DeviceIndexes & (int) ushort.MaxValue | value << 16; + } + + public bool NoiseSuppression + { + get + { + object property = this.GetProperty(8); + return property != null && 0 != (int) property; + } + set + { + this.VerifyFeatureMode(); + this.SetProperty(8, (object) (value ? 1 : 0)); + } + } + + public bool AutomaticGainControlEnabled + { + get + { + object property = this.GetProperty(9); + return property != null && (bool) property; + } + set + { + this.VerifyFeatureMode(); + this.SetProperty(9, (object) value); + } + } + + public double BeamAngle => this._beamAngle * 180.0 / Math.PI; + + public double ManualBeamAngle + { + get => this._manualBeamAngle; + set + { + this._manualBeamAngle = value; + this._beamAngleSetValue = this._manualBeamAngle * Math.PI / 180.0; + } + } + + internal void SetBeamAngle(double angle) + { + this._beamAngle = angle; + this._BeamAngleChangedContextHandler.Invoke((object) this, new BeamAngleChangedEventArgs() + { + Angle = this.BeamAngle + }); + } + + internal void SetSoundSourceAngleAndConfidence(double angle, double confidence) + { + this._soundSourceAngle = angle; + this._soundSourceAngleConfidence = confidence; + this._SoundSourceAngleChangedContextHandler.Invoke((object) this, new SoundSourceAngleChangedEventArgs() + { + Angle = this.SoundSourceAngle, + ConfidenceLevel = this.SoundSourceAngleConfidence + }); + } + + internal double FetchNextBeamAngle() + { + double beamAngleSetValue = this._beamAngleSetValue; + this._beamAngleSetValue = double.MinValue; + return beamAngleSetValue; + } + + private IEnumerable FindCaptureDevices() + { + int count = 0; + this._nativeAudioWrapper.GetMicrophoneArrayDevices((MicrophoneArrayDevice[]) null, ref count); + MicrophoneArrayDevice[] deviceBuffer = new MicrophoneArrayDevice[count]; + this._nativeAudioWrapper.GetMicrophoneArrayDevices(deviceBuffer, ref count); + return (IEnumerable) deviceBuffer; + } + + private int GetDefaultSpeakerIndex() + { + int count = 0; + this._nativeAudioWrapper.GetSpeakerDevices((SpeakerDevice[]) null, ref count); + SpeakerDevice[] deviceBuffer = new SpeakerDevice[count]; + this._nativeAudioWrapper.GetSpeakerDevices(deviceBuffer, ref count); + int defaultSpeakerIndex = 0; + foreach (SpeakerDevice speakerDevice in deviceBuffer) + { + if (speakerDevice.IsDefault) + { + defaultSpeakerIndex = speakerDevice.DeviceIndex; + break; + } + } + return defaultSpeakerIndex; + } + + internal ushort? FindMicrophoneIndex() + { + foreach (MicrophoneArrayDevice captureDevice in this.FindCaptureDevices()) + { + if (this._nativeAudioWrapper.MatchAudioDeviceToSensor(captureDevice)) + return new ushort?((ushort) captureDevice.DeviceIndex); + } + return new ushort?(); + } + + internal void Dispose() + { + lock (this._initLock) + { + if (this._sensor == null) + return; + if (this._stream != null) + this.Stop(); + this._BeamAngleChangedContextHandler.Dispose(); + this._SoundSourceAngleChangedContextHandler.Dispose(); + this._sensor = (KinectSensor) null; + } + } + + internal enum _MIC_ARRAY_MODE + { + SingleChannel = 0, + SimpleSum = 256, // 0x00000100 + SingleBeam = 512, // 0x00000200 + FixedBeam = 1024, // 0x00000400 + ExternalBeam = 2048, // 0x00000800 + AdaptiveBeam = 4352, // 0x00001100 + } + + internal enum _AEC_SYSTEM_MODE + { + ArrayOnly = 2, + ArrayAndEchoCancellation = 4, + } + } +} diff --git a/src/Microsoft.Kinect/KinectAudioStream.cs b/src/Microsoft.Kinect/KinectAudioStream.cs new file mode 100644 index 0000000..cb0a053 --- /dev/null +++ b/src/Microsoft.Kinect/KinectAudioStream.cs @@ -0,0 +1,475 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.KinectAudioStream +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Microsoft.Kinect +{ + internal class KinectAudioStream : Stream + { + internal const uint DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE = 16777216; + private const uint AUDCLNT_E_DEVICE_INVALIDATED = 2290679812; + internal const uint BufferSizeMilliSeconds = 50; + internal const uint BufferSizeBytes = 1600; + private const uint MinTotalBufferMilliseconds = 1000; + private const uint MaxTotalBufferMilliseconds = 4000; + private const int AdditionalStaleDataToDiscard = 250; + private readonly ManualResetEvent _stopEvent; + private readonly KinectAudioSource _audioSource; + private readonly Stack _writeBufferStack = new Stack(); + private readonly Queue _readBufferQueue = new Queue(); + private readonly object _syncRoot = new object(); + private readonly AutoResetEvent _dataReady = new AutoResetEvent(false); + private bool _started; + private Thread _capturingThread; + private KinectAudioStream.Buffer _currentBuffer; + private int _currentBufferIndex; + private long _bytesRead; + private bool _capturing; + private DateTime _lastRead = DateTime.MinValue; + private readonly TimeSpan _readStaleThreshold; + private Exception _captureException; + + internal KinectAudioStream(KinectAudioSource audioSource, TimeSpan readStaleThreshold) + { + this._audioSource = audioSource; + this._readStaleThreshold = readStaleThreshold; + this._stopEvent = audioSource.NativeWrapper.CreateStreamStopEvent(); + } + + internal void Stop() + { + if (!this._started) + throw new InvalidOperationException(Resources.CaptureNotStarted); + this._stopEvent.Set(); + this._capturingThread.Join(); + } + + public void Start() + { + if (this._started) + throw new InvalidOperationException(Resources.CaptureAlreadyStarted); + this.ResetStaleTracking(); + this._capturingThread = new Thread(new ParameterizedThreadStart(this.RunCapture)); + this._capturingThread.IsBackground = true; + this._capturingThread.SetApartmentState(ApartmentState.MTA); + this._capturingThread.Name = "AudioCaptureThread"; + this._capturingThread.Start((object) null); + this._capturing = true; + this._started = true; + } + + internal void ResetStaleTracking() => this._lastRead = DateTime.UtcNow; + + private static void InitializeMediaObject(IMediaObject mediaObject) + { + WAVEFORMATEX fmt = new WAVEFORMATEX() + { + wFormatTag = 1, + nChannels = 1, + nSamplesPerSec = 16000, + nAvgBytesPerSec = 32000, + nBlockAlign = 2, + wBitsPerSample = 16, + cbSize = 0 + }; + using (DMO_MEDIA_TYPE pmt = new DMO_MEDIA_TYPE()) + { + pmt.majortype = DMO_MEDIA_TYPE.MEDIATYPE_Audio; + pmt.subtype = DMO_MEDIA_TYPE.MEDIASUBTYPE_PCM; + pmt.lSampleSize = 0; + pmt.bFixedSizeSamples = true; + pmt.bTemporalCompression = false; + pmt.formattype = DMO_MEDIA_TYPE.FORMAT_WaveFormatEx; + pmt.SetFormat(fmt); + pmt.cbFormat = Marshal.SizeOf(typeof (WAVEFORMATEX)); + mediaObject.SetOutputType(0, pmt, 0); + } + mediaObject.AllocateStreamingResources(); + } + + internal static uint GetNumBuffersInPool(uint readStaleThresholdMilliseconds) => (uint) Math.Ceiling((double) Math.Min(4000U, Math.Max(1000U, readStaleThresholdMilliseconds)) / 50.0); + + private void RunCapture(object notused) + { + byte[] data = new byte[1600]; + object dmoInstance = this._audioSource.NativeWrapper.CreateDmoInstance(); + IMediaObject mediaObject; + IPropertyStore propertyStore1; + if (dmoInstance is NuiAudioBeam nuiAudioBeam) + { + mediaObject = (IMediaObject) nuiAudioBeam.Wrapped; + propertyStore1 = (IPropertyStore) nuiAudioBeam.Wrapped; + } + else + { + mediaObject = (IMediaObject) dmoInstance; + propertyStore1 = (IPropertyStore) dmoInstance; + } + int taskIndex = 0; + int avrtHandle = NativeMethods.AvSetMmThreadCharacteristics("Audio", ref taskIndex); + uint numBuffersInPool = KinectAudioStream.GetNumBuffersInPool((uint) this._readStaleThreshold.TotalMilliseconds); + for (int index = 0; (long) index < (long) numBuffersInPool; ++index) + this._writeBufferStack.Push(new KinectAudioStream.Buffer(1600U)); + GCHandle handle1 = new GCHandle(); + GCHandle handle2 = new GCHandle(); + IntPtr pUnk = IntPtr.Zero; + bool flag1 = false; + ushort? nullable1 = new ushort?(); + try + { + handle1 = GCHandle.Alloc((object) data, GCHandleType.Pinned); + StaticMediaBuffer o = new StaticMediaBuffer(handle1.AddrOfPinnedObject(), (uint) data.Length); + pUnk = Marshal.GetComInterfaceForObject((object) o, typeof (IMediaBuffer)); + DMO_OUTPUT_DATA_BUFFER outputDataBuffer = new DMO_OUTPUT_DATA_BUFFER() + { + Buffer = pUnk, + Status = 0 + }; + handle2 = GCHandle.Alloc((object) outputDataBuffer, GCHandleType.Pinned); + DMO_OUTPUT_DATA_BUFFER[] pOutputBuffers = new DMO_OUTPUT_DATA_BUFFER[1] + { + outputDataBuffer + }; + KinectAudioStream.AudioAngleTracker audioAngleTracker = new KinectAudioStream.AudioAngleTracker(this._audioSource, dmoInstance as INuiAudioBeam); + KinectAudioStream.BufferManager bufferManager = new KinectAudioStream.BufferManager(this); + bool flag2 = false; +label_28: + if (!flag2) + { + do + { + outputDataBuffer.Status = 0U; + o.Reset((uint) data.Length); + while (!this._stopEvent.WaitOne(0, false)) + { + ushort? nullable2 = nullable1; + if (!(nullable2.HasValue ? new int?((int) nullable2.GetValueOrDefault()) : new int?()).HasValue) + { + nullable1 = this._audioSource.FindMicrophoneIndex(); + ushort? nullable3 = nullable1; + if ((nullable3.HasValue ? new int?((int) nullable3.GetValueOrDefault()) : new int?()).HasValue) + { + this._audioSource.MicrophoneIndex = nullable1.Value; + } + else + { + bufferManager.WriteEmpty(1600U); + Thread.Sleep(50); + } + } + else + break; + } + if (this._stopEvent.WaitOne(10, false)) + { + flag2 = true; + break; + } + this._audioSource.ApplyPendingProperties(propertyStore1); + try + { + if (!flag1) + { + KinectAudioStream.InitializeMediaObject(mediaObject); + flag1 = true; + } + mediaObject.ProcessOutput(0, 1, pOutputBuffers, out int _); + } + catch (COMException ex) + { + if (ex.ErrorCode == -2004287484) + { + nullable1 = new ushort?(); + goto label_27; + } + else + throw; + } + catch (ArgumentException ex) + { + int count = 0; + this._audioSource.NativeWrapper.GetSpeakerDevices((SpeakerDevice[]) null, ref count); + if (this._audioSource.EchoCancellationSpeakerIndex >= count) + { + IPropertyStore propertyStore2 = propertyStore1; + PROPERTYKEY propertykey1 = KinectAudioSource.PropertyKeyFromId(2); + ref PROPERTYKEY local1 = ref propertykey1; + object obj1 = (object) 2; + ref object local2 = ref obj1; + propertyStore2.SetValue(ref local1, ref local2); + IPropertyStore propertyStore3 = propertyStore1; + PROPERTYKEY propertykey2 = KinectAudioSource.PropertyKeyFromId(10); + ref PROPERTYKEY local3 = ref propertykey2; + object obj2 = (object) 0; + ref object local4 = ref obj2; + propertyStore3.SetValue(ref local3, ref local4); + goto label_27; + } + else + throw; + } + uint cbLength; + o.GetBufferAndLength(IntPtr.Zero, out cbLength); + bufferManager.Write(data, cbLength); + audioAngleTracker.TrackAngles(); +label_27:; + } + while (((int) outputDataBuffer.Status & 16777216) != 0); + goto label_28; + } + else + bufferManager.Flush(); + } + catch (COMException ex) + { + this._captureException = (Exception) ex; + } + catch (UnauthorizedAccessException ex) + { + this._captureException = (Exception) ex; + } + catch (Exception ex) + { + this._captureException = (Exception) null; + } + finally + { + this._capturing = false; + this._dataReady.Set(); + KinectAudioStream.SafeFree(handle2); + KinectAudioStream.SafeFree(handle1); + if (pUnk != IntPtr.Zero) + Marshal.Release(pUnk); + this._audioSource.NativeWrapper.DestroyDmoInstance(dmoInstance); + if (avrtHandle != 0) + NativeMethods.AvRevertMmThreadCharacteristics(avrtHandle); + } + } + + internal Queue ReadBufferQueue => this._readBufferQueue; + + private void QueueCapturedBuffer(KinectAudioStream.Buffer capturedBuffer) + { + lock (this._syncRoot) + { + this._readBufferQueue.Enqueue(capturedBuffer); + this._dataReady.Set(); + } + } + + private KinectAudioStream.Buffer GetWriteBuffer() + { + lock (this._syncRoot) + { + if (this._writeBufferStack.Count > 0) + return this._writeBufferStack.Pop(); + if (this._readBufferQueue.Count <= 0) + return (KinectAudioStream.Buffer) null; + KinectAudioStream.Buffer writeBuffer = this._readBufferQueue.Dequeue(); + writeBuffer.DataLength = 0U; + return writeBuffer; + } + } + + private static void SafeFree(GCHandle handle) + { + if (!(handle != new GCHandle())) + return; + handle.Free(); + } + + public override bool CanRead => this._started; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override void Flush() => throw new InvalidOperationException(Resources.NotSupported); + + public override long Length => -1; + + public override long Position + { + get => this._bytesRead; + set => throw new InvalidOperationException(Resources.NotSupported); + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (this._captureException != null) + throw this._captureException; + if (DateTime.UtcNow - this._lastRead > this._readStaleThreshold) + { + Thread.Sleep(250); + this.ReleaseAllBuffers(); + } + this.ResetStaleTracking(); + int num = 0; + while (count > 0 && this._capturing) + { + lock (this._syncRoot) + { + if (this._currentBuffer == null && this._readBufferQueue.Count != 0) + { + this._currentBuffer = this._readBufferQueue.Dequeue(); + this._currentBufferIndex = 0; + } + if (this._currentBuffer != null) + { + int length = (int) Math.Min((long) this._currentBuffer.DataLength - (long) this._currentBufferIndex, (long) count); + Array.Copy((Array) this._currentBuffer.Data, this._currentBufferIndex, (Array) buffer, offset, length); + count -= length; + offset += length; + num += length; + this._currentBufferIndex += length; + if ((long) this._currentBufferIndex >= (long) this._currentBuffer.DataLength) + { + this.ReleaseBuffer(this._currentBuffer); + this._currentBuffer = this._readBufferQueue.Count != 0 ? this._readBufferQueue.Dequeue() : (KinectAudioStream.Buffer) null; + this._currentBufferIndex = 0; + } + } + } + if (this._currentBuffer == null && count > 0) + this._dataReady.WaitOne(-1, false); + } + this._bytesRead += (long) num; + return num; + } + + private void ReleaseBuffer(KinectAudioStream.Buffer buffer) + { + buffer.DataLength = 0U; + this._writeBufferStack.Push(buffer); + } + + private void ReleaseAllBuffers() + { + lock (this._syncRoot) + { + while (this._readBufferQueue.Count > 0) + this.ReleaseBuffer(this._readBufferQueue.Dequeue()); + if (this._currentBuffer != null) + this.ReleaseBuffer(this._currentBuffer); + this._currentBufferIndex = 0; + this._currentBuffer = (KinectAudioStream.Buffer) null; + } + } + + public override long Seek(long offset, SeekOrigin origin) => this._bytesRead + offset; + + public override void SetLength(long value) => throw new InvalidOperationException(Resources.NotSupported); + + public override void Write(byte[] buffer, int offset, int count) => throw new InvalidOperationException(Resources.NotSupported); + + public override void Close() + { + base.Close(); + this.Stop(); + } + + internal class Buffer + { + public Buffer(uint size) => this.Data = new byte[size]; + + public uint DataLength { get; set; } + + public byte[] Data { get; private set; } + } + + internal class AudioAngleTracker + { + private double _lastAngle = double.MinValue; + private double _lastSoundSourceAngle = double.MinValue; + private double _lastSoundSourceConfidence = double.MinValue; + private readonly KinectAudioSource _audioSource; + private readonly INuiAudioBeam _audioBeam; + + internal AudioAngleTracker(KinectAudioSource audioSource, INuiAudioBeam audioBeam) + { + this._audioSource = audioSource; + this._audioBeam = audioBeam; + } + + internal void TrackAngles() + { + bool flag = false; + if (this._audioSource.BeamAngleMode == BeamAngleMode.Manual) + { + double angle = this._audioSource.FetchNextBeamAngle(); + if (angle > double.MinValue) + { + this._audioBeam.SetBeam(angle); + flag = true; + } + } + if (this._audioSource.BeamAngleMode == BeamAngleMode.Automatic || this._audioSource.BeamAngleMode == BeamAngleMode.Adaptive || flag) + { + double angle = 0.0; + this._audioBeam.GetBeam(out angle); + if (Math.Abs(angle - this._lastAngle) > double.Epsilon) + { + this._lastAngle = angle; + this._audioSource.SetBeamAngle(angle); + } + } + double angle1; + double confidence; + this._audioBeam.GetPosition(out angle1, out confidence); + if (Math.Abs(angle1 - this._lastSoundSourceAngle) <= double.Epsilon && Math.Abs(confidence - this._lastSoundSourceConfidence) <= double.Epsilon) + return; + this._audioSource.SetSoundSourceAngleAndConfidence(angle1, confidence); + this._lastSoundSourceAngle = angle1; + this._lastSoundSourceConfidence = confidence; + } + } + + internal class BufferManager + { + private KinectAudioStream.Buffer _writeBuf; + private readonly KinectAudioStream _stream; + + internal BufferManager(KinectAudioStream stream) => this._stream = stream; + + internal void Write(byte[] data, uint length) => this.WriteHelper(length, (Action) (destIndex => Array.Copy((Array) data, 0L, (Array) this._writeBuf.Data, (long) destIndex, (long) length))); + + internal void WriteEmpty(uint length) => this.WriteHelper(length, (Action) (destIndex => Array.Clear((Array) this._writeBuf.Data, (int) destIndex, (int) length))); + + private void WriteHelper(uint length, Action writeAction) + { + if (length <= 0U) + return; + if (this._writeBuf == null) + this._writeBuf = this._stream.GetWriteBuffer(); + if ((long) (this._writeBuf.DataLength + length) < (long) this._writeBuf.Data.Length) + { + writeAction(this._writeBuf.DataLength); + this._writeBuf.DataLength += length; + } + else + { + this._stream.QueueCapturedBuffer(this._writeBuf); + this._writeBuf = this._stream.GetWriteBuffer(); + writeAction(0U); + this._writeBuf.DataLength = length; + } + } + + internal void Flush() + { + if (this._writeBuf == null) + return; + this._stream.QueueCapturedBuffer(this._writeBuf); + this._writeBuf = (KinectAudioStream.Buffer) null; + } + } + } +} diff --git a/src/Microsoft.Kinect/KinectEtwProvider.cs b/src/Microsoft.Kinect/KinectEtwProvider.cs new file mode 100644 index 0000000..67eeeb0 --- /dev/null +++ b/src/Microsoft.Kinect/KinectEtwProvider.cs @@ -0,0 +1,527 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.KinectEtwProvider +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Diagnostics.Eventing; + +namespace Microsoft.Kinect +{ + internal static class KinectEtwProvider + { + private static readonly EventProviderVersionTwo Provider = new EventProviderVersionTwo(); + private static EventDescriptor getSegmentationBegin = new EventDescriptor(0, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 1, long.MinValue); + private static EventDescriptor getSegmentationEnd = new EventDescriptor(1, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 1, long.MinValue); + private static EventDescriptor processInputBufferBegin = new EventDescriptor(2, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 2, long.MinValue); + private static EventDescriptor processInputBufferEnd = new EventDescriptor(3, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 2, long.MinValue); + private static EventDescriptor notifyFrameReadyStart = new EventDescriptor(4, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 3, long.MinValue); + private static EventDescriptor notifyFrameReadyEnd = new EventDescriptor(5, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 3, long.MinValue); + private static EventDescriptor processFrameStart = new EventDescriptor(6, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 4, long.MinValue); + private static EventDescriptor processFrameEnd = new EventDescriptor(7, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 4, long.MinValue); + private static EventDescriptor getSkeletonsBegin = new EventDescriptor(8, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 5, long.MinValue); + private static EventDescriptor getSkeletonsEnd = new EventDescriptor(9, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 5, long.MinValue); + private static EventDescriptor unpackBayerStart = new EventDescriptor(10, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 6, long.MinValue); + private static EventDescriptor unpackBayerEnd = new EventDescriptor(11, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 6, long.MinValue); + private static EventDescriptor frameStart = new EventDescriptor(12, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 7, long.MinValue); + private static EventDescriptor frameEnd = new EventDescriptor(13, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 7, long.MinValue); + private static EventDescriptor mapDepthFrameToColorFrameStart = new EventDescriptor(14, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 8, long.MinValue); + private static EventDescriptor mapDepthFrameToColorFrameEnd = new EventDescriptor(15, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 8, long.MinValue); + private static EventDescriptor mapDepthToColorImagePointStart = new EventDescriptor(16, (byte) 0, (byte) 16, (byte) 5, (byte) 1, 9, long.MinValue); + private static EventDescriptor mapDepthToColorImagePointEnd = new EventDescriptor(17, (byte) 0, (byte) 16, (byte) 5, (byte) 2, 9, long.MinValue); + private static EventDescriptor mapSkeletonPointToColorStart = new EventDescriptor(18, (byte) 0, (byte) 16, (byte) 5, (byte) 1, 10, long.MinValue); + private static EventDescriptor mapSkeletonPointToColorEnd = new EventDescriptor(19, (byte) 0, (byte) 16, (byte) 5, (byte) 2, 10, long.MinValue); + private static EventDescriptor mapSkeletonPointToDepthStart = new EventDescriptor(20, (byte) 0, (byte) 16, (byte) 5, (byte) 1, 11, long.MinValue); + private static EventDescriptor mapSkeletonPointToDepthEnd = new EventDescriptor(21, (byte) 0, (byte) 16, (byte) 5, (byte) 2, 11, long.MinValue); + private static EventDescriptor mapDepthToSkeletonPointStart = new EventDescriptor(22, (byte) 0, (byte) 16, (byte) 5, (byte) 1, 12, long.MinValue); + private static EventDescriptor mapDepthToSkeletonPointEnd = new EventDescriptor(23, (byte) 0, (byte) 16, (byte) 5, (byte) 2, 12, long.MinValue); + private static EventDescriptor managedNuiTransformDepthImageToSkeletonStart = new EventDescriptor(24, (byte) 0, (byte) 16, (byte) 5, (byte) 1, 13, long.MinValue); + private static EventDescriptor managedNuiTransformDepthImageToSkeletonEnd = new EventDescriptor(25, (byte) 0, (byte) 16, (byte) 5, (byte) 2, 13, long.MinValue); + private static EventDescriptor managedNuiTransformSkeletonToDepthImageStart = new EventDescriptor(26, (byte) 0, (byte) 16, (byte) 5, (byte) 1, 14, long.MinValue); + private static EventDescriptor managedNuiTransformSkeletonToDepthImageEnd = new EventDescriptor(27, (byte) 0, (byte) 16, (byte) 5, (byte) 2, 14, long.MinValue); + private static EventDescriptor nuiImageGetColorPixelCoordinatesFromDepthPixelAtResolutionStart = new EventDescriptor(28, (byte) 0, (byte) 16, (byte) 5, (byte) 1, 15, long.MinValue); + private static EventDescriptor nuiImageGetColorPixelCoordinatesFromDepthPixelAtResolutionEnd = new EventDescriptor(29, (byte) 0, (byte) 16, (byte) 5, (byte) 2, 15, long.MinValue); + private static EventDescriptor nuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolutionStart = new EventDescriptor(30, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 16, long.MinValue); + private static EventDescriptor nuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolutionEnd = new EventDescriptor(31, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 16, long.MinValue); + private static EventDescriptor nuiImageStreamOpenStart = new EventDescriptor(32, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 17, long.MinValue); + private static EventDescriptor nuiImageStreamOpenEnd = new EventDescriptor(33, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 17, long.MinValue); + private static EventDescriptor nuiImageStreamGetNextFrameStart = new EventDescriptor(34, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 18, long.MinValue); + private static EventDescriptor nuiImageStreamGetNextFrameEnd = new EventDescriptor(35, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 18, long.MinValue); + private static EventDescriptor nuiImageStreamReleaseFrameStart = new EventDescriptor(36, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 19, long.MinValue); + private static EventDescriptor nuiImageStreamReleaseFrameEnd = new EventDescriptor(37, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 19, long.MinValue); + private static EventDescriptor nuiInitializeStart = new EventDescriptor(38, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 20, long.MinValue); + private static EventDescriptor nuiInitializeEnd = new EventDescriptor(39, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 20, long.MinValue); + private static EventDescriptor allFramesReady = new EventDescriptor(40, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 21, long.MinValue); + private static EventDescriptor colorFrameReady = new EventDescriptor(41, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 22, long.MinValue); + private static EventDescriptor depthFrameReady = new EventDescriptor(42, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 23, long.MinValue); + private static EventDescriptor skeletonFrameReady = new EventDescriptor(43, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 24, long.MinValue); + private static EventDescriptor stopDeviceStart = new EventDescriptor(44, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 25, long.MinValue); + private static EventDescriptor stopDeviceEnd = new EventDescriptor(45, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 25, long.MinValue); + private static EventDescriptor singleStreamStopStart = new EventDescriptor(46, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 26, long.MinValue); + private static EventDescriptor singleStreamStopEnd = new EventDescriptor(47, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 26, long.MinValue); + private static EventDescriptor detectGenuineDeviceStart = new EventDescriptor(48, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 27, long.MinValue); + private static EventDescriptor detectGenuineDeviceEnd = new EventDescriptor(49, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 27, long.MinValue); + private static EventDescriptor createDeviceStart = new EventDescriptor(50, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 28, long.MinValue); + private static EventDescriptor createDeviceEnd = new EventDescriptor(51, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 28, long.MinValue); + private static EventDescriptor reEnumerateDevicesStart = new EventDescriptor(52, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 29, long.MinValue); + private static EventDescriptor reEnumerateDevicesEnd = new EventDescriptor(53, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 29, long.MinValue); + private static EventDescriptor outputStreamInitStart = new EventDescriptor(54, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 30, long.MinValue); + private static EventDescriptor outputStreamInitEnd = new EventDescriptor(55, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 30, long.MinValue); + private static EventDescriptor singleStreamStartStart = new EventDescriptor(56, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 31, long.MinValue); + private static EventDescriptor singleStreamStartEnd = new EventDescriptor(57, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 31, long.MinValue); + private static EventDescriptor skeletalTrackerInitializeStart = new EventDescriptor(58, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 32, long.MinValue); + private static EventDescriptor skeletalTrackerInitializeEnd = new EventDescriptor(59, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 32, long.MinValue); + private static EventDescriptor kinectSensorInitializeStart = new EventDescriptor(60, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 33, long.MinValue); + private static EventDescriptor kinectSensorInitializeEnd = new EventDescriptor(61, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 33, long.MinValue); + private static EventDescriptor skeletonStageBGRStart = new EventDescriptor(62, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 34, long.MinValue); + private static EventDescriptor skeletonStageBGREnd = new EventDescriptor(63, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 34, long.MinValue); + private static EventDescriptor skeletonStageCDRPStart = new EventDescriptor(64, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 35, long.MinValue); + private static EventDescriptor skeletonStageCDRPEnd = new EventDescriptor(65, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 35, long.MinValue); + private static EventDescriptor skeletonStageHeadDetectorStart = new EventDescriptor(66, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 36, long.MinValue); + private static EventDescriptor skeletonStageHeadDetectorEnd = new EventDescriptor(67, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 36, long.MinValue); + private static EventDescriptor skeletonStageExemplarStart = new EventDescriptor(68, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 37, long.MinValue); + private static EventDescriptor skeletonStageExemplarEnd = new EventDescriptor(69, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 37, long.MinValue); + private static EventDescriptor skeletonStageCentroidsStart = new EventDescriptor(70, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 38, long.MinValue); + private static EventDescriptor skeletonStageCentroidsEnd = new EventDescriptor(71, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 38, long.MinValue); + private static EventDescriptor skeletonStageModelFittingStart = new EventDescriptor(72, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 39, long.MinValue); + private static EventDescriptor skeletonStageModelFittingEnd = new EventDescriptor(73, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 39, long.MinValue); + private static EventDescriptor frameRequestDropped = new EventDescriptor(74, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 40, long.MinValue); + private static EventDescriptor unexpectedFrameRequestError = new EventDescriptor(75, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 41, long.MinValue); + private static EventDescriptor frameStateChanged = new EventDescriptor(76, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 42, long.MinValue); + private static EventDescriptor frameDropped = new EventDescriptor(77, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 43, long.MinValue); + private static EventDescriptor nuiInitializeInfo = new EventDescriptor(85, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 20, -9223372036854775807L); + private static EventDescriptor nuiImageStreamOpenInfo = new EventDescriptor(86, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 17, -9223372036854775807L); + private static EventDescriptor nuiShutdownTrace = new EventDescriptor(87, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 44, -9223372036854775807L); + private static EventDescriptor internalNuiShutdownTrace = new EventDescriptor(88, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 45, -9223372036854775807L); + private static EventDescriptor nuiSkeletonTrackingEnableTrace = new EventDescriptor(89, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 55, -9223372036854775807L); + private static EventDescriptor nuiSkeletonTrackingDisableTrace = new EventDescriptor(90, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 56, -9223372036854775807L); + private static EventDescriptor nuiTransformSmoothInfo = new EventDescriptor(91, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 47, -9223372036854775807L); + private static EventDescriptor nuiSkeletonSetTrackedSkeletonsInfo = new EventDescriptor(92, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 57, -9223372036854775807L); + private static EventDescriptor nuiSetFrameEndEventInfo = new EventDescriptor(93, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 48, -9223372036854775807L); + private static EventDescriptor nuiImageStreamGetNextFrameInfo = new EventDescriptor(94, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 18, -9223372036854775807L); + private static EventDescriptor nuiSkeletonGetNextFrameInfo = new EventDescriptor(95, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 49, -9223372036854775807L); + private static EventDescriptor nuiDeviceConnectionIdInfo = new EventDescriptor(97, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 50, -9223372036854775807L); + private static EventDescriptor nuiUniqueIdInfo = new EventDescriptor(96, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 51, -9223372036854775807L); + private static EventDescriptor nuiCreateSensorByIndexInfo = new EventDescriptor(98, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 52, -9223372036854775807L); + private static EventDescriptor nuiCreateSensorByIdInfo = new EventDescriptor(99, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 53, -9223372036854775807L); + private static EventDescriptor nuiImageStreamSetImageFrameFlagsInfo = new EventDescriptor(100, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 54, -9223372036854775807L); + private static EventDescriptor nuiAudioBeamGetBeamInfo = new EventDescriptor(101, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 58, -9223372036854775807L); + private static EventDescriptor nuiAudioBeamGetPositionInfo = new EventDescriptor(102, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 59, -9223372036854775807L); + private static EventDescriptor nuiAudioBeamSetBeamInfo = new EventDescriptor(103, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 60, -9223372036854775807L); + private static EventDescriptor nuiGetAudioSourceInfo = new EventDescriptor(104, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 61, -9223372036854775807L); + private static EventDescriptor audioDmoSetPropertyInfo = new EventDescriptor(105, (byte) 0, (byte) 16, (byte) 4, (byte) 0, 65, -9223372036854775807L); + private static EventDescriptor managedKinectSensorStartInfo = new EventDescriptor(106, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 66, -9223372036854775807L); + private static EventDescriptor managedImageStreamDisabledInfo = new EventDescriptor(107, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 67, -9223372036854775807L); + private static EventDescriptor managedFrameReadyEventAddedInfo = new EventDescriptor(108, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 68, -9223372036854775807L); + private static EventDescriptor managedFrameReadyEventRemovedInfo = new EventDescriptor(109, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 69, -9223372036854775807L); + private static EventDescriptor managedOpenNextFrameInfo = new EventDescriptor(110, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 70, -9223372036854775807L); + private static EventDescriptor managedOpenFrameFromEventInfo = new EventDescriptor(111, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 71, -9223372036854775807L); + private static EventDescriptor managedOpenFrameFromAllFramesEventInfo = new EventDescriptor(112, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 72, -9223372036854775807L); + private static EventDescriptor managedAllFramesReadyEventAddedInfo = new EventDescriptor(113, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 73, -9223372036854775807L); + private static EventDescriptor managedAllFramesReadyEventRemovedInfo = new EventDescriptor(114, (byte) 0, (byte) 16, (byte) 5, (byte) 0, 74, -9223372036854775807L); + private static EventDescriptor mapColorFrameToDepthFrameStart = new EventDescriptor(115, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 75, long.MinValue); + private static EventDescriptor mapColorFrameToDepthFrameEnd = new EventDescriptor(116, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 75, long.MinValue); + private static EventDescriptor mapColorFrameToDepthFrame_InterpolateGapsStart = new EventDescriptor(117, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 76, long.MinValue); + private static EventDescriptor mapColorFrameToDepthFrame_InterpolateGapsEnd = new EventDescriptor(118, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 76, long.MinValue); + private static EventDescriptor mapColorFrameToSkeletonFrameStart = new EventDescriptor(119, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 77, long.MinValue); + private static EventDescriptor mapColorFrameToSkeletonFrameEnd = new EventDescriptor(120, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 77, long.MinValue); + private static EventDescriptor mapDepthFrameToSkeletonFrameStart = new EventDescriptor(121, (byte) 0, (byte) 16, (byte) 4, (byte) 1, 78, long.MinValue); + private static EventDescriptor mapDepthFrameToSkeletonFrameEnd = new EventDescriptor(122, (byte) 0, (byte) 16, (byte) 4, (byte) 2, 78, long.MinValue); + + public static bool EventWriteGetSegmentationBegin( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.getSegmentationBegin, streamId, width, height, frameNumber); + } + + public static bool EventWriteGetSegmentationEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.getSegmentationEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteProcessInputBufferBegin() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.processInputBufferBegin); + + public static bool EventWriteProcessInputBufferEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.processInputBufferEnd); + + public static bool EventWriteNotifyFrameReadyStart( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.notifyFrameReadyStart, streamId, width, height, frameNumber); + } + + public static bool EventWriteNotifyFrameReadyEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.notifyFrameReadyEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteProcessFrameStart(IntPtr frameOverlapId, uint streamId) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateProcessFrameData(ref KinectEtwProvider.processFrameStart, frameOverlapId, streamId); + + public static bool EventWriteProcessFrameEnd(IntPtr frameOverlapId, uint streamId) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateProcessFrameData(ref KinectEtwProvider.processFrameEnd, frameOverlapId, streamId); + + public static bool EventWriteGetSkeletonsBegin( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.getSkeletonsBegin, streamId, width, height, frameNumber); + } + + public static bool EventWriteGetSkeletonsEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.getSkeletonsEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteUnpackBayerStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.unpackBayerStart); + + public static bool EventWriteUnpackBayerEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.unpackBayerEnd); + + public static bool EventWriteFrameStart(uint streamType, int bufferIndex, int frameNumber) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameLifecycleData(ref KinectEtwProvider.frameStart, streamType, bufferIndex, frameNumber); + + public static bool EventWriteFrameEnd(uint streamType, int bufferIndex, int frameNumber) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameLifecycleData(ref KinectEtwProvider.frameEnd, streamType, bufferIndex, frameNumber); + + public static bool EventWriteMapDepthFrameToColorFrameStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthFrameToColorFrameStart); + + public static bool EventWriteMapDepthFrameToColorFrameEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthFrameToColorFrameEnd); + + public static bool EventWriteMapDepthToColorImagePointStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthToColorImagePointStart); + + public static bool EventWriteMapDepthToColorImagePointEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthToColorImagePointEnd); + + public static bool EventWriteMapSkeletonPointToColorStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapSkeletonPointToColorStart); + + public static bool EventWriteMapSkeletonPointToColorEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapSkeletonPointToColorEnd); + + public static bool EventWriteMapSkeletonPointToDepthStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapSkeletonPointToDepthStart); + + public static bool EventWriteMapSkeletonPointToDepthEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapSkeletonPointToDepthEnd); + + public static bool EventWriteMapDepthToSkeletonPointStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthToSkeletonPointStart); + + public static bool EventWriteMapDepthToSkeletonPointEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthToSkeletonPointEnd); + + public static bool EventWriteManagedNuiTransformDepthImageToSkeletonStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.managedNuiTransformDepthImageToSkeletonStart); + + public static bool EventWriteManagedNuiTransformDepthImageToSkeletonEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.managedNuiTransformDepthImageToSkeletonEnd); + + public static bool EventWriteManagedNuiTransformSkeletonToDepthImageStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.managedNuiTransformSkeletonToDepthImageStart); + + public static bool EventWriteManagedNuiTransformSkeletonToDepthImageEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.managedNuiTransformSkeletonToDepthImageEnd); + + public static bool EventWriteNuiImageGetColorPixelCoordinatesFromDepthPixelAtResolutionStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageGetColorPixelCoordinatesFromDepthPixelAtResolutionStart); + + public static bool EventWriteNuiImageGetColorPixelCoordinatesFromDepthPixelAtResolutionEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageGetColorPixelCoordinatesFromDepthPixelAtResolutionEnd); + + public static bool EventWriteNuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolutionStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolutionStart); + + public static bool EventWriteNuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolutionEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolutionEnd); + + public static bool EventWriteNuiImageStreamOpenStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageStreamOpenStart); + + public static bool EventWriteNuiImageStreamOpenEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageStreamOpenEnd); + + public static bool EventWriteNuiImageStreamGetNextFrameStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageStreamGetNextFrameStart); + + public static bool EventWriteNuiImageStreamGetNextFrameEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageStreamGetNextFrameEnd); + + public static bool EventWriteNuiImageStreamReleaseFrameStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageStreamReleaseFrameStart); + + public static bool EventWriteNuiImageStreamReleaseFrameEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiImageStreamReleaseFrameEnd); + + public static bool EventWriteNuiInitializeStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiInitializeStart); + + public static bool EventWriteNuiInitializeEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiInitializeEnd); + + public static bool EventWriteAllFramesReady( + long colorFrameTimestamp, + long depthFrameTimestamp, + long skeletonFrameTimestamp) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateAllFramesReadyData(ref KinectEtwProvider.allFramesReady, colorFrameTimestamp, depthFrameTimestamp, skeletonFrameTimestamp); + } + + public static bool EventWriteColorFrameReady(long timestamp) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameReadyData(ref KinectEtwProvider.colorFrameReady, timestamp); + + public static bool EventWriteDepthFrameReady(long timestamp) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameReadyData(ref KinectEtwProvider.depthFrameReady, timestamp); + + public static bool EventWriteSkeletonFrameReady(long timestamp) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameReadyData(ref KinectEtwProvider.skeletonFrameReady, timestamp); + + public static bool EventWriteStopDeviceStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.stopDeviceStart); + + public static bool EventWriteStopDeviceEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.stopDeviceEnd); + + public static bool EventWriteSingleStreamStopStart(uint streamType) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateStreamTypeOnly(ref KinectEtwProvider.singleStreamStopStart, streamType); + + public static bool EventWriteSingleStreamStopEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.singleStreamStopEnd); + + public static bool EventWriteDetectGenuineDeviceStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.detectGenuineDeviceStart); + + public static bool EventWriteDetectGenuineDeviceEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.detectGenuineDeviceEnd); + + public static bool EventWriteCreateDeviceStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.createDeviceStart); + + public static bool EventWriteCreateDeviceEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.createDeviceEnd); + + public static bool EventWriteReEnumerateDevicesStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.reEnumerateDevicesStart); + + public static bool EventWriteReEnumerateDevicesEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.reEnumerateDevicesEnd); + + public static bool EventWriteOutputStreamInitStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.outputStreamInitStart); + + public static bool EventWriteOutputStreamInitEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.outputStreamInitEnd); + + public static bool EventWriteSingleStreamStartStart(uint streamType) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateStreamTypeOnly(ref KinectEtwProvider.singleStreamStartStart, streamType); + + public static bool EventWriteSingleStreamStartEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.singleStreamStartEnd); + + public static bool EventWriteSkeletalTrackerInitializeStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.skeletalTrackerInitializeStart); + + public static bool EventWriteSkeletalTrackerInitializeEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.skeletalTrackerInitializeEnd); + + public static bool EventWriteKinectSensorInitializeStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.kinectSensorInitializeStart); + + public static bool EventWriteKinectSensorInitializeEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.kinectSensorInitializeEnd); + + public static bool EventWriteSkeletonStageBGRStart( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageBGRStart, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageBGREnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageBGREnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageCDRPStart( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageCDRPStart, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageCDRPEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageCDRPEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageHeadDetectorStart( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageHeadDetectorStart, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageHeadDetectorEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageHeadDetectorEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageExemplarStart( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageExemplarStart, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageExemplarEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageExemplarEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageCentroidsStart( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageCentroidsStart, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageCentroidsEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageCentroidsEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageModelFittingStart( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageModelFittingStart, streamId, width, height, frameNumber); + } + + public static bool EventWriteSkeletonStageModelFittingEnd( + uint streamId, + ulong width, + ulong height, + ulong frameNumber) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameData(ref KinectEtwProvider.skeletonStageModelFittingEnd, streamId, width, height, frameNumber); + } + + public static bool EventWriteFrameRequestDropped() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.frameRequestDropped); + + public static bool EventWriteUnexpectedFrameRequestError() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.unexpectedFrameRequestError); + + public static bool EventWriteFrameStateChanged(uint streamType, int frameNumber, uint state) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameStateData(ref KinectEtwProvider.frameStateChanged, streamType, frameNumber, state); + + public static bool EventWriteFrameDropped(uint streamType, int frameNumber) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateFrameDroppedData(ref KinectEtwProvider.frameDropped, streamType, frameNumber); + + public static bool EventWriteNuiInitializeInfo(string deviceId, string processName, uint flags) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiInitializeData(ref KinectEtwProvider.nuiInitializeInfo, deviceId, processName, flags); + + public static bool EventWriteNuiImageStreamOpenInfo( + IntPtr hStream, + uint imageType, + uint imageResolution, + uint imageFrameFlags, + IntPtr hNextFrameEvent) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiImageStreamOpenData(ref KinectEtwProvider.nuiImageStreamOpenInfo, hStream, imageType, imageResolution, imageFrameFlags, hNextFrameEvent); + } + + public static bool EventWriteNuiShutdownTrace() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiShutdownTrace); + + public static bool EventWriteInternalNuiShutdownTrace() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.internalNuiShutdownTrace); + + public static bool EventWriteNuiSkeletonTrackingEnableTrace( + IntPtr hNextFrameEvent, + uint dwFlags) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiSkeletonTrackingData(ref KinectEtwProvider.nuiSkeletonTrackingEnableTrace, hNextFrameEvent, dwFlags); + } + + public static bool EventWriteNuiSkeletonTrackingDisableTrace() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiSkeletonTrackingDisableTrace); + + public static bool EventWriteNuiTransformSmoothInfo( + float smoothing, + float correction, + float prediction, + float jitterRadius, + float maxDeviationRadius) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiTransformSmoothParams(ref KinectEtwProvider.nuiTransformSmoothInfo, smoothing, correction, prediction, jitterRadius, maxDeviationRadius); + } + + public static bool EventWriteNuiSkeletonSetTrackedSkeletonsInfo(uint skeleton1, uint skeleton2) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiSkeletonSetTrackedSkeletonsData(ref KinectEtwProvider.nuiSkeletonSetTrackedSkeletonsInfo, skeleton1, skeleton2); + + public static bool EventWriteNuiSetFrameEndEventInfo(IntPtr hEvent, uint dwFrameEventFlag) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiSetFrameEndEventData(ref KinectEtwProvider.nuiSetFrameEndEventInfo, hEvent, dwFrameEventFlag); + + public static bool EventWriteNuiImageStreamGetNextFrameInfo( + IntPtr hStream, + uint dwMillisecondsToWait) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiImageStreamGetNextFrameData(ref KinectEtwProvider.nuiImageStreamGetNextFrameInfo, hStream, dwMillisecondsToWait); + } + + public static bool EventWriteNuiSkeletonGetNextFrameInfo(uint dwMillisecondsToWait) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiSkeletonGetNextFrameData(ref KinectEtwProvider.nuiSkeletonGetNextFrameInfo, dwMillisecondsToWait); + + public static bool EventWriteNuiDeviceConnectionIdInfo(string kinectId) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateKinectIdStringData(ref KinectEtwProvider.nuiDeviceConnectionIdInfo, kinectId); + + public static bool EventWriteNuiUniqueIdInfo(string kinectId) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateKinectIdStringData(ref KinectEtwProvider.nuiUniqueIdInfo, kinectId); + + public static bool EventWriteNuiCreateSensorByIndexInfo(int index) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiCreateSensorByIndexData(ref KinectEtwProvider.nuiCreateSensorByIndexInfo, index); + + public static bool EventWriteNuiCreateSensorByIdInfo(string strInstanceId) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiCreateSensorByIdData(ref KinectEtwProvider.nuiCreateSensorByIdInfo, strInstanceId); + + public static bool EventWriteNuiImageStreamSetImageFrameFlagsInfo( + IntPtr hStream, + uint dwImageFrameFlags) + { + return !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateNuiImageStreamSetImageFrameFlagsData(ref KinectEtwProvider.nuiImageStreamSetImageFrameFlagsInfo, hStream, dwImageFrameFlags); + } + + public static bool EventWriteNuiAudioBeamGetBeamInfo(double dAngle) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateAudioAngleData(ref KinectEtwProvider.nuiAudioBeamGetBeamInfo, dAngle); + + public static bool EventWriteNuiAudioBeamGetPositionInfo(double dAngle) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateAudioAngleData(ref KinectEtwProvider.nuiAudioBeamGetPositionInfo, dAngle); + + public static bool EventWriteNuiAudioBeamSetBeamInfo(double dAngle) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateAudioAngleData(ref KinectEtwProvider.nuiAudioBeamSetBeamInfo, dAngle); + + public static bool EventWriteNuiGetAudioSourceInfo() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.nuiGetAudioSourceInfo); + + public static bool EventWriteAudioDmoSetPropertyInfo(uint pid, uint value) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateAudioPropertyData(ref KinectEtwProvider.audioDmoSetPropertyInfo, pid, value); + + public static bool EventWriteManagedKinectSensorStartInfo(string deviceID) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateKinectSensorStartData(ref KinectEtwProvider.managedKinectSensorStartInfo, deviceID); + + public static bool EventWriteManagedImageStreamDisabledInfo(int type) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateManagedImageStreamData(ref KinectEtwProvider.managedImageStreamDisabledInfo, type); + + public static bool EventWriteManagedFrameReadyEventAddedInfo(int type) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateManagedFramesReadyRegistrationData(ref KinectEtwProvider.managedFrameReadyEventAddedInfo, type); + + public static bool EventWriteManagedFrameReadyEventRemovedInfo(int type) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateManagedFramesReadyRegistrationData(ref KinectEtwProvider.managedFrameReadyEventRemovedInfo, type); + + public static bool EventWriteManagedOpenNextFrameInfo(int streamType, int millisecondsWait) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateManagedOpenNextFrameData(ref KinectEtwProvider.managedOpenNextFrameInfo, streamType, millisecondsWait); + + public static bool EventWriteManagedOpenFrameFromEventInfo(int type) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateManagedImageStreamData(ref KinectEtwProvider.managedOpenFrameFromEventInfo, type); + + public static bool EventWriteManagedOpenFrameFromAllFramesEventInfo(int type) => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateManagedImageStreamData(ref KinectEtwProvider.managedOpenFrameFromAllFramesEventInfo, type); + + public static bool EventWriteManagedAllFramesReadyEventAddedInfo() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.managedAllFramesReadyEventAddedInfo); + + public static bool EventWriteManagedAllFramesReadyEventRemovedInfo() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.managedAllFramesReadyEventRemovedInfo); + + public static bool EventWriteMapColorFrameToDepthFrameStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapColorFrameToDepthFrameStart); + + public static bool EventWriteMapColorFrameToDepthFrameEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapColorFrameToDepthFrameEnd); + + public static bool EventWriteMapColorFrameToDepthFrame_InterpolateGapsStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapColorFrameToDepthFrame_InterpolateGapsStart); + + public static bool EventWriteMapColorFrameToDepthFrame_InterpolateGapsEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapColorFrameToDepthFrame_InterpolateGapsEnd); + + public static bool EventWriteMapColorFrameToSkeletonFrameStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapColorFrameToSkeletonFrameStart); + + public static bool EventWriteMapColorFrameToSkeletonFrameEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapColorFrameToSkeletonFrameEnd); + + public static bool EventWriteMapDepthFrameToSkeletonFrameStart() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthFrameToSkeletonFrameStart); + + public static bool EventWriteMapDepthFrameToSkeletonFrameEnd() => !KinectEtwProvider.Provider.IsEnabled() || KinectEtwProvider.Provider.TemplateEventDescriptor(ref KinectEtwProvider.mapDepthFrameToSkeletonFrameEnd); + } +} diff --git a/src/Microsoft.Kinect/KinectExceptionHelper.cs b/src/Microsoft.Kinect/KinectExceptionHelper.cs new file mode 100644 index 0000000..2554d87 --- /dev/null +++ b/src/Microsoft.Kinect/KinectExceptionHelper.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.KinectExceptionHelper +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + internal static class KinectExceptionHelper + { + private const int E_NUI_HARDWARE_FEATURE_UNAVAILABLE = -2097086449; + private const int E_NUI_NOTGENUINE = -2097086458; + private const int E_NUI_NOTSUPPORTED = -2097086456; + private const int E_NUI_BADINDEX = -2097085051; + private const int E_WIN32_ERROR_REQUEST_ABORTED = -2147023661; + private const int E_NUI_DEVICE_IN_USE = -2097086455; + + internal static void CheckHr(int hr) + { + if (hr >= 0) + return; + switch (hr) + { + case -2147023661: + throw new UnauthorizedAccessException(Resources.UnauthorizedAccess); + case -2097086458: + throw new InvalidOperationException(Resources.DeviceNotGenuine); + case -2097086456: + throw new InvalidOperationException(Resources.DeviceNotSupported); + case -2097086455: + throw new IOException(Resources.KinectInUse); + case -2097086449: + throw new InvalidOperationException(Resources.HardwareFeatureUnavailable); + case -2097085051: + throw new InvalidOperationException(Resources.BadIndex); + default: + Exception exceptionForHr = Marshal.GetExceptionForHR(hr); + if (exceptionForHr == null) + break; + throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.InvariantCulture, Resources.GenericException, (object) hr), exceptionForHr); + } + } + } +} diff --git a/src/Microsoft.Kinect/KinectSensor.cs b/src/Microsoft.Kinect/KinectSensor.cs new file mode 100644 index 0000000..ac08e26 --- /dev/null +++ b/src/Microsoft.Kinect/KinectSensor.cs @@ -0,0 +1,881 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.KinectSensor +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + +namespace Microsoft.Kinect +{ + public sealed class KinectSensor : IDisposable + { + private const int ColorHelperIndex = 0; + private const int DepthHelperIndex = 1; + private const int SkeletonHelperIndex = 2; + private static ulong failureStackPointer = NativeMethods.NuiDebugGetFailureStack(); + private readonly ReaderWriterLockSlim _initLock = new ReaderWriterLockSlim(); + private readonly object _disposeLock = new object(); + private KinectAudioSource _audioSource; + private static bool _unsupportedMessageShown = false; + private KinectStatus _lastStatus = KinectStatus.NotReady; + private readonly ContextEventHandler _depthFrameReadyContextHandler; + private readonly ContextEventHandler _colorFrameReadyContextHandler; + private readonly ContextEventHandler _skeletonFrameReadyContextHandler; + private readonly ContextEventHandler _allFramesReadyContextHandler; + private CoordinateMapper _coordinateMapper; + private ManualResetEvent _hKillThread; + private readonly KinectSensor.FrameStateHelper[] _frameHelpers; + private KinectSensor.SensorOptions _requestedOptions; + private KinectSensor.SensorOptions _currentOptions; + private Thread _thread; + + internal int InstanceIndex => this.NuiSensor != null ? this.NuiSensor.NuiInstanceIndex() : int.MinValue; + + public static KinectSensorCollection KinectSensors => KinectSensorCollection.Instance; + + internal NuiSensor NuiSensor { get; private set; } + + internal KinectSensor(INuiSensor nuiSensor) + { + this._allFramesReadyContextHandler = new ContextEventHandler(); + this._depthFrameReadyContextHandler = new ContextEventHandler(); + this._colorFrameReadyContextHandler = new ContextEventHandler(); + this._skeletonFrameReadyContextHandler = new ContextEventHandler(); + this._frameHelpers = new KinectSensor.FrameStateHelper[3] + { + (KinectSensor.FrameStateHelper) new KinectSensor.FrameStateHelper(KinectSensor.FrameStateType.Color, this._colorFrameReadyContextHandler), + (KinectSensor.FrameStateHelper) new KinectSensor.FrameStateHelper(KinectSensor.FrameStateType.Depth, this._depthFrameReadyContextHandler), + (KinectSensor.FrameStateHelper) new KinectSensor.FrameStateHelper(KinectSensor.FrameStateType.Skeleton, this._skeletonFrameReadyContextHandler) + }; + this.NuiSensor = new NuiSensor(nuiSensor); + this._requestedOptions = KinectSensor.SensorOptions.None; + this.LastStatus = this.GetStatus(); + if (KinectSensor._unsupportedMessageShown || this.NuiSensor.IsSupported) + return; + if (this.LastStatus == KinectStatus.DeviceNotSupported) + Debugger.Log(0, "Warning", Resources.KinectNotSupportedNonDeveloper); + else + Debugger.Log(0, "Warning", Resources.KinectNotSupportedDeveloper); + KinectSensor._unsupportedMessageShown = true; + } + + internal void UpdateNuiSensor(INuiSensor nuiSensor) => this.NuiSensor = new NuiSensor(nuiSensor); + + private void CreateStreamObjects() + { + this.DepthStream = new DepthImageStream(this); + this.ColorStream = new ColorImageStream(this); + this.SkeletonStream = new SkeletonStream(this); + this._requestedOptions = KinectSensor.SensorOptions.UseColor | KinectSensor.SensorOptions.UseDepth; + } + + public string UniqueKinectId + { + get + { + using (this.EnterReadLock()) + return this.GetUniqueKinectId(); + } + } + + internal string GetUniqueKinectId() + { + if (this.LastStatus != KinectStatus.Connected) + return (string)null; + string str = this.NuiSensor.NuiUniqueId(); + return !string.IsNullOrEmpty(str) ? str : throw new InvalidOperationException(Resources.FailedToGetDeviceName); + } + + public string DeviceConnectionId + { + get + { + using (this.EnterReadLock()) + return this.GetDeviceConnectionId(); + } + } + + internal string GetDeviceConnectionId() => this.NuiSensor.NuiDeviceConnectionId(); + + public KinectStatus Status + { + get + { + using (this.EnterReadLock()) + return this.LastStatus = this.GetStatus(); + } + } + + internal KinectStatus GetStatus() => KinectSensor.MapStatus(this.NuiSensor.NuiStatus()); + + internal static KinectStatus MapStatus(uint code) + { + switch (code) + { + case 0: + return KinectStatus.Connected; + case 50397185: + return KinectStatus.Initializing; + case 2147483648: + return KinectStatus.Error; + case 2197880838: + return KinectStatus.DeviceNotGenuine; + case 2197880839: + return KinectStatus.InsufficientBandwidth; + case 2197880840: + return KinectStatus.DeviceNotSupported; + case 2197880852: + return KinectStatus.Disconnected; + case 2197880853: + return KinectStatus.NotReady; + case 2197881471: + return KinectStatus.NotPowered; + default: + return KinectStatus.Error; + } + } + + internal KinectStatus LastStatus + { + get => this._lastStatus; + set + { + if (value == KinectStatus.Connected && this._requestedOptions == KinectSensor.SensorOptions.None) + this.CreateStreamObjects(); + this._lastStatus = value; + } + } + + internal bool WasRunning { get; set; } + + public event EventHandler DepthFrameReady + { + add + { + KinectEtwProvider.EventWriteManagedFrameReadyEventAddedInfo(1); + this._depthFrameReadyContextHandler.AddHandler(value); + } + remove + { + KinectEtwProvider.EventWriteManagedFrameReadyEventRemovedInfo(1); + this._depthFrameReadyContextHandler.RemoveHandler(value); + } + } + + public event EventHandler ColorFrameReady + { + add + { + KinectEtwProvider.EventWriteManagedFrameReadyEventAddedInfo(0); + this._colorFrameReadyContextHandler.AddHandler(value); + } + remove + { + KinectEtwProvider.EventWriteManagedFrameReadyEventRemovedInfo(0); + this._colorFrameReadyContextHandler.RemoveHandler(value); + } + } + + public event EventHandler SkeletonFrameReady + { + add + { + KinectEtwProvider.EventWriteManagedFrameReadyEventAddedInfo(2); + this._skeletonFrameReadyContextHandler.AddHandler(value); + } + remove + { + KinectEtwProvider.EventWriteManagedFrameReadyEventRemovedInfo(2); + this._skeletonFrameReadyContextHandler.RemoveHandler(value); + } + } + + public event EventHandler AllFramesReady + { + add + { + KinectEtwProvider.EventWriteManagedAllFramesReadyEventAddedInfo(); + this._allFramesReadyContextHandler.AddHandler(value); + } + remove + { + KinectEtwProvider.EventWriteManagedAllFramesReadyEventRemovedInfo(); + this._allFramesReadyContextHandler.RemoveHandler(value); + } + } + + internal bool HasDepthInvocations => this._depthFrameReadyContextHandler.HasHandlers; + + internal bool HasColorInvocations => this._colorFrameReadyContextHandler.HasHandlers; + + internal bool HasSkeletonInvocations => this._skeletonFrameReadyContextHandler.HasHandlers; + + internal bool HasAllFramesInvocations => this._allFramesReadyContextHandler.HasHandlers; + + public CoordinateMapper CoordinateMapper => this._coordinateMapper ?? (this._coordinateMapper = new CoordinateMapper(this)); + + public static bool IsKnownPoint(DepthImagePixel depthImagePixel) => depthImagePixel.Depth != (short)0; + + public static bool IsKnownPoint(ColorImagePoint colorImagePoint) => colorImagePoint.X != int.MinValue || colorImagePoint.Y != int.MinValue; + + public static bool IsKnownPoint(DepthImagePoint depthImagePoint) => depthImagePoint.Depth != 0; + + public static bool IsKnownPoint(SkeletonPoint skeletonPoint) => (double)skeletonPoint.Z > 0.0; + + public DepthImageStream DepthStream { get; private set; } + + public ColorImageStream ColorStream { get; private set; } + + public SkeletonStream SkeletonStream { get; private set; } + + public KinectAudioSource AudioSource + { + get + { + using (this.EnterReadLock()) + { + if (this._audioSource == null) + this._audioSource = this.LastStatus != KinectStatus.Connected ? (KinectAudioSource)null : new KinectAudioSource(this); + return this._audioSource; + } + } + } + + public int MaxElevationAngle => 27; + + public int MinElevationAngle => -27; + + public int ElevationAngle + { + get + { + using (this.EnterReadLock()) + { + this.CheckNotRunning(); + return this.NuiSensor.NuiCameraElevationGetAngle(); + } + } + set + { + using (this.EnterReadLock()) + { + this.CheckNotRunning(); + if (value < this.MinElevationAngle || value > this.MaxElevationAngle) + throw new ArgumentOutOfRangeException(Resources.ElevationIncorrect); + this.NuiSensor.NuiCameraElevationSetAngle(value); + } + } + } + + public bool ForceInfraredEmitterOff + { + get => this.NuiSensor.ForceInfraredEmitterOff; + set => this.NuiSensor.ForceInfraredEmitterOff = value; + } + + public IDepthFilter DepthFilter + { + get => this.NuiSensor.DepthFilter; + set => this.NuiSensor.DepthFilter = value; + } + + public Vector4 AccelerometerGetCurrentReading() + { + using (this.EnterReadLock()) + return this.NuiSensor.NuiAccelerometerGetCurrentReading(); + } + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapDepthPointToColorPoint", false)] + public ColorImagePoint MapDepthToColorImagePoint( + DepthImageFormat depthImageFormat, + int depthX, + int depthY, + short depthPixelValue, + ColorImageFormat colorImageFormat) + { + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof(depthImageFormat)); + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof(colorImageFormat)); + KinectEtwProvider.EventWriteMapDepthToColorImagePointStart(); + int plColorX; + int plColorY; + var viewArea = new _NUI_IMAGE_VIEW_AREA() + { + eDigitalZoom = 0, + lCenterX = 0, + lCenterY = 0 + }; + this.NuiSensor.NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution((_NUI_IMAGE_RESOLUTION)ColorImageStream.LookUpImageResolution(colorImageFormat), (_NUI_IMAGE_RESOLUTION)DepthImageStream.LookUpImageResolution(depthImageFormat), ref viewArea, depthX, depthY, (ushort)depthPixelValue, out plColorX, out plColorY); + KinectEtwProvider.EventWriteMapDepthToColorImagePointEnd(); + return new ColorImagePoint() + { + X = plColorX, + Y = plColorY + }; + } + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapDepthFrameToColorFrame", false)] + public void MapDepthFrameToColorFrame( + DepthImageFormat depthImageFormat, + short[] depthPixelData, + ColorImageFormat colorImageFormat, + ColorImagePoint[] colorCoordinates) + { + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof(depthImageFormat)); + if (depthPixelData == null) + throw new ArgumentNullException(nameof(depthPixelData)); + if (depthPixelData.Length != DepthImageStream.LookUpPixelDataLength(depthImageFormat)) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof(depthPixelData)); + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof(colorImageFormat)); + if (colorCoordinates == null) + throw new ArgumentNullException(nameof(colorCoordinates)); + if (colorCoordinates.Length != depthPixelData.Length) + throw new ArgumentException(Resources.PixelBufferIncorrectLength, nameof(colorCoordinates)); + KinectEtwProvider.EventWriteMapDepthFrameToColorFrameStart(); + this.NuiSensor.NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution((_NUI_IMAGE_RESOLUTION)ColorImageStream.LookUpImageResolution(colorImageFormat), (_NUI_IMAGE_RESOLUTION)DepthImageStream.LookUpImageResolution(depthImageFormat), depthPixelData, colorCoordinates); + KinectEtwProvider.EventWriteMapDepthFrameToColorFrameEnd(); + } + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapSkeletonPointToColorPoint", false)] + public ColorImagePoint MapSkeletonPointToColor( + SkeletonPoint skeletonPoint, + ColorImageFormat colorImageFormat) + { + if (colorImageFormat == ColorImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof(colorImageFormat)); + KinectEtwProvider.EventWriteMapSkeletonPointToColorStart(); + _Vector4 vPoint; + vPoint.x = skeletonPoint.X; + vPoint.y = skeletonPoint.Y; + vPoint.z = skeletonPoint.Z; + vPoint.w = 1f; + float pfDepthX; + float pfDepthY; + float pfDepthValue; + KinectSensor.ManagedNuiTransformSkeletonToDepthImage(vPoint, out pfDepthX, out pfDepthY, out pfDepthValue); + ColorImagePoint colorImagePoint = this.MapDepthToColorImagePoint(DepthImageFormat.Resolution640x480Fps30, (int)((double)pfDepthX * 640.0), (int)((double)pfDepthY * 480.0), (short)((int)pfDepthValue << 3), colorImageFormat); + KinectEtwProvider.EventWriteMapSkeletonPointToColorEnd(); + return colorImagePoint; + } + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapSkeletonPointToDepthPoint", false)] + public DepthImagePoint MapSkeletonPointToDepth( + SkeletonPoint skeletonPoint, + DepthImageFormat depthImageFormat) + { + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof(depthImageFormat)); + KinectEtwProvider.EventWriteMapSkeletonPointToDepthStart(); + _Vector4 vPoint; + vPoint.x = skeletonPoint.X; + vPoint.y = skeletonPoint.Y; + vPoint.z = skeletonPoint.Z; + vPoint.w = 1f; + float pfDepthX; + float pfDepthY; + float pfDepthValue; + KinectSensor.ManagedNuiTransformSkeletonToDepthImage(vPoint, out pfDepthX, out pfDepthY, out pfDepthValue); + int width; + int height; + ImageStream.ResolutionToHeightWidth(DepthImageStream.LookUpImageResolution(depthImageFormat), out width, out height); + DepthImagePoint depth = new DepthImagePoint() + { + X = (int)((double)pfDepthX * (double)width + 0.5), + Y = (int)((double)pfDepthY * (double)height + 0.5), + Depth = (int)((double)pfDepthValue + 0.5) + }; + KinectEtwProvider.EventWriteMapSkeletonPointToDepthEnd(); + return depth; + } + + [Obsolete("This method is replaced by Microsoft.Kinect.CoordinateMapper.MapDepthPointToSkeletonPoint", false)] + public SkeletonPoint MapDepthToSkeletonPoint( + DepthImageFormat depthImageFormat, + int depthX, + int depthY, + short depthPixelValue) + { + if (depthImageFormat == DepthImageFormat.Undefined) + throw new ArgumentException(Resources.ImageFormatNotSupported, nameof(depthImageFormat)); + KinectEtwProvider.EventWriteMapDepthToSkeletonPointStart(); + int width; + int height; + ImageStream.ResolutionToHeightWidth(DepthImageStream.LookUpImageResolution(depthImageFormat), out width, out height); + _Vector4 skeleton = KinectSensor.ManagedNuiTransformDepthImageToSkeleton((float)depthX / (float)width, (float)depthY / (float)height, depthPixelValue); + SkeletonPoint skeletonPoint = new SkeletonPoint() + { + X = skeleton.x, + Y = skeleton.y, + Z = skeleton.z + }; + KinectEtwProvider.EventWriteMapDepthToSkeletonPointEnd(); + return skeletonPoint; + } + + private static _Vector4 ManagedNuiTransformDepthImageToSkeleton( + float fDepthX, + float fDepthY, + short depthPixelDatum) + { + KinectEtwProvider.EventWriteManagedNuiTransformDepthImageToSkeletonStart(); + float num1 = (float)((int)depthPixelDatum >> 3) / 1000f; + float num2 = (float)((double)(fDepthX - 0.5f) * (0.003501000115647912 * (double)num1) * 320.0); + float num3 = (float)((double)(0.5f - fDepthY) * (0.003501000115647912 * (double)num1) * 240.0); + _Vector4 skeleton; + skeleton.x = num2; + skeleton.y = num3; + skeleton.z = num1; + skeleton.w = 1f; + KinectEtwProvider.EventWriteManagedNuiTransformDepthImageToSkeletonEnd(); + return skeleton; + } + + internal static void ManagedNuiTransformSkeletonToDepthImage( + _Vector4 vPoint, + out float pfDepthX, + out float pfDepthY, + out float pfDepthValue) + { + KinectEtwProvider.EventWriteManagedNuiTransformSkeletonToDepthImageStart(); + if ((double)vPoint.z > 1.4012984643248171E-45) + { + pfDepthX = (float)(0.5 + (double)vPoint.x * 285.6300048828125 / ((double)vPoint.z * 320.0)); + pfDepthY = (float)(0.5 - (double)vPoint.y * 285.6300048828125 / ((double)vPoint.z * 240.0)); + pfDepthValue = vPoint.z * 1000f; + } + else + { + pfDepthX = 0.0f; + pfDepthY = 0.0f; + pfDepthValue = 0.0f; + } + KinectEtwProvider.EventWriteManagedNuiTransformSkeletonToDepthImageEnd(); + } + + public void Start() + { + using (AutoLock autoLock = this.EnterUpgradeableReadLock()) + { + if (this.LastStatus != KinectStatus.Connected) + throw new InvalidOperationException(Resources.KinectNotReady); + if (!this.IsRunningInternal) + { + using (autoLock.UpgradeToWrite()) + this.Initialize(this._requestedOptions); + } + KinectEtwProvider.EventWriteManagedKinectSensorStartInfo(this.GetDeviceConnectionId()); + } + } + + public void Stop() + { + using (AutoLock autoLock = this.EnterUpgradeableReadLock()) + { + if (!this.IsRunningInternal) + return; + using (autoLock.UpgradeToWrite()) + this.Uninitialize(); + } + } + + public bool IsRunning + { + get + { + using (this.EnterReadLock()) + return this.IsRunningInternal; + } + } + + private bool IsRunningInternal => this._currentOptions != KinectSensor.SensorOptions.None; + + internal void RequestSkeletonEngine(bool enable) + { + using (AutoLock autoLock = this.EnterUpgradeableReadLock()) + { + this._requestedOptions = !enable ? KinectSensor.SensorOptions.UseColor | KinectSensor.SensorOptions.UseDepth : KinectSensor.SensorOptions.UseDepthAndPlayerIndex | KinectSensor.SensorOptions.UseColor | KinectSensor.SensorOptions.UseSkeletalTracking | KinectSensor.SensorOptions.UseDepth; + if (this.LastStatus != KinectStatus.Connected || !this.IsRunningInternal || this._currentOptions == (this._requestedOptions | KinectSensor.SensorOptions.UseAudio)) + return; + using (autoLock.UpgradeToWrite()) + { + this.Uninitialize(); + this.Initialize(this._requestedOptions); + } + } + } + + private void Initialize(KinectSensor.SensorOptions options) + { + KinectEtwProvider.EventWriteKinectSensorInitializeStart(); + options |= KinectSensor.SensorOptions.UseAudio; + this.NuiSensor.NuiInitialize((uint)options); + this._currentOptions = options; + try + { + this.ColorStream.Start(); + this.DepthStream.Start(); + this.SkeletonStream.Start(); + } + catch (InvalidOperationException ex) + { + this.Uninitialize(); + throw; + } + this._hKillThread = new ManualResetEvent(false); + this._hKillThread.Reset(); + this._thread = new Thread(new ParameterizedThreadStart(this.MainBackgroundThreadProc)); + this._thread.Name = "Background M-NUI Thread"; + this._thread.IsBackground = true; + this._thread.Start((object)this._hKillThread); + KinectEtwProvider.EventWriteKinectSensorInitializeEnd(); + } + + private void Uninitialize() + { + this.ColorStream.Stop(); + this.DepthStream.Stop(); + this.SkeletonStream.Stop(); + if (this._audioSource != null) + this._audioSource.Stop(); + if (this._hKillThread != null) + { + this._hKillThread.Set(); + this._hKillThread = (ManualResetEvent)null; + } + if (this._thread != null) + { + this._thread.Join(); + this._thread = (Thread)null; + } + this.NuiSensor.NuiShutdown(); + this._currentOptions = KinectSensor.SensorOptions.None; + } + + private void MainBackgroundThreadProc(object data) + { + using (ManualResetEvent manualResetEvent = (ManualResetEvent)data) + { + List waitHandleList = new List(4) + { + (WaitHandle) manualResetEvent + }; + while (true) + { + bool flag1 = default; + do + { + if (waitHandleList.Count > 1) + waitHandleList.RemoveRange(1, waitHandleList.Count - 1); + bool flag2 = false; + bool flag3 = false; + bool flag4 = false; + if (this.ColorStream != null && this.ColorStream.IsEnabled && (this.HasColorInvocations || this.HasAllFramesInvocations)) + { + flag2 = true; + waitHandleList.Add((WaitHandle)this.ColorStream.NextFrameEvent); + } + if (this.DepthStream != null && this.DepthStream.IsEnabled && (this.HasDepthInvocations || this.HasAllFramesInvocations)) + { + flag3 = true; + waitHandleList.Add((WaitHandle)this.DepthStream.NextFrameEvent); + } + if (this.SkeletonStream != null && this.SkeletonStream.IsEnabled && (this.HasSkeletonInvocations || this.HasAllFramesInvocations)) + { + flag4 = true; + waitHandleList.Add((WaitHandle)this.SkeletonStream.NextSkeletonEvent); + } + switch (WaitHandle.WaitAny(waitHandleList.ToArray(), 250)) + { + case 0: + goto label_41; + case 258: + continue; + default: + bool flag5 = true; + while (flag5) + { + if (flag2 && this._frameHelpers[0].IsReadyForSetArgs && this.ColorStream.NextFrameEvent.WaitOne(0)) + this.GetColorFrame(); + if (flag3 && this._frameHelpers[1].IsReadyForSetArgs && this.DepthStream.NextFrameEvent.WaitOne(0)) + this.GetDepthFrame(); + if (flag4 && this._frameHelpers[2].IsReadyForSetArgs && this.SkeletonStream.NextSkeletonEvent.WaitOne(0)) + this.GetSkeletonFrame(); + long earliestTimestampSoFar = long.MaxValue; + int earliestFramenumberSoFar = int.MaxValue; + KinectSensor.FrameStateHelper frameStateHelper = (KinectSensor.FrameStateHelper)null; + foreach (KinectSensor.FrameStateHelper frameHelper in this._frameHelpers) + { + if (frameHelper.IsCandidateForInvoke(earliestTimestampSoFar, earliestFramenumberSoFar)) + { + earliestTimestampSoFar = frameHelper.MostRecentTimestamp; + earliestFramenumberSoFar = frameHelper.MostRecentFramenumber; + frameStateHelper = frameHelper; + } + } + if (frameStateHelper != null) + frameStateHelper.Invoke(this); + else + flag5 = false; + } + flag1 = (!flag2 || this._frameHelpers[0].HasArgs) && (!flag3 || this._frameHelpers[1].HasArgs) && (!flag4 || this._frameHelpers[2].HasArgs); + if (flag1 && flag3 && flag4) + { + if (this._frameHelpers[1].MostRecentTimestamp < this._frameHelpers[2].MostRecentTimestamp) + { + this._frameHelpers[1].ResetAndReturnArgs(); + flag1 = false; + } + else if (this._frameHelpers[1].MostRecentTimestamp > this._frameHelpers[2].MostRecentTimestamp) + { + this._frameHelpers[2].ResetAndReturnArgs(); + flag1 = false; + } + } + if (flag1 && flag2 && (flag3 || flag4)) + { + long num = this._frameHelpers[0].MostRecentTimestamp - (flag3 ? this._frameHelpers[1].MostRecentTimestamp : this._frameHelpers[2].MostRecentTimestamp); + if (num > 16L && num <= 33L) + { + if (flag3) + this._frameHelpers[1].ResetAndReturnArgs(); + if (flag4) + this._frameHelpers[2].ResetAndReturnArgs(); + flag1 = false; + } + } + continue; + } + } + while (!flag1); + KinectEtwProvider.EventWriteAllFramesReady(this._frameHelpers[0].MostRecentTimestamp, this._frameHelpers[1].MostRecentTimestamp, this._frameHelpers[2].MostRecentTimestamp); + this._allFramesReadyContextHandler.Invoke((object)this, new AllFramesReadyEventArgs((ColorImageFrameReadyEventArgs)this._frameHelpers[0].ResetAndReturnArgs(), (DepthImageFrameReadyEventArgs)this._frameHelpers[1].ResetAndReturnArgs(), (SkeletonFrameReadyEventArgs)this._frameHelpers[2].ResetAndReturnArgs())); + } + label_41:; + } + } + + private void GetDepthFrame() + { + int frameNumber; + long timestamp; + ImageFrameFlags frameFlags; + if (this.DepthStream == null || !this.DepthStream.TryGetNextFrameInternal(0, out frameNumber, out timestamp, out frameFlags)) + return; + this._frameHelpers[1].SetArgs((EventArgs)DepthImageFrameReadyEventArgs.Create(this.DepthStream, frameNumber, timestamp, frameFlags), timestamp, frameNumber); + } + + private void GetColorFrame() + { + int frameNumber; + long timestamp; + ImageFrameFlags frameFlags; + if (this.ColorStream == null || !this.ColorStream.TryGetNextFrameInternal(0, out frameNumber, out timestamp, out frameFlags)) + return; + this._frameHelpers[0].SetArgs((EventArgs)ColorImageFrameReadyEventArgs.Create(this.ColorStream, frameNumber, timestamp, frameFlags), timestamp, frameNumber); + } + + private void GetSkeletonFrame() + { + int frameNumber; + long timestamp; + SkeletonTrackingMode trackingMode; + if (this.SkeletonStream == null || !this.SkeletonStream.TryGetNextFrameInternal(0, out frameNumber, out timestamp, out trackingMode)) + return; + this._frameHelpers[2].SetArgs((EventArgs)SkeletonFrameReadyEventArgs.Create(this.SkeletonStream, frameNumber, timestamp, trackingMode), timestamp, frameNumber); + } + + internal bool IsDisposed { get; private set; } + + public void Dispose() + { + lock (this._disposeLock) + { + if (this.IsDisposed) + return; + using (this.EnterWriteLock()) + { + this._allFramesReadyContextHandler.Dispose(); + this._depthFrameReadyContextHandler.Dispose(); + this._colorFrameReadyContextHandler.Dispose(); + this._skeletonFrameReadyContextHandler.Dispose(); + if (this.IsRunningInternal) + this.Uninitialize(); + string name = (string)null; + if (this.LastStatus == KinectStatus.Connected) + name = this.GetDeviceConnectionId(); + if (this.DepthStream != null) + { + this.DepthStream.Dispose(); + this.DepthStream = (DepthImageStream)null; + } + if (this.ColorStream != null) + { + this.ColorStream.Dispose(); + this.ColorStream = (ColorImageStream)null; + } + if (this.SkeletonStream != null) + { + this.SkeletonStream.Dispose(); + this.SkeletonStream = (SkeletonStream)null; + } + if (this._audioSource != null) + { + this._audioSource.Dispose(); + this._audioSource = (KinectAudioSource)null; + } + this.NuiSensor = (NuiSensor)null; + KinectSensorCollection.Instance.RemakeSensor(this, name); + this.IsDisposed = true; + } + this._initLock.Dispose(); + } + } + + private AutoLock EnterReadLock() + { + lock (this._disposeLock) + { + if (this.IsDisposed) + throw new ObjectDisposedException(nameof(KinectSensor)); + return this._initLock.EnterReadLockAuto(); + } + } + + private AutoLock EnterUpgradeableReadLock() + { + lock (this._disposeLock) + { + if (this.IsDisposed) + throw new ObjectDisposedException(nameof(KinectSensor)); + return this._initLock.EnterUpgradeableReadLockAuto(); + } + } + + private AutoLock EnterWriteLock() + { + lock (this._disposeLock) + { + if (this.IsDisposed) + throw new ObjectDisposedException(nameof(KinectSensor)); + return this._initLock.EnterWriteLockAuto(); + } + } + + private void CheckNotRunning() + { + if (!this.IsRunningInternal) + throw new InvalidOperationException(Resources.KinectMustBeRunning); + } + + private abstract class FrameStateHelper + { + public long MostRecentTimestamp { get; protected set; } + + public int MostRecentFramenumber { get; protected set; } + + public bool IsReadyForSetArgs => !this.HasArgs || this.HaveDispatchedEvent; + + public abstract bool HasArgs { get; } + + public abstract void SetArgs(EventArgs args, long timestamp, int framenumber); + + public abstract void Invoke(KinectSensor sender); + + public abstract EventArgs ResetAndReturnArgs(); + + public bool IsCandidateForInvoke(long earliestTimestampSoFar, int earliestFramenumberSoFar) + { + if (!this.HasArgs || this.HaveDispatchedEvent) + return false; + if (this.MostRecentTimestamp < earliestTimestampSoFar) + return true; + return this.MostRecentTimestamp == earliestTimestampSoFar && this.MostRecentFramenumber < earliestFramenumberSoFar; + } + + protected bool HaveDispatchedEvent { get; set; } + + protected abstract bool HasListeners { get; } + } + + internal enum FrameStateType + { + Color, + Depth, + Skeleton, + } + + private class FrameStateHelper : KinectSensor.FrameStateHelper where TArgs : EventArgs + { + private readonly ContextEventHandler _handler; + private readonly KinectSensor.FrameStateType _type; + private TArgs _args; + + public FrameStateHelper( + KinectSensor.FrameStateType type, + ContextEventHandler contextHandler) + { + this._type = type; + this._handler = contextHandler; + } + + public override bool HasArgs => (object)this._args != null; + + public override void SetArgs(EventArgs args, long timestamp, int framenumber) + { + this._args = (TArgs)args; + this.MostRecentTimestamp = timestamp; + this.MostRecentFramenumber = framenumber; + this.HaveDispatchedEvent = false; + } + + public override void Invoke(KinectSensor sender) + { + switch (this._type) + { + case KinectSensor.FrameStateType.Color: + KinectEtwProvider.EventWriteColorFrameReady(this.MostRecentTimestamp); + break; + case KinectSensor.FrameStateType.Depth: + KinectEtwProvider.EventWriteDepthFrameReady(this.MostRecentTimestamp); + break; + case KinectSensor.FrameStateType.Skeleton: + KinectEtwProvider.EventWriteSkeletonFrameReady(this.MostRecentTimestamp); + break; + } + if (this.HasListeners) + this._handler.Invoke((object)sender, this._args); + this.HaveDispatchedEvent = true; + } + + public override EventArgs ResetAndReturnArgs() + { + TArgs args = this._args; + this._args = default(TArgs); + this.HaveDispatchedEvent = false; + this.MostRecentTimestamp = 0L; + return (EventArgs)args; + } + + protected override bool HasListeners => this._handler.HasHandlers; + } + + [Flags] + private enum SensorOptions + { + None = 0, + UseDepthAndPlayerIndex = 1, + UseColor = 2, + UseSkeletalTracking = 8, + UseDepth = 32, // 0x00000020 + UseAudio = 268435456, // 0x10000000 + } + } +} diff --git a/src/Microsoft.Kinect/KinectSensorCollection.cs b/src/Microsoft.Kinect/KinectSensorCollection.cs new file mode 100644 index 0000000..41fa6f3 --- /dev/null +++ b/src/Microsoft.Kinect/KinectSensorCollection.cs @@ -0,0 +1,165 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.KinectSensorCollection +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [ComVisible(false)] + public sealed class KinectSensorCollection : ReadOnlyCollection, IDisposable + { + private static readonly object s_sensorsLock = new object(); + private static readonly ThreadSafeList s_activeSensors = new ThreadSafeList(KinectSensorCollection.s_sensorsLock); + private static readonly KinectSensorCollection s_instance = KinectSensorCollection.Initialize(); + private readonly List _sensors = new List(); + private readonly NativeMethods.NuiStatusCallback _nuiCallBackDelegate; + private readonly ContextEventHandler _statusChangedContextHandler; + + internal static KinectSensorCollection Instance => KinectSensorCollection.s_instance; + + public event EventHandler StatusChanged + { + add => this._statusChangedContextHandler.AddHandler(value); + remove => this._statusChangedContextHandler.RemoveHandler(value); + } + + public KinectSensor this[string instanceId] + { + get + { + lock (KinectSensorCollection.s_sensorsLock) + { + if (string.IsNullOrEmpty(instanceId)) + throw new ArgumentNullException(nameof (instanceId)); + KinectSensor kinectSensor = this._sensors.FirstOrDefault((Func) (r => r.GetDeviceConnectionId() == instanceId || r.GetUniqueKinectId() == instanceId)); + if (kinectSensor == null) + { + INuiSensor pNuiSensor = (INuiSensor) null; + KinectExceptionHelper.CheckHr(NativeMethods.NuiCreateSensorById(instanceId, out pNuiSensor)); + kinectSensor = new KinectSensor(pNuiSensor); + this._sensors.Add(kinectSensor); + this.UpdateActiveSensors(); + } + return kinectSensor; + } + } + } + + private KinectSensorCollection() + : base((IList) KinectSensorCollection.s_activeSensors) + { + this._nuiCallBackDelegate = new NativeMethods.NuiStatusCallback(this.OnNuiStatusCallback); + NativeMethods.NuiSetDeviceStatusCallback(this._nuiCallBackDelegate, IntPtr.Zero); + this._statusChangedContextHandler = new ContextEventHandler(); + } + + private static KinectSensorCollection Initialize() + { + KinectSensorCollection sensorCollection = new KinectSensorCollection(); + try + { + int pCount; + KinectExceptionHelper.CheckHr(NativeMethods.NuiGetSensorCount(out pCount)); + for (int index = 0; index < pCount; ++index) + { + INuiSensor pNuiSensor = (INuiSensor) null; + if (NativeMethods.NuiCreateSensorByIndex(index, out pNuiSensor) == 0) + { + KinectSensor kinectSensor = new KinectSensor(pNuiSensor); + sensorCollection._sensors.Add(kinectSensor); + } + } + sensorCollection.UpdateActiveSensors(); + } + catch (Exception ex) + { + sensorCollection.Dispose(); + throw; + } + return sensorCollection; + } + + internal void OnNuiStatusCallback( + int status, + string instanceName, + string uniqueDeviceName, + IntPtr pUserData) + { + this.NotifyUserKinectsStatusChanged((object) new InternalStatusChangedEventArgs() + { + KinectStatus = KinectSensor.MapStatus((uint) status), + DeviceConnectionId = instanceName, + UniqueKinectId = uniqueDeviceName + }); + } + + internal void NotifyUserKinectsStatusChanged(object state) + { + KinectSensor sensor = (KinectSensor) null; + InternalStatusChangedEventArgs internalArgs = (InternalStatusChangedEventArgs) state; + lock (KinectSensorCollection.s_sensorsLock) + { + sensor = this._sensors.FirstOrDefault((Func) (r => r.GetDeviceConnectionId() == internalArgs.DeviceConnectionId)); + if (internalArgs.KinectStatus == KinectStatus.Disconnected) + { + if (sensor != null) + this.RemakeSensor(sensor, internalArgs.DeviceConnectionId); + } + else if (sensor == null) + { + INuiSensor pNuiSensor = (INuiSensor) null; + KinectExceptionHelper.CheckHr(NativeMethods.NuiCreateSensorById(internalArgs.DeviceConnectionId, out pNuiSensor)); + sensor = new KinectSensor(pNuiSensor); + this._sensors.Add(sensor); + } + if (sensor != null) + sensor.LastStatus = internalArgs.KinectStatus; + this.UpdateActiveSensors(); + } + if (!this._statusChangedContextHandler.HasHandlers) + return; + StatusChangedEventArgs eventArgs = new StatusChangedEventArgs() + { + Status = internalArgs.KinectStatus + }; + eventArgs.Sensor = sensor; + this._statusChangedContextHandler.Invoke((object) this, eventArgs); + } + + private void UpdateActiveSensors() + { + lock (KinectSensorCollection.s_sensorsLock) + { + KinectSensorCollection.s_activeSensors.Clear(); + KinectSensorCollection.s_activeSensors.AddRange((IEnumerable) this._sensors.Where((Func) (r => r.GetStatus() != KinectStatus.Disconnected)).OrderBy((Func) (r => r.InstanceIndex))); + } + } + + internal void RemakeSensor(KinectSensor sensor, string name) + { + lock (KinectSensorCollection.s_sensorsLock) + this._sensors.Remove(sensor); + if (sensor.LastStatus != KinectStatus.Connected) + return; + if (name == null) + return; + try + { + sensor = KinectSensorCollection.Instance[name]; + } + catch (InvalidOperationException ex) + { + } + } + + public void Dispose() => this._statusChangedContextHandler.Dispose(); + } +} diff --git a/src/Microsoft.Kinect/KinectStatus.cs b/src/Microsoft.Kinect/KinectStatus.cs new file mode 100644 index 0000000..eab8c55 --- /dev/null +++ b/src/Microsoft.Kinect/KinectStatus.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.KinectStatus +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum KinectStatus + { + Undefined, + Disconnected, + Connected, + Initializing, + Error, + NotPowered, + NotReady, + DeviceNotGenuine, + DeviceNotSupported, + InsufficientBandwidth, + } +} diff --git a/src/Microsoft.Kinect/Matrix4.cs b/src/Microsoft.Kinect/Matrix4.cs new file mode 100644 index 0000000..228518b --- /dev/null +++ b/src/Microsoft.Kinect/Matrix4.cs @@ -0,0 +1,83 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Matrix4 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; + +namespace Microsoft.Kinect +{ + public struct Matrix4 + { + public float M11 { get; set; } + + public float M12 { get; set; } + + public float M13 { get; set; } + + public float M14 { get; set; } + + public float M21 { get; set; } + + public float M22 { get; set; } + + public float M23 { get; set; } + + public float M24 { get; set; } + + public float M31 { get; set; } + + public float M32 { get; set; } + + public float M33 { get; set; } + + public float M34 { get; set; } + + public float M41 { get; set; } + + public float M42 { get; set; } + + public float M43 { get; set; } + + public float M44 { get; set; } + + public static Matrix4 Identity => new Matrix4() + { + M11 = 1f, + M22 = 1f, + M33 = 1f, + M44 = 1f + }; + + public override bool Equals(object obj) => obj is Matrix4 mat && this.Equals(mat); + + public bool Equals(Matrix4 mat) => this.M11.Equals(mat.M11) && this.M12.Equals(mat.M12) && this.M13.Equals(mat.M13) && this.M14.Equals(mat.M14) && this.M21.Equals(mat.M21) && this.M22.Equals(mat.M22) && this.M23.Equals(mat.M23) && this.M24.Equals(mat.M24) && this.M31.Equals(mat.M31) && this.M32.Equals(mat.M32) && this.M33.Equals(mat.M33) && this.M34.Equals(mat.M34) && this.M41.Equals(mat.M41) && this.M42.Equals(mat.M42) && this.M43.Equals(mat.M43) && this.M44.Equals(mat.M44); + + public override int GetHashCode() => this.M11.GetHashCode() + this.M12.GetHashCode() + this.M13.GetHashCode() + this.M14.GetHashCode() + this.M21.GetHashCode() + this.M22.GetHashCode() + this.M23.GetHashCode() + this.M24.GetHashCode() + this.M31.GetHashCode() + this.M32.GetHashCode() + this.M33.GetHashCode() + this.M34.GetHashCode() + this.M41.GetHashCode() + this.M42.GetHashCode() + this.M43.GetHashCode() + this.M44.GetHashCode(); + + public static bool operator ==(Matrix4 mat1, Matrix4 mat2) => mat1.Equals(mat2); + + public static bool operator !=(Matrix4 mat1, Matrix4 mat2) => !mat1.Equals(mat2); + + internal static Matrix4 CopyFrom(ref _Matrix4 mat) => new Matrix4() + { + M11 = mat.M11, + M12 = mat.M12, + M13 = mat.M13, + M14 = mat.M14, + M21 = mat.M21, + M22 = mat.M22, + M23 = mat.M23, + M24 = mat.M24, + M31 = mat.M31, + M32 = mat.M32, + M33 = mat.M33, + M34 = mat.M34, + M41 = mat.M41, + M42 = mat.M42, + M43 = mat.M43, + M44 = mat.M44 + }; + } +} diff --git a/src/Microsoft.Kinect/MicrophoneArrayDevice.cs b/src/Microsoft.Kinect/MicrophoneArrayDevice.cs new file mode 100644 index 0000000..dd37810 --- /dev/null +++ b/src/Microsoft.Kinect/MicrophoneArrayDevice.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.MicrophoneArrayDevice +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct MicrophoneArrayDevice + { + private const int MaxStrLen = 512; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] + public string DeviceName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] + public string DeviceID; + [MarshalAs(UnmanagedType.I4)] + public int DeviceIndex; + } +} diff --git a/src/Microsoft.Kinect/Microsoft.Kinect.csproj b/src/Microsoft.Kinect/Microsoft.Kinect.csproj new file mode 100644 index 0000000..17e9814 --- /dev/null +++ b/src/Microsoft.Kinect/Microsoft.Kinect.csproj @@ -0,0 +1,17 @@ + + + + + net6.0-windows + 1.8.0.0 + true + ..\..\lib + + true + + + + none + + + \ No newline at end of file diff --git a/src/Microsoft.Kinect/Microsoft.Kinect.sln b/src/Microsoft.Kinect/Microsoft.Kinect.sln new file mode 100644 index 0000000..bbeeab8 --- /dev/null +++ b/src/Microsoft.Kinect/Microsoft.Kinect.sln @@ -0,0 +1,33 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33815.320 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Kinect", "Microsoft.Kinect.csproj", "{DE5EFA3E-9FDA-418D-9DD2-03E00FA5F4F5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Kinect.Toolkit", "..\Microsoft.Kinect.Toolkit\Microsoft.Kinect.Toolkit.csproj", "{7405F8D7-F671-4B2D-995A-5BE174ACEC19}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Kinect.Toolkit.FaceTracking", "..\Microsoft.Kinect.Toolkit.FaceTracking\Microsoft.Kinect.Toolkit.FaceTracking.csproj", "{B5F16EDB-3960-4E05-B709-0E8CAF88910A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DE5EFA3E-9FDA-418D-9DD2-03E00FA5F4F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE5EFA3E-9FDA-418D-9DD2-03E00FA5F4F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE5EFA3E-9FDA-418D-9DD2-03E00FA5F4F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE5EFA3E-9FDA-418D-9DD2-03E00FA5F4F5}.Release|Any CPU.Build.0 = Release|Any CPU + {7405F8D7-F671-4B2D-995A-5BE174ACEC19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7405F8D7-F671-4B2D-995A-5BE174ACEC19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7405F8D7-F671-4B2D-995A-5BE174ACEC19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7405F8D7-F671-4B2D-995A-5BE174ACEC19}.Release|Any CPU.Build.0 = Release|Any CPU + {B5F16EDB-3960-4E05-B709-0E8CAF88910A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5F16EDB-3960-4E05-B709-0E8CAF88910A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5F16EDB-3960-4E05-B709-0E8CAF88910A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5F16EDB-3960-4E05-B709-0E8CAF88910A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/Microsoft.Kinect/NativeMethods.cs b/src/Microsoft.Kinect/NativeMethods.cs new file mode 100644 index 0000000..7fe2e75 --- /dev/null +++ b/src/Microsoft.Kinect/NativeMethods.cs @@ -0,0 +1,77 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.NativeMethods +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + internal static class NativeMethods + { + internal const int S_OK = 0; + + [DllImport("Kinect10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern void NuiSetDeviceStatusCallback( + [In] NativeMethods.NuiStatusCallback pCallback, + IntPtr pUserData); + + [DllImport("KinectAudio10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern void NuiGetMicrophoneArrayDevices( + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] MicrophoneArrayDevice[] deviceBuffer, + [In] int size, + [In, Out] ref int count); + + [DllImport("KinectAudio10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern void NuiGetSpeakerDevices( + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] SpeakerDevice[] deviceBuffer, + [In] int size, + [In, Out] ref int count); + + [DllImport("Kinect10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern int NuiGetSensorCount(out int pCount); + + [DllImport("Kinect10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern int NuiCreateSensorByIndex(int index, out INuiSensor pNuiSensor); + + [DllImport("Kinect10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern int NuiCreateSensorById([MarshalAs(UnmanagedType.LPWStr)] string instanceName, out INuiSensor pNuiSensor); + + [DllImport("avrt.dll", EntryPoint = "AvSetMmThreadCharacteristicsW", CallingConvention = CallingConvention.StdCall)] + internal static extern int AvSetMmThreadCharacteristics([MarshalAs(UnmanagedType.LPWStr)] string taskName, [In, Out] ref int taskIndex); + + [DllImport("avrt.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool AvRevertMmThreadCharacteristics(int avrtHandle); + + [DllImport("Kinect10.dll", EntryPoint = "#1", CallingConvention = CallingConvention.StdCall)] + internal static extern ulong NuiDebugGetFailureStack(); + + [DllImport("Kinect10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern int NuiSkeletonCalculateBoneOrientations( + [In] ref _NUI_SKELETON_DATA pSkeletonData, + [Out] _NUI_SKELETON_BONE_ORIENTATION[] pBoneOrientations); + + [DllImport("Kinect10.dll", CallingConvention = CallingConvention.StdCall)] + internal static extern int NuiCreateCoordinateMapperFromParameters( + [In] uint length, + [In] IntPtr pMapperParameters, + out INuiCoordinateMapper pCoordinateMapper); + + internal static unsafe void CopyMemory(IntPtr destination, IntPtr source, int length) + { + Unsafe.CopyBlockUnaligned(destination.ToPointer(), source.ToPointer(), (uint)length); + } + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate void NuiStatusCallback( + int status, + [MarshalAs(UnmanagedType.LPWStr)] string instanceName, + [MarshalAs(UnmanagedType.LPWStr)] string uniqueDeviceName, + IntPtr pUserData); + } +} diff --git a/src/Microsoft.Kinect/NuiAudioBeam.cs b/src/Microsoft.Kinect/NuiAudioBeam.cs new file mode 100644 index 0000000..9e0fcd9 --- /dev/null +++ b/src/Microsoft.Kinect/NuiAudioBeam.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.NuiAudioBeam +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + internal class NuiAudioBeam : INuiAudioBeam + { + private readonly Microsoft.Kinect.Interop.INuiAudioBeam _beam; + + public object Wrapped => (object) this._beam; + + public NuiAudioBeam(Microsoft.Kinect.Interop.INuiAudioBeam beam) => this._beam = beam; + + public void GetBeam(out double angle) => KinectExceptionHelper.CheckHr(this._beam.GetBeam(out angle)); + + public void SetBeam(double angle) => KinectExceptionHelper.CheckHr(this._beam.SetBeam(angle)); + + public void GetPosition(out double angle, out double confidence) => KinectExceptionHelper.CheckHr(this._beam.GetPosition(out angle, out confidence)); + } +} diff --git a/src/Microsoft.Kinect/NuiColorCameraSettings.cs b/src/Microsoft.Kinect/NuiColorCameraSettings.cs new file mode 100644 index 0000000..c5bb8f1 --- /dev/null +++ b/src/Microsoft.Kinect/NuiColorCameraSettings.cs @@ -0,0 +1,289 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.NuiColorCameraSettings +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; + +namespace Microsoft.Kinect +{ + internal class NuiColorCameraSettings + { + private readonly INuiColorCameraSettings _nuiColorCameraSettings; + + public NuiColorCameraSettings(INuiColorCameraSettings nuiColorCameraSettings) => this._nuiColorCameraSettings = nuiColorCameraSettings; + + public void SetAutoWhiteBalance(bool bAutoWhiteBalanceEnabled) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetAutoWhiteBalance(bAutoWhiteBalanceEnabled ? 1 : 0)); + + public bool GetAutoWhiteBalance() + { + int pAutoWhiteBalanceEnabled; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetAutoWhiteBalance(out pAutoWhiteBalanceEnabled)); + return pAutoWhiteBalanceEnabled != 0; + } + + public void SetWhiteBalance(int whiteBalance) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetWhiteBalance(whiteBalance)); + + public int GetWhiteBalance() + { + int pWhiteBalance; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetWhiteBalance(out pWhiteBalance)); + return pWhiteBalance; + } + + public int GetMinWhiteBalance() + { + int pWhiteBalance; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinWhiteBalance(out pWhiteBalance)); + return pWhiteBalance; + } + + public int GetMaxWhiteBalance() + { + int pWhiteBalance; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxWhiteBalance(out pWhiteBalance)); + return pWhiteBalance; + } + + public void SetContrast(double contrast) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetContrast(contrast)); + + public double GetContrast() + { + double pContrast; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetContrast(out pContrast)); + return pContrast; + } + + public double GetMinContrast() + { + double pContrast; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinContrast(out pContrast)); + return pContrast; + } + + public double GetMaxContrast() + { + double pContrast; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxContrast(out pContrast)); + return pContrast; + } + + public void SetHue(double hue) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetHue(hue)); + + public double GetHue() + { + double pHue; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetHue(out pHue)); + return pHue; + } + + public double GetMinHue() + { + double pHue; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinHue(out pHue)); + return pHue; + } + + public double GetMaxHue() + { + double pHue; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxHue(out pHue)); + return pHue; + } + + public void SetSaturation(double saturation) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetSaturation(saturation)); + + public double GetSaturation() + { + double pSaturation; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetSaturation(out pSaturation)); + return pSaturation; + } + + public double GetMinSaturation() + { + double pSaturation; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinSaturation(out pSaturation)); + return pSaturation; + } + + public double GetMaxSaturation() + { + double pSaturation; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxSaturation(out pSaturation)); + return pSaturation; + } + + public void SetGamma(double gamma) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetGamma(gamma)); + + public double GetGamma() + { + double pGamma; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetGamma(out pGamma)); + return pGamma; + } + + public double GetMinGamma() + { + double pGamma; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinGamma(out pGamma)); + return pGamma; + } + + public double GetMaxGamma() + { + double pGamma; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxGamma(out pGamma)); + return pGamma; + } + + public void SetSharpness(double sharpness) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetSharpness(sharpness)); + + public double GetSharpness() + { + double pSharpness; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetSharpness(out pSharpness)); + return pSharpness; + } + + public double GetMinSharpness() + { + double pSharpness; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinSharpness(out pSharpness)); + return pSharpness; + } + + public double GetMaxSharpness() + { + double pSharpness; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxSharpness(out pSharpness)); + return pSharpness; + } + + public void SetAutoExposure(bool bAutoExposureEnabled) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetAutoExposure(bAutoExposureEnabled ? 1 : 0)); + + public bool GetAutoExposure() + { + int pAutoExposureEnabled; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetAutoExposure(out pAutoExposureEnabled)); + return pAutoExposureEnabled != 0; + } + + public void SetExposureTime(double exposureTime) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetExposureTime(exposureTime)); + + public double GetExposureTime() + { + double pExposureTime; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetExposureTime(out pExposureTime)); + return pExposureTime; + } + + public double GetMinExposureTime() + { + double pExposureTime; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinExposureTime(out pExposureTime)); + return pExposureTime; + } + + public double GetMaxExposureTime() + { + double pExposureTime; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxExposureTime(out pExposureTime)); + return pExposureTime; + } + + public void SetFrameInterval(double frameInterval) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetFrameInterval(frameInterval)); + + public double GetFrameInterval() + { + double pFrameInterval; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetFrameInterval(out pFrameInterval)); + return pFrameInterval; + } + + public double GetMinFrameInterval() + { + double pFrameInterval; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinFrameInterval(out pFrameInterval)); + return pFrameInterval; + } + + public double GetMaxFrameInterval() + { + double pFrameInterval; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxFrameInterval(out pFrameInterval)); + return pFrameInterval; + } + + public void SetBrightness(double brightness) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetBrightness(brightness)); + + public double GetBrightness() + { + double pBrightness; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetBrightness(out pBrightness)); + return pBrightness; + } + + public double GetMinBrightness() + { + double pBrightness; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinBrightness(out pBrightness)); + return pBrightness; + } + + public double GetMaxBrightness() + { + double pBrightness; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxBrightness(out pBrightness)); + return pBrightness; + } + + public void SetPowerLineFrequency(_NUI_POWER_LINE_FREQUENCY powerLineFrequency) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetPowerLineFrequency(powerLineFrequency)); + + public _NUI_POWER_LINE_FREQUENCY GetPowerLineFrequency() + { + _NUI_POWER_LINE_FREQUENCY pPowerLineFrequency; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetPowerLineFrequency(out pPowerLineFrequency)); + return pPowerLineFrequency; + } + + public void SetBacklightCompensationMode( + _NUI_BACKLIGHT_COMPENSATION_MODE backlightCompensationMode) + { + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetBacklightCompensationMode(backlightCompensationMode)); + } + + public _NUI_BACKLIGHT_COMPENSATION_MODE GetBacklightCompensationMode() + { + _NUI_BACKLIGHT_COMPENSATION_MODE pBacklightCompensationMode; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetBacklightCompensationMode(out pBacklightCompensationMode)); + return pBacklightCompensationMode; + } + + public void SetGain(double gain) => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.SetGain(gain)); + + public double GetGain() + { + double pGain; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetGain(out pGain)); + return pGain; + } + + public double GetMinGain() + { + double pGain; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMinGain(out pGain)); + return pGain; + } + + public double GetMaxGain() + { + double pGain; + KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.GetMaxGain(out pGain)); + return pGain; + } + + public void ResetCameraSettingsToDefault() => KinectExceptionHelper.CheckHr(this._nuiColorCameraSettings.ResetCameraSettingsToDefault()); + } +} diff --git a/src/Microsoft.Kinect/NuiCoordinateMapper.cs b/src/Microsoft.Kinect/NuiCoordinateMapper.cs new file mode 100644 index 0000000..39497f0 --- /dev/null +++ b/src/Microsoft.Kinect/NuiCoordinateMapper.cs @@ -0,0 +1,122 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.NuiCoordinateMapper +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + internal class NuiCoordinateMapper : INuiCoordinateMapperParametersChangedEvent + { + private INuiCoordinateMapper _nuiCoordinateMapper; + private ContextEventHandler _relationalParametersChangedHandler; + + public NuiCoordinateMapper(INuiCoordinateMapper nuiCoordinateMapper) + { + this._nuiCoordinateMapper = nuiCoordinateMapper; + this.Init(); + } + + public unsafe NuiCoordinateMapper(byte[] parameters) + { + fixed (byte* pMapperParameters = parameters) + KinectExceptionHelper.CheckHr(NativeMethods.NuiCreateCoordinateMapperFromParameters((uint) parameters.Length, (IntPtr) (void*) pMapperParameters, out this._nuiCoordinateMapper)); + this.Init(); + } + + internal void Init() + { + this._relationalParametersChangedHandler = new ContextEventHandler(); + KinectExceptionHelper.CheckHr(this._nuiCoordinateMapper.NotifyParametersChanged((INuiCoordinateMapperParametersChangedEvent) this)); + } + + public byte[] GetColorToDepthRelationalParameters() + { + IntPtr ppData = IntPtr.Zero; + try + { + uint pDataByteCount; + KinectExceptionHelper.CheckHr(this._nuiCoordinateMapper.GetColorToDepthRelationalParameters(out pDataByteCount, out ppData)); + byte[] destination = new byte[pDataByteCount]; + Marshal.Copy(ppData, destination, 0, (int) pDataByteCount); + return destination; + } + finally + { + Marshal.FreeCoTaskMem(ppData); + } + } + + public event EventHandler RelationalParametersChanged + { + add => this._relationalParametersChangedHandler.AddHandler(value); + remove => this._relationalParametersChangedHandler.RemoveHandler(value); + } + + public void MapDepthPointToColorPoint( + _NUI_IMAGE_RESOLUTION eDepthResolution, + ref _NUI_DEPTH_IMAGE_POINT depthPoint, + _NUI_IMAGE_TYPE eColorType, + _NUI_IMAGE_RESOLUTION eColorResolution, + out _NUI_COLOR_IMAGE_POINT colorPoint) + { + KinectExceptionHelper.CheckHr(this._nuiCoordinateMapper.MapDepthPointToColorPoint(eDepthResolution, ref depthPoint, eColorType, eColorResolution, out colorPoint)); + } + + public unsafe void MapDepthFrameToColorFrame( + _NUI_IMAGE_RESOLUTION eDepthResolution, + DepthImagePixel[] depthPixels, + _NUI_IMAGE_TYPE eColorType, + _NUI_IMAGE_RESOLUTION eColorResolution, + ColorImagePoint[] colorPoints) + { + fixed (DepthImagePixel* pDepthPixels = depthPixels) + fixed (ColorImagePoint* pColorPoints = colorPoints) + KinectExceptionHelper.CheckHr(this._nuiCoordinateMapper.MapDepthFrameToColorFrame(eDepthResolution, (uint) depthPixels.Length, (IntPtr) (void*) pDepthPixels, eColorType, eColorResolution, (uint) colorPoints.Length, (IntPtr) (void*) pColorPoints)); + } + + public unsafe void MapColorFrameToSkeletonFrame( + _NUI_IMAGE_TYPE eColorType, + _NUI_IMAGE_RESOLUTION eColorResolution, + _NUI_IMAGE_RESOLUTION eDepthResolution, + DepthImagePixel[] depthPixels, + SkeletonPoint[] skeletonPoints) + { + fixed (DepthImagePixel* pDepthPixels = depthPixels) + fixed (SkeletonPoint* pSkeletonPoints = skeletonPoints) + KinectExceptionHelper.CheckHr(this._nuiCoordinateMapper.MapColorFrameToSkeletonFrame(eColorType, eColorResolution, eDepthResolution, (uint) depthPixels.Length, (IntPtr) (void*) pDepthPixels, (uint) skeletonPoints.Length, (IntPtr) (void*) pSkeletonPoints)); + } + + public unsafe void MapDepthFrameToSkeletonFrame( + _NUI_IMAGE_RESOLUTION eDepthResolution, + DepthImagePixel[] depthPixels, + SkeletonPoint[] skeletonPoints) + { + fixed (DepthImagePixel* pDepthPixels = depthPixels) + fixed (SkeletonPoint* pSkeletonPoints = skeletonPoints) + KinectExceptionHelper.CheckHr(this._nuiCoordinateMapper.MapDepthFrameToSkeletonFrame(eDepthResolution, (uint) depthPixels.Length, (IntPtr) (void*) pDepthPixels, (uint) skeletonPoints.Length, (IntPtr) (void*) pSkeletonPoints)); + } + + public unsafe void MapColorFrameToDepthFrame( + _NUI_IMAGE_TYPE eColorType, + _NUI_IMAGE_RESOLUTION eColorResolution, + _NUI_IMAGE_RESOLUTION eDepthResolution, + DepthImagePixel[] depthPixels, + DepthImagePoint[] depthPoints) + { + fixed (DepthImagePixel* pDepthPixels = depthPixels) + fixed (DepthImagePoint* pDepthPoints = depthPoints) + KinectExceptionHelper.CheckHr(this._nuiCoordinateMapper.MapColorFrameToDepthFrame(eColorType, eColorResolution, eDepthResolution, (uint) depthPixels.Length, (IntPtr) (void*) pDepthPixels, (uint) depthPoints.Length, (IntPtr) (void*) pDepthPoints)); + } + + int INuiCoordinateMapperParametersChangedEvent.Invoke() + { + this._relationalParametersChangedHandler.Invoke((object) this, new EventArgs()); + return 0; + } + } +} diff --git a/src/Microsoft.Kinect/NuiDepthFilter.cs b/src/Microsoft.Kinect/NuiDepthFilter.cs new file mode 100644 index 0000000..beada1f --- /dev/null +++ b/src/Microsoft.Kinect/NuiDepthFilter.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.NuiDepthFilter +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; + +namespace Microsoft.Kinect +{ + public class NuiDepthFilter : IDepthFilter + { + public object NativeObject { get; set; } + + public unsafe bool ProcessFrame( + long timestamp, + int width, + int height, + DepthImagePixel[] pixelData) + { + int num1 = 0; + INuiDepthFilter nativeObject = (INuiDepthFilter) this.NativeObject; + if (nativeObject != null) + { + fixed (DepthImagePixel* depthImagePixelPtr = pixelData) + { + IntPtr num2 = (IntPtr) (void*) depthImagePixelPtr; + INuiDepthFilter nuiDepthFilter = nativeObject; + _LARGE_INTEGER liTimeStamp = new _LARGE_INTEGER() + { + QuadPart = timestamp + }; + int Width = width; + int Height = height; + IntPtr pDepthImagePixels = num2; + ref int local = ref num1; + KinectExceptionHelper.CheckHr(nuiDepthFilter.ProcessFrame(liTimeStamp, (uint) Width, (uint) Height, pDepthImagePixels, out local)); + } + } + return num1 != 0; + } + } +} diff --git a/src/Microsoft.Kinect/NuiSensor.cs b/src/Microsoft.Kinect/NuiSensor.cs new file mode 100644 index 0000000..1e3611a --- /dev/null +++ b/src/Microsoft.Kinect/NuiSensor.cs @@ -0,0 +1,260 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.NuiSensor +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + internal class NuiSensor + { + private readonly INuiSensor _nuiSensor; + private IDepthFilter _depthFilter; + private List _depthFilters = new List(); + private INuiAudioBeam _nuiAudioSource; + private NuiCoordinateMapper _nuiCoordinateMapper; + + public NuiSensor(INuiSensor wrapped) => this._nuiSensor = wrapped; + + public int NuiInstanceIndex() => this._nuiSensor.NuiInstanceIndex(); + + public void NuiInitialize(uint dwFlags) => KinectExceptionHelper.CheckHr(this._nuiSensor.NuiInitialize(dwFlags)); + + public INuiAudioBeam NuiGetAudioSource() + { + if (this._nuiAudioSource == null) + { + Microsoft.Kinect.Interop.INuiAudioBeam ppDmo; + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiGetAudioSource(out ppDmo)); + this._nuiAudioSource = (INuiAudioBeam)new NuiAudioBeam(ppDmo); + } + return this._nuiAudioSource; + } + + public NuiCoordinateMapper NuiGetCoordinateMapper() + { + if (this._nuiCoordinateMapper == null) + { + INuiCoordinateMapper pMapping; + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiGetCoordinateMapper(out pMapping)); + this._nuiCoordinateMapper = new NuiCoordinateMapper(pMapping); + } + return this._nuiCoordinateMapper; + } + + public void NuiShutdown() + { + this._nuiAudioSource = (INuiAudioBeam)null; + this._nuiSensor.NuiShutdown(); + } + + internal bool IsSupported + { + get + { + object obj = this[NuiSensorProperty.IsSupported]; + return obj != null && obj.GetType() == typeof(bool) && (bool)obj; + } + } + + public object this[NuiSensorProperty index] + { + get + { + try + { + IPropertyStore propertyStore = (IPropertyStore)this._nuiSensor; + PROPERTYKEY propertykey; + propertykey.fmtid = new Guid("1f5e088c-a8c7-41d3-9957-209677a13e85"); + propertykey.pid = (int)index; + propertyStore.GetValue(ref propertykey, out var result); + return result; + } + catch (COMException ex) + { + return (object)null; + } + } + } + + public void NuiSetFrameEndEvent(IntPtr hEvent, uint dwFrameEventFlag) => KinectExceptionHelper.CheckHr(this._nuiSensor.NuiSetFrameEndEvent(hEvent, dwFrameEventFlag)); + + public void NuiImageStreamOpen( + _NUI_IMAGE_TYPE eImageType, + _NUI_IMAGE_RESOLUTION eResolution, + uint dwImageFrameFlags, + uint dwFrameLimit, + IntPtr hNextFrameEvent, + out IntPtr phStreamHandle) + { + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiImageStreamOpen(eImageType, eResolution, dwImageFrameFlags, dwFrameLimit, hNextFrameEvent, out phStreamHandle)); + } + + public void NuiImageStreamSetImageFrameFlags(IntPtr hStream, uint dwImageFrameFlags) => KinectExceptionHelper.CheckHr(this._nuiSensor.NuiImageStreamSetImageFrameFlags(hStream, dwImageFrameFlags)); + + public uint NuiImageStreamGetImageFrameFlags(IntPtr hStream) + { + uint pdwImageFrameFlags; + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiImageStreamGetImageFrameFlags(hStream, out pdwImageFrameFlags)); + return pdwImageFrameFlags; + } + + public int NuiImageStreamGetNextFrameNoThrow( + IntPtr hStream, + uint dwMillisecondsToWait, + out _NUI_IMAGE_FRAME pImageFrame) + { + return this._nuiSensor.NuiImageStreamGetNextFrame(hStream, dwMillisecondsToWait, out pImageFrame); + } + + public void NuiImageStreamReleaseFrame(IntPtr hStream, ref _NUI_IMAGE_FRAME pImageFrame) + { + try + { + INuiSensor nuiSensor = this._nuiSensor; + IntPtr hStream1 = hStream; + _NUI_IMAGE_FRAME nuiImageFrame = pImageFrame; + ref _NUI_IMAGE_FRAME local = ref nuiImageFrame; + nuiSensor.NuiImageStreamReleaseFrame(hStream1, ref local); + Marshal.FinalReleaseComObject((object)pImageFrame.pFrameTexture); + } + catch (COMException ex) + { + } + } + + public void NuiImageFrameGetDepthImagePixelFrameTexture( + IntPtr hStream, + ref _NUI_IMAGE_FRAME pImageFrame, + out bool nearMode, + out INuiFrameTexture ppTexture) + { + int pNearMode; + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiImageFrameGetDepthImagePixelFrameTexture(hStream, ref pImageFrame, out pNearMode, out ppTexture)); + nearMode = pNearMode != 0; + } + + public void NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution( + _NUI_IMAGE_RESOLUTION eColorResolution, + _NUI_IMAGE_RESOLUTION eDepthResolution, + ref _NUI_IMAGE_VIEW_AREA pcViewArea, + int lDepthX, + int lDepthY, + ushort usDepthValue, + out int plColorX, + out int plColorY) + { + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution(eColorResolution, eDepthResolution, ref pcViewArea, lDepthX, lDepthY, usDepthValue, out plColorX, out plColorY)); + } + + public unsafe void NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution( + _NUI_IMAGE_RESOLUTION eColorResolution, + _NUI_IMAGE_RESOLUTION eDepthResolution, + short[] depthValues, + ColorImagePoint[] colorCoordinates) + { + fixed (ColorImagePoint* pColorCoordinates = colorCoordinates) + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution(eColorResolution, eDepthResolution, (uint)depthValues.Length, depthValues, (uint)(colorCoordinates.Length * 2), (IntPtr)(void*)pColorCoordinates)); + } + + public void NuiCameraElevationSetAngle(int lAngleDegrees) => KinectExceptionHelper.CheckHr(this._nuiSensor.NuiCameraElevationSetAngle(lAngleDegrees)); + + public int NuiCameraElevationGetAngle() + { + int plAngleDegrees; + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiCameraElevationGetAngle(out plAngleDegrees)); + return plAngleDegrees; + } + + public Vector4 NuiAccelerometerGetCurrentReading() + { + _Vector4 pReading; + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiAccelerometerGetCurrentReading(out pReading)); + return Vector4.CopyFrom(ref pReading); + } + + public void NuiSkeletonTrackingEnable(IntPtr hNextFrameEvent, uint dwFlags) => KinectExceptionHelper.CheckHr(this._nuiSensor.NuiSkeletonTrackingEnable(hNextFrameEvent, dwFlags)); + + public int NuiSkeletonTrackingDisableNoThrow() => this._nuiSensor.NuiSkeletonTrackingDisable(); + + public int NuiSkeletonGetNextFrameNoThrow( + uint dwMillisecondsToWait, + ref _NUI_SKELETON_FRAME pSkeletonFrame) + { + return this._nuiSensor.NuiSkeletonGetNextFrame(dwMillisecondsToWait, ref pSkeletonFrame); + } + + public void NuiTransformSmooth( + ref _NUI_SKELETON_FRAME pSkeletonFrame, + ref _NUI_TRANSFORM_SMOOTH_PARAMETERS pSmoothingParams) + { + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiTransformSmooth(ref pSkeletonFrame, ref pSmoothingParams)); + } + + public string NuiDeviceConnectionId() => this._nuiSensor.NuiDeviceConnectionId(); + + public string NuiUniqueId() => this._nuiSensor.NuiUniqueId(); + + public string NuiAudioArrayId() => this._nuiSensor.NuiAudioArrayId(); + + public uint NuiStatus() => (uint)this._nuiSensor.NuiStatus(); + + public uint NuiInitializationFlags() => this._nuiSensor.NuiInitializationFlags(); + + public void NuiSkeletonSetTrackedSkeletons(uint trackingId1, uint trackingId2) => KinectExceptionHelper.CheckHr(this._nuiSensor.NuiSkeletonSetTrackedSkeletons(new uint[2] + { + trackingId1, + trackingId2 + })); + + public NuiColorCameraSettings NuiGetColorCameraSettings() + { + INuiColorCameraSettings pCameraSettings; + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiGetColorCameraSettings(out pCameraSettings)); + return new NuiColorCameraSettings(pCameraSettings); + } + + public bool ForceInfraredEmitterOff + { + get => this._nuiSensor.NuiGetForceInfraredEmitterOff() != 0; + set => KinectExceptionHelper.CheckHr(this._nuiSensor.NuiSetForceInfraredEmitterOff(value ? 1 : 0)); + } + + public IDepthFilter DepthFilter + { + get => this._depthFilter; + set + { + if (value?.NativeObject is not INuiDepthFilter pDepthFilter) + throw new ArgumentException(Resources.DepthFilterMustImplementNativeInterface, nameof(value)); + KinectExceptionHelper.CheckHr(this._nuiSensor.NuiSetDepthFilter(pDepthFilter)); + this._depthFilter = value; + if (value == null || this._depthFilters.Contains(value)) + return; + this._depthFilters.Add(value); + } + } + + public IDepthFilter GetDepthFilterForTimestamp(long timestamp) + { + INuiDepthFilter ppDepthFilter; + if (this._nuiSensor.NuiGetDepthFilterForTimeStamp(new _LARGE_INTEGER() + { + QuadPart = timestamp + }, out ppDepthFilter) == 0 && ppDepthFilter != null) + { + foreach (IDepthFilter depthFilter in this._depthFilters) + { + if (depthFilter.NativeObject as INuiDepthFilter == ppDepthFilter) + return depthFilter; + } + } + return (IDepthFilter)null; + } + } +} diff --git a/src/Microsoft.Kinect/NuiSensorProperty.cs b/src/Microsoft.Kinect/NuiSensorProperty.cs new file mode 100644 index 0000000..e822f24 --- /dev/null +++ b/src/Microsoft.Kinect/NuiSensorProperty.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.NuiSensorProperty +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + internal enum NuiSensorProperty + { + Default, + IsSupported, + } +} diff --git a/src/Microsoft.Kinect/PROPERTYKEY.cs b/src/Microsoft.Kinect/PROPERTYKEY.cs new file mode 100644 index 0000000..6aa2371 --- /dev/null +++ b/src/Microsoft.Kinect/PROPERTYKEY.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.PROPERTYKEY +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + internal struct PROPERTYKEY + { + public Guid fmtid; + public int pid; + } +} diff --git a/src/Microsoft.Kinect/PowerLineFrequency.cs b/src/Microsoft.Kinect/PowerLineFrequency.cs new file mode 100644 index 0000000..d90da44 --- /dev/null +++ b/src/Microsoft.Kinect/PowerLineFrequency.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.PowerLineFrequency +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum PowerLineFrequency + { + Disabled, + FiftyHertz, + SixtyHertz, + } +} diff --git a/src/Microsoft.Kinect/ReaderWriterLockSlimExtensionMethods.cs b/src/Microsoft.Kinect/ReaderWriterLockSlimExtensionMethods.cs new file mode 100644 index 0000000..6fc7161 --- /dev/null +++ b/src/Microsoft.Kinect/ReaderWriterLockSlimExtensionMethods.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ReaderWriterLockSlimExtensionMethods +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Threading; + +namespace Microsoft.Kinect +{ + internal static class ReaderWriterLockSlimExtensionMethods + { + public static AutoLock EnterReadLockAuto(this ReaderWriterLockSlim readerWriterLock) => new AutoLock(readerWriterLock, AutoLock.AutoLockMode.Read); + + public static AutoLock EnterUpgradeableReadLockAuto(this ReaderWriterLockSlim readerWriterLock) => new AutoLock(readerWriterLock, AutoLock.AutoLockMode.UpgradeableRead); + + public static AutoLock EnterWriteLockAuto(this ReaderWriterLockSlim readerWriterLock) => new AutoLock(readerWriterLock, AutoLock.AutoLockMode.Write); + } +} diff --git a/src/Microsoft.Kinect/Resources.cs b/src/Microsoft.Kinect/Resources.cs new file mode 100644 index 0000000..8c24033 --- /dev/null +++ b/src/Microsoft.Kinect/Resources.cs @@ -0,0 +1,118 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Resources +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.CodeDom.Compiler; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.Resources; +using System.Runtime.CompilerServices; + +namespace Microsoft.Kinect +{ + [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [DebuggerNonUserCode] + [CompilerGenerated] + internal class Resources + { + private static ResourceManager resourceMan; + private static CultureInfo resourceCulture; + + internal Resources() + { + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static ResourceManager ResourceManager + { + get + { + if (object.ReferenceEquals((object) Microsoft.Kinect.Resources.resourceMan, (object) null)) + Microsoft.Kinect.Resources.resourceMan = new ResourceManager("Microsoft.Kinect.Resources", typeof (Microsoft.Kinect.Resources).Assembly); + return Microsoft.Kinect.Resources.resourceMan; + } + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static CultureInfo Culture + { + get => Microsoft.Kinect.Resources.resourceCulture; + set => Microsoft.Kinect.Resources.resourceCulture = value; + } + + internal static string BadIndex => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (BadIndex), Microsoft.Kinect.Resources.resourceCulture); + + internal static string CannotPollAndUseEvents => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (CannotPollAndUseEvents), Microsoft.Kinect.Resources.resourceCulture); + + internal static string CaptureAlreadyStarted => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (CaptureAlreadyStarted), Microsoft.Kinect.Resources.resourceCulture); + + internal static string CaptureNotStarted => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (CaptureNotStarted), Microsoft.Kinect.Resources.resourceCulture); + + internal static string ColorStreamMustBeEnabled => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (ColorStreamMustBeEnabled), Microsoft.Kinect.Resources.resourceCulture); + + internal static string DepthFilterMustImplementNativeInterface => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (DepthFilterMustImplementNativeInterface), Microsoft.Kinect.Resources.resourceCulture); + + internal static string DepthStreamMustBeEnabled => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (DepthStreamMustBeEnabled), Microsoft.Kinect.Resources.resourceCulture); + + internal static string DeviceNotGenuine => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (DeviceNotGenuine), Microsoft.Kinect.Resources.resourceCulture); + + internal static string DeviceNotSupported => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (DeviceNotSupported), Microsoft.Kinect.Resources.resourceCulture); + + internal static string ElevationIncorrect => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (ElevationIncorrect), Microsoft.Kinect.Resources.resourceCulture); + + internal static string FailedToGetDeviceName => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (FailedToGetDeviceName), Microsoft.Kinect.Resources.resourceCulture); + + internal static string GenericException => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (GenericException), Microsoft.Kinect.Resources.resourceCulture); + + internal static string HardwareFeatureUnavailable => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (HardwareFeatureUnavailable), Microsoft.Kinect.Resources.resourceCulture); + + internal static string ImageFormatNotSupported => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (ImageFormatNotSupported), Microsoft.Kinect.Resources.resourceCulture); + + internal static string ImageFrameNotDisposed => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (ImageFrameNotDisposed), Microsoft.Kinect.Resources.resourceCulture); + + internal static string IncorrectJointType => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (IncorrectJointType), Microsoft.Kinect.Resources.resourceCulture); + + internal static string InvalidBeamAngleMode => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (InvalidBeamAngleMode), Microsoft.Kinect.Resources.resourceCulture); + + internal static string InvalidEchoCancellationMode => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (InvalidEchoCancellationMode), Microsoft.Kinect.Resources.resourceCulture); + + internal static string KinectInUse => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (KinectInUse), Microsoft.Kinect.Resources.resourceCulture); + + internal static string KinectMustBeRunning => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (KinectMustBeRunning), Microsoft.Kinect.Resources.resourceCulture); + + internal static string KinectNotReady => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (KinectNotReady), Microsoft.Kinect.Resources.resourceCulture); + + internal static string KinectNotSupportedDeveloper => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (KinectNotSupportedDeveloper), Microsoft.Kinect.Resources.resourceCulture); + + internal static string KinectNotSupportedNonDeveloper => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (KinectNotSupportedNonDeveloper), Microsoft.Kinect.Resources.resourceCulture); + + internal static string NativeStreamCantBeZero => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (NativeStreamCantBeZero), Microsoft.Kinect.Resources.resourceCulture); + + internal static string NeedFeatureMode => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (NeedFeatureMode), Microsoft.Kinect.Resources.resourceCulture); + + internal static string NoDevicesFound => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (NoDevicesFound), Microsoft.Kinect.Resources.resourceCulture); + + internal static string NotSupported => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (NotSupported), Microsoft.Kinect.Resources.resourceCulture); + + internal static string PixelBufferIncorrectLength => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (PixelBufferIncorrectLength), Microsoft.Kinect.Resources.resourceCulture); + + internal static string SensorMustBeRunning => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (SensorMustBeRunning), Microsoft.Kinect.Resources.resourceCulture); + + internal static string SensorMustBeRunningForAudio => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (SensorMustBeRunningForAudio), Microsoft.Kinect.Resources.resourceCulture); + + internal static string SkeletonBufferIncorrectLength => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (SkeletonBufferIncorrectLength), Microsoft.Kinect.Resources.resourceCulture); + + internal static string SkeletonEngineMustBeEnabled => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (SkeletonEngineMustBeEnabled), Microsoft.Kinect.Resources.resourceCulture); + + internal static string SkeletonFrameNotDisposed => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (SkeletonFrameNotDisposed), Microsoft.Kinect.Resources.resourceCulture); + + internal static string UnauthorizedAccess => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (UnauthorizedAccess), Microsoft.Kinect.Resources.resourceCulture); + + internal static string UnexpectedDepthRange => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (UnexpectedDepthRange), Microsoft.Kinect.Resources.resourceCulture); + + internal static string UnexpectedUniqueDeviceName => Microsoft.Kinect.Resources.ResourceManager.GetString(nameof (UnexpectedUniqueDeviceName), Microsoft.Kinect.Resources.resourceCulture); + } +} diff --git a/src/Microsoft.Kinect/Resources.resx b/src/Microsoft.Kinect/Resources.resx new file mode 100644 index 0000000..f4ce6ba --- /dev/null +++ b/src/Microsoft.Kinect/Resources.resx @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + A bad index or id was used when referencing a Kinect sensor. + + + Depth filter must implement the native INuiDepthFilter interface + + + Could not access the hardware + + + Kinect is already in use in another process. + + + Unexpected value for EchoCancellationMode + + + Native DLL failed in get device name + + + Unexpected value for BeamAngleMode + + + The capture has not been started + + + The Kinect sensor plugged into your computer is for use on the Xbox 360. +You may continue using your Xbox 360 Kinect sensor on your computer for development purposes. +Microsoft does not guarantee full compatibility for Kinect for Windows applications and the Xbox 360 Kinect Sensor. + + + This Depth Stream must be Enabled to get next Depth image frame. Call KinectSensor.DepthStream.Enable() + + + The operation is not supported + + + This API cannot be called when an event listener has been set. + + + The specified Image Format is not supported. + + + Kinect must be running to control the motor + + + The Kinect sensor plugged into your computer is for use on the Xbox 360. +To run a Kinect for Windows application, you must plug in a Kinect for Windows sensor. + + + The feature is not supported by this version of the hardware + + + JointType index value must match Joint.JointType + + + Kinect is not ready + + + KinectSensor must be running in order to start audio stream + + + Could not find a Kinect audio device + + + Unexpected UniqueDeviceName format + + + The data buffer length must match the length required by the associated ImageFormat. + + + The Color Stream must be Enabled to get next Color image frame. Call KinectSensor.ColorStream.Enable() + + + NativeStreamHandle can't be Zero + + + The capture has already been started + + + Warning: A SkeletonFrame instance was not Disposed. + + + Unexpected depth range + + + The attached Kinect device is not supported. + + + KinectSensor must be running to get next frame. Call KinectSensor.Start() + + + Feature mode needs to be set to True before setting this property + + + The attached Kinect device is not genuine. + + + SkeletonEngine must be Enabled to get next skeleton frame. Call KinectSensor.SkeletonEngine.Enable() + + + Elevation angle must be between Elevation Minimum/Maximum + + + The data buffer must have length equal to SkeletonArrayLength. + + + This API has returned an exception from an HRESULT: 0x{0:X} + + + Warning: An ImageFrame instance was not Disposed. + + \ No newline at end of file diff --git a/src/Microsoft.Kinect/Skeleton.cs b/src/Microsoft.Kinect/Skeleton.cs new file mode 100644 index 0000000..2627d0d --- /dev/null +++ b/src/Microsoft.Kinect/Skeleton.cs @@ -0,0 +1,163 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Skeleton +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Xml.Serialization; + +namespace Microsoft.Kinect +{ + [Serializable] + public class Skeleton + { + internal static readonly Array JointTypeValues = Enum.GetValues(typeof (JointType)); + [XmlIgnore] + [NonSerialized] + private BoneOrientationCollection _boneOrientations; + + internal Skeleton(_NUI_SKELETON_DATA nativeSkeleton) => this.CopyFrom(nativeSkeleton); + + internal Skeleton(Skeleton sourceData) => this.CopyFrom(sourceData); + + public Skeleton() + { + this.Joints = new JointCollection(this); + Joint joint = new Joint(); + foreach (JointType jointTypeValue in Skeleton.JointTypeValues) + { + joint.JointType = jointTypeValue; + this.Joints[jointTypeValue] = joint; + } + } + + public SkeletonTrackingState TrackingState { get; set; } + + public int TrackingId { get; set; } + + public SkeletonPoint Position { get; set; } + + public JointCollection Joints { get; protected set; } + + public BoneOrientationCollection BoneOrientations + { + get + { + if (this._boneOrientations == null) + this._boneOrientations = new BoneOrientationCollection(this); + this._boneOrientations.Recalculate(); + return this._boneOrientations; + } + protected set => this._boneOrientations = value; + } + + public FrameEdges ClippedEdges { get; set; } + + internal void CopyFrom(_NUI_SKELETON_DATA nativeSkeleton) + { + this.TrackingState = (SkeletonTrackingState) nativeSkeleton.eTrackingState; + this.TrackingId = (int) nativeSkeleton.dwTrackingID; + this.Position = new SkeletonPoint() + { + X = nativeSkeleton.Position.x, + Y = nativeSkeleton.Position.y, + Z = nativeSkeleton.Position.z + }; + this.ClippedEdges = (FrameEdges) nativeSkeleton.dwQualityFlags; + this.Joints = new JointCollection(this); + Joint joint = new Joint(); + foreach (JointType jointTypeValue in Skeleton.JointTypeValues) + { + joint.JointType = jointTypeValue; + joint.TrackingState = (JointTrackingState) nativeSkeleton.eSkeletonPositionTrackingState[(int) jointTypeValue]; + _Vector4 skeletonPosition = nativeSkeleton.SkeletonPositions[(int) jointTypeValue]; + joint.Position = new SkeletonPoint() + { + X = skeletonPosition.x, + Y = skeletonPosition.y, + Z = skeletonPosition.z + }; + this.Joints[jointTypeValue] = joint; + } + } + + internal void CopyFrom(Skeleton sourceData) + { + this.TrackingState = sourceData.TrackingState; + this.TrackingId = sourceData.TrackingId; + this.Position = sourceData.Position; + this.ClippedEdges = sourceData.ClippedEdges; + if (this.Joints == null) + this.Joints = new JointCollection(this); + foreach (JointType jointTypeValue in Skeleton.JointTypeValues) + this.Joints[jointTypeValue] = new Joint() + { + Position = sourceData.Joints[jointTypeValue].Position, + JointType = sourceData.Joints[jointTypeValue].JointType, + TrackingState = sourceData.Joints[jointTypeValue].TrackingState + }; + if (sourceData._boneOrientations != null && sourceData._boneOrientations.IsValid) + { + if (this._boneOrientations == null) + this._boneOrientations = new BoneOrientationCollection(this); + this._boneOrientations.IsValid = true; + foreach (JointType jointTypeValue in Skeleton.JointTypeValues) + { + BoneOrientation boneOrientation = new BoneOrientation(jointTypeValue); + boneOrientation.CopyFrom(sourceData._boneOrientations[jointTypeValue]); + this._boneOrientations[jointTypeValue] = boneOrientation; + } + } + else + this._boneOrientations = (BoneOrientationCollection) null; + } + + internal void InvalidateBoneOrientations() + { + if (this._boneOrientations == null) + return; + this._boneOrientations.Invalidate(); + } + + internal bool CalculateBoneOrientations(BoneOrientation[] boneOrientations) + { + if (this.TrackingState != SkeletonTrackingState.NotTracked && (this.Joints[JointType.HipCenter].TrackingState != JointTrackingState.NotTracked || this.Joints[JointType.ShoulderCenter].TrackingState != JointTrackingState.NotTracked)) + { + _NUI_SKELETON_DATA pSkeletonData = new _NUI_SKELETON_DATA(); + pSkeletonData.eTrackingState = _NUI_SKELETON_TRACKING_STATE.NUI_SKELETON_TRACKED; + pSkeletonData.dwTrackingID = (uint) this.TrackingId; + pSkeletonData.Position.x = this.Position.X; + pSkeletonData.Position.y = this.Position.Y; + pSkeletonData.Position.z = this.Position.Z; + pSkeletonData.eSkeletonPositionTrackingState = new _NUI_SKELETON_POSITION_TRACKING_STATE[Skeleton.JointTypeValues.Length]; + pSkeletonData.SkeletonPositions = new _Vector4[Skeleton.JointTypeValues.Length]; + foreach (JointType jointTypeValue in Skeleton.JointTypeValues) + { + if (this.Joints[jointTypeValue].TrackingState == JointTrackingState.NotTracked) + { + pSkeletonData.eSkeletonPositionTrackingState[(int) jointTypeValue] = _NUI_SKELETON_POSITION_TRACKING_STATE.NUI_SKELETON_POSITION_NOT_TRACKED; + } + else + { + Joint joint = this.Joints[jointTypeValue]; + pSkeletonData.eSkeletonPositionTrackingState[(int) jointTypeValue] = joint.TrackingState != JointTrackingState.Inferred ? _NUI_SKELETON_POSITION_TRACKING_STATE.NUI_SKELETON_POSITION_TRACKED : _NUI_SKELETON_POSITION_TRACKING_STATE.NUI_SKELETON_POSITION_INFERRED; + } + pSkeletonData.SkeletonPositions[(int) jointTypeValue].x = this.Joints[jointTypeValue].Position.X; + pSkeletonData.SkeletonPositions[(int) jointTypeValue].y = this.Joints[jointTypeValue].Position.Y; + pSkeletonData.SkeletonPositions[(int) jointTypeValue].z = this.Joints[jointTypeValue].Position.Z; + } + _NUI_SKELETON_BONE_ORIENTATION[] pBoneOrientations = new _NUI_SKELETON_BONE_ORIENTATION[Skeleton.JointTypeValues.Length]; + int boneOrientations1 = NativeMethods.NuiSkeletonCalculateBoneOrientations(ref pSkeletonData, pBoneOrientations); + foreach (JointType jointTypeValue in Skeleton.JointTypeValues) + boneOrientations[(int) jointTypeValue].CopyFrom(ref pBoneOrientations[(int) jointTypeValue]); + if (boneOrientations1 == 0) + return true; + } + foreach (BoneOrientation boneOrientation in boneOrientations) + boneOrientation.SetDefaults(); + return false; + } + } +} diff --git a/src/Microsoft.Kinect/SkeletonFrame.cs b/src/Microsoft.Kinect/SkeletonFrame.cs new file mode 100644 index 0000000..96482c4 --- /dev/null +++ b/src/Microsoft.Kinect/SkeletonFrame.cs @@ -0,0 +1,108 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SkeletonFrame +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Diagnostics; +using System.Globalization; +using System.Threading; + +namespace Microsoft.Kinect +{ + public sealed class SkeletonFrame : IDisposable + { + private readonly SkeletonStream _skeletonStream; + private DataPool, object, Skeleton[], bool?>.Entry _skeletonData; + private readonly object _dataAccessLock = new object(); + private int _isDisposed; + + private SkeletonFrame( + SkeletonStream skeletonStream, + int frameNumber, + long timestamp, + SkeletonTrackingMode trackingMode, + DataPool, object, Skeleton[], bool?>.Entry skeletonData) + { + this._skeletonStream = skeletonStream; + this._skeletonData = skeletonData; + this.FrameNumber = frameNumber; + this.Timestamp = timestamp; + this.TrackingMode = trackingMode; + this.FloorClipPlane = skeletonData.Value1; + this._skeletonData = skeletonData; + } + + internal static SkeletonFrame Create( + SkeletonStream skeletonStream, + int frameNumber, + long timestamp, + SkeletonTrackingMode trackingMode) + { + SkeletonFrame skeletonFrame = (SkeletonFrame) null; + DataPool, object, Skeleton[], bool?>.Entry skeletonData = skeletonStream.LockSkeletonData(frameNumber); + if (skeletonData != null) + skeletonFrame = new SkeletonFrame(skeletonStream, frameNumber, timestamp, trackingMode, skeletonData); + return skeletonFrame; + } + + public long Timestamp { get; set; } + + public int FrameNumber { get; set; } + + [Obsolete("SkeletonFrame.TrackingMode property is reserved for future use. Do not use this property; this value may change in a future release.", false)] + public SkeletonTrackingMode TrackingMode { get; private set; } + + public Tuple FloorClipPlane { get; set; } + + public int SkeletonArrayLength => 6; + + public IDepthFilter DepthFilter => this._skeletonStream.Sensor.NuiSensor.GetDepthFilterForTimestamp(this.Timestamp); + + public void CopySkeletonDataTo(Skeleton[] skeletonData) + { + if (skeletonData == null) + throw new ArgumentNullException(nameof (skeletonData)); + if (skeletonData.Length != this._skeletonData.Value3.Length) + throw new ArgumentException(Resources.SkeletonBufferIncorrectLength, nameof (skeletonData)); + lock (this._dataAccessLock) + { + if (this._skeletonData == null) + throw new ObjectDisposedException(nameof (SkeletonFrame)); + for (int index = 0; index < this._skeletonData.Value3.Length; ++index) + { + if (skeletonData[index] == null) + skeletonData[index] = new Skeleton(this._skeletonData.Value3[index]); + else + skeletonData[index].CopyFrom(this._skeletonData.Value3[index]); + } + } + } + + public void Dispose() + { + if (Interlocked.Exchange(ref this._isDisposed, 1) != 0) + return; + this.Dispose(true); + GC.SuppressFinalize((object) this); + } + + ~SkeletonFrame() + { + Debugger.Log(0, "Performance", string.Format((IFormatProvider) CultureInfo.InvariantCulture, "{0}\n", (object) Resources.SkeletonFrameNotDisposed)); + this.Dispose(false); + } + + private void Dispose(bool disposing) + { + if (!disposing) + return; + lock (this._dataAccessLock) + { + this._skeletonStream.UnlockSkeletonData(this._skeletonData); + this._skeletonData = (DataPool, object, Skeleton[], bool?>.Entry) null; + } + } + } +} diff --git a/src/Microsoft.Kinect/SkeletonFrameReadyEventArgs.cs b/src/Microsoft.Kinect/SkeletonFrameReadyEventArgs.cs new file mode 100644 index 0000000..f4f926f --- /dev/null +++ b/src/Microsoft.Kinect/SkeletonFrameReadyEventArgs.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SkeletonFrameReadyEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + public sealed class SkeletonFrameReadyEventArgs : EventArgs + { + private readonly SkeletonStream _skeletonStream; + private readonly int _frameNumber; + private readonly long _timestamp; + private readonly SkeletonTrackingMode _trackingMode; + private bool _isInvalid; + + private SkeletonFrameReadyEventArgs( + SkeletonStream skeletonStream, + int frameNumber, + long timestamp, + SkeletonTrackingMode trackingMode, + bool isInvalid) + { + this._skeletonStream = skeletonStream; + this._frameNumber = frameNumber; + this._timestamp = timestamp; + this._trackingMode = trackingMode; + this._isInvalid = isInvalid; + } + + internal static SkeletonFrameReadyEventArgs Create( + SkeletonStream skeletonImageStream, + int frameNumber, + long timestamp, + SkeletonTrackingMode trackingMode) + { + return new SkeletonFrameReadyEventArgs(skeletonImageStream, frameNumber, timestamp, trackingMode, false); + } + + internal static SkeletonFrameReadyEventArgs CreateInvalid() => new SkeletonFrameReadyEventArgs((SkeletonStream) null, 0, 0L, SkeletonTrackingMode.Default, true); + + public SkeletonFrame OpenSkeletonFrame() + { + if (this._isInvalid) + return (SkeletonFrame) null; + KinectEtwProvider.EventWriteManagedOpenFrameFromEventInfo(2); + SkeletonFrame skeletonFrame = SkeletonFrame.Create(this._skeletonStream, this._frameNumber, this._timestamp, this._trackingMode); + if (skeletonFrame == null) + this._isInvalid = true; + return skeletonFrame; + } + } +} diff --git a/src/Microsoft.Kinect/SkeletonPoint.cs b/src/Microsoft.Kinect/SkeletonPoint.cs new file mode 100644 index 0000000..51ece3c --- /dev/null +++ b/src/Microsoft.Kinect/SkeletonPoint.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SkeletonPoint +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [DebuggerDisplay("X:{X} Y:{Y} Z:{Z}")] + [Serializable] + [StructLayout(LayoutKind.Sequential, Size = 16, Pack = 4)] + public struct SkeletonPoint + { + public float X { get; set; } + + public float Y { get; set; } + + public float Z { get; set; } + + public override bool Equals(object obj) => obj is SkeletonPoint skeletonPoint && this.Equals(skeletonPoint); + + public bool Equals(SkeletonPoint skeletonPoint) => this.X.Equals(skeletonPoint.X) && this.Y.Equals(skeletonPoint.Y) && this.Z.Equals(skeletonPoint.Z); + + public override int GetHashCode() => this.X.GetHashCode() + this.Y.GetHashCode() + this.Z.GetHashCode(); + + public static bool operator ==(SkeletonPoint skeletonPoint1, SkeletonPoint skeletonPoint2) => skeletonPoint1.Equals(skeletonPoint2); + + public static bool operator !=(SkeletonPoint skeletonPoint1, SkeletonPoint skeletonPoint2) => !skeletonPoint1.Equals(skeletonPoint2); + } +} diff --git a/src/Microsoft.Kinect/SkeletonStream.cs b/src/Microsoft.Kinect/SkeletonStream.cs new file mode 100644 index 0000000..b6a0516 --- /dev/null +++ b/src/Microsoft.Kinect/SkeletonStream.cs @@ -0,0 +1,271 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SkeletonStream +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; +using System; +using System.Threading; + +namespace Microsoft.Kinect +{ + public sealed class SkeletonStream + { + private const uint NUI_SKELETON_FRAME_FLAG_SEATED_SUPPORT_ENABLED = 8; + private const uint NUI_SKELETON_TRACKING_FLAG_SUPPRESS_NO_FRAME_DATA = 1; + private const uint NUI_SKELETON_TRACKING_FLAG_TITLE_SETS_TRACKED_SKELETONS = 2; + private const uint NUI_SKELETON_TRACKING_FLAG_ENABLE_SEATED_SUPPORT = 4; + private const uint NUI_SKELETON_TRACKING_FLAG_ENABLE_IN_NEAR_RANGE = 8; + internal const int s_skeletonCount = 6; + private readonly KinectSensor _nuiSensor; + private readonly DataPool, object, Skeleton[]> _skeletonDataPool; + internal ManualResetEvent NextSkeletonEvent = new ManualResetEvent(false); + private bool _isEnabled; + private bool _appChoosesSkeletons; + private SkeletonTrackingMode _trackingMode; + private bool _enableTrackingInNearRange; + private bool _isTracking; + + internal KinectSensor Sensor => this._nuiSensor; + + internal SkeletonStream(KinectSensor mainNui) + { + this._nuiSensor = mainNui; + this._isEnabled = false; + this._skeletonDataPool = new DataPool, object, Skeleton[]>(2); + } + + public bool IsEnabled + { + get => this._isEnabled; + private set + { + if (this._isEnabled == value) + return; + if (this._nuiSensor.IsRunning && !value) + this.StopTracking(); + this._isEnabled = value; + } + } + + public bool AppChoosesSkeletons + { + get => this._appChoosesSkeletons; + set + { + if (this._appChoosesSkeletons == value) + return; + this._appChoosesSkeletons = value; + if (!this._isTracking) + return; + this.StartTracking(); + } + } + + public SkeletonTrackingMode TrackingMode + { + get => this._trackingMode; + set + { + if (this._trackingMode == value) + return; + this._trackingMode = value; + if (!this._isTracking) + return; + this.StartTracking(); + } + } + + public bool EnableTrackingInNearRange + { + get => this._enableTrackingInNearRange; + set + { + if (this._enableTrackingInNearRange == value) + return; + this._enableTrackingInNearRange = value; + if (!this._isTracking) + return; + this.StartTracking(); + } + } + + public void Enable() + { + this.SetSmoothingState(false, new TransformSmoothParameters()); + this.SetEnabledState(true); + } + + public void Enable(TransformSmoothParameters smoothParameters) + { + if ((double) smoothParameters.Smoothing < 0.0 || (double) smoothParameters.Smoothing >= 1.0 || (double) smoothParameters.Correction < 0.0 || (double) smoothParameters.Correction > 1.0 || (double) smoothParameters.Prediction < 0.0 || (double) smoothParameters.JitterRadius < 0.0 || (double) smoothParameters.MaxDeviationRadius < 0.0) + throw new ArgumentOutOfRangeException(nameof (smoothParameters)); + if (this.IsEnabled && smoothParameters != this.SmoothParameters) + this.SetEnabledState(false); + this.SetSmoothingState(true, smoothParameters); + this.SetEnabledState(true); + } + + public void Disable() + { + this.SetSmoothingState(false, new TransformSmoothParameters()); + this.SetEnabledState(false); + } + + private void SetEnabledState(bool enable) + { + this.IsEnabled = enable; + this._nuiSensor.RequestSkeletonEngine(enable); + } + + private void SetSmoothingState(bool enable, TransformSmoothParameters smoothParameters) + { + this.IsSmoothingEnabled = enable; + this.SmoothParameters = smoothParameters; + } + + public void ChooseSkeletons() => this.ChooseSkeletons(0, 0); + + public void ChooseSkeletons(int trackingId1) => this.ChooseSkeletons(trackingId1, 0); + + public void ChooseSkeletons(int trackingId1, int trackingId2) => this._nuiSensor.NuiSensor.NuiSkeletonSetTrackedSkeletons((uint) trackingId1, (uint) trackingId2); + + private void StartTracking() + { + uint dwFlags = 1; + if (this._trackingMode == SkeletonTrackingMode.Seated) + dwFlags |= 4U; + if (this._enableTrackingInNearRange) + dwFlags |= 8U; + if (this._appChoosesSkeletons) + dwFlags |= 2U; + this._nuiSensor.NuiSensor.NuiSkeletonTrackingEnable(this.NextSkeletonEvent.SafeWaitHandle.DangerousGetHandle(), dwFlags); + this._isTracking = true; + } + + private void StopTracking() + { + this._nuiSensor.NuiSensor.NuiSkeletonTrackingDisableNoThrow(); + this._isTracking = false; + } + + internal void Start() + { + if (!this._isEnabled) + return; + this.StartTracking(); + } + + internal void Stop() + { + if (!this._isTracking) + return; + this.StopTracking(); + } + + public TransformSmoothParameters SmoothParameters { get; private set; } + + public bool IsSmoothingEnabled { get; private set; } + + public int FrameSkeletonArrayLength => 6; + + public SkeletonFrame OpenNextFrame(int millisecondsWait) + { + SkeletonFrame skeletonFrame = (SkeletonFrame) null; + if (!this._nuiSensor.IsRunning) + throw new InvalidOperationException(Resources.SensorMustBeRunning); + if (!this._isEnabled) + throw new InvalidOperationException(Resources.SkeletonEngineMustBeEnabled); + if (this._nuiSensor.HasSkeletonInvocations) + throw new InvalidOperationException(Resources.CannotPollAndUseEvents); + KinectEtwProvider.EventWriteManagedOpenNextFrameInfo(2, millisecondsWait); + int frameNumber; + long timestamp; + SkeletonTrackingMode trackingMode; + if (this.TryGetNextFrameInternal(millisecondsWait, out frameNumber, out timestamp, out trackingMode)) + skeletonFrame = SkeletonFrame.Create(this, frameNumber, timestamp, trackingMode); + return skeletonFrame; + } + + internal void StoreSkeletonData( + int frameNumber, + _NUI_SKELETON_FRAME skeletonData, + Tuple floorClipPlane) + { + DataPool, object, Skeleton[], bool?>.Entry entry = this._skeletonDataPool.CheckOutFreeEntryForUpdate(); + entry.Key = frameNumber; + entry.Value1 = floorClipPlane; + if (entry.Value3 == null || entry.Value3.Length != skeletonData.SkeletonData.Length) + entry.Value3 = new Skeleton[skeletonData.SkeletonData.Length]; + for (int index = 0; index < entry.Value3.Length; ++index) + { + if (entry.Value3[index] == null) + entry.Value3[index] = new Skeleton(skeletonData.SkeletonData[index]); + else + entry.Value3[index].CopyFrom(skeletonData.SkeletonData[index]); + } + this._skeletonDataPool.CheckInEntryForUpdate(entry); + } + + internal bool TryGetNextFrameInternal( + int millisecondsWait, + out int frameNumber, + out long timestamp, + out SkeletonTrackingMode trackingMode) + { + frameNumber = 0; + timestamp = 0L; + trackingMode = SkeletonTrackingMode.Default; + _NUI_SKELETON_FRAME pSkeletonFrame = new _NUI_SKELETON_FRAME(); + int nextFrameNoThrow = this._nuiSensor.NuiSensor.NuiSkeletonGetNextFrameNoThrow((uint) millisecondsWait, ref pSkeletonFrame); + if (nextFrameNoThrow < 0) + { + this.NextSkeletonEvent.Reset(); + return false; + } + if (nextFrameNoThrow != 0) + return false; + if (this.IsSmoothingEnabled) + { + _NUI_TRANSFORM_SMOOTH_PARAMETERS pSmoothingParams = new _NUI_TRANSFORM_SMOOTH_PARAMETERS() + { + fSmoothing = this.SmoothParameters.Smoothing, + fCorrection = this.SmoothParameters.Correction, + fPrediction = this.SmoothParameters.Prediction, + fJitterRadius = this.SmoothParameters.JitterRadius, + fMaxDeviationRadius = this.SmoothParameters.MaxDeviationRadius + }; + this._nuiSensor.NuiSensor.NuiTransformSmooth(ref pSkeletonFrame, ref pSmoothingParams); + } + frameNumber = (int) pSkeletonFrame.dwFrameNumber; + timestamp = pSkeletonFrame.liTimeStamp.QuadPart; + if (((int) pSkeletonFrame.dwFlags & 8) != 0) + trackingMode = SkeletonTrackingMode.Seated; + Tuple floorClipPlane = new Tuple(pSkeletonFrame.vFloorClipPlane.x, pSkeletonFrame.vFloorClipPlane.y, pSkeletonFrame.vFloorClipPlane.z, pSkeletonFrame.vFloorClipPlane.w); + this.StoreSkeletonData(frameNumber, pSkeletonFrame, floorClipPlane); + return true; + } + + internal DataPool, object, Skeleton[], bool?>.Entry LockSkeletonData( + int frameNumber) + { + DataPool, object, Skeleton[], bool?>.Entry entry; + this._skeletonDataPool.TryLockEntry(frameNumber, out entry); + return entry; + } + + internal void UnlockSkeletonData( + DataPool, object, Skeleton[], bool?>.Entry entry) + { + this._skeletonDataPool.UnlockEntry(entry); + } + + internal void Dispose() + { + if (this.NextSkeletonEvent == null) + return; + this.NextSkeletonEvent.Close(); + } + } +} diff --git a/src/Microsoft.Kinect/SkeletonTrackingMode.cs b/src/Microsoft.Kinect/SkeletonTrackingMode.cs new file mode 100644 index 0000000..de7a075 --- /dev/null +++ b/src/Microsoft.Kinect/SkeletonTrackingMode.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SkeletonTrackingMode +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum SkeletonTrackingMode + { + Default, + Seated, + } +} diff --git a/src/Microsoft.Kinect/SkeletonTrackingState.cs b/src/Microsoft.Kinect/SkeletonTrackingState.cs new file mode 100644 index 0000000..9f58a41 --- /dev/null +++ b/src/Microsoft.Kinect/SkeletonTrackingState.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SkeletonTrackingState +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + public enum SkeletonTrackingState + { + NotTracked, + PositionOnly, + Tracked, + } +} diff --git a/src/Microsoft.Kinect/SoundSourceAngleChangedEventArgs.cs b/src/Microsoft.Kinect/SoundSourceAngleChangedEventArgs.cs new file mode 100644 index 0000000..38308e2 --- /dev/null +++ b/src/Microsoft.Kinect/SoundSourceAngleChangedEventArgs.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SoundSourceAngleChangedEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + public sealed class SoundSourceAngleChangedEventArgs : EventArgs + { + internal SoundSourceAngleChangedEventArgs() + { + } + + public double Angle { get; internal set; } + + public double ConfidenceLevel { get; internal set; } + } +} diff --git a/src/Microsoft.Kinect/SpeakerDevice.cs b/src/Microsoft.Kinect/SpeakerDevice.cs new file mode 100644 index 0000000..32668c6 --- /dev/null +++ b/src/Microsoft.Kinect/SpeakerDevice.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.SpeakerDevice +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SpeakerDevice + { + private const int MaxStrLen = 512; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] + public string DeviceName; + [MarshalAs(UnmanagedType.I4)] + public int DeviceIndex; + [MarshalAs(UnmanagedType.Bool)] + public bool IsDefault; + } +} diff --git a/src/Microsoft.Kinect/StaticMediaBuffer.cs b/src/Microsoft.Kinect/StaticMediaBuffer.cs new file mode 100644 index 0000000..d675a5b --- /dev/null +++ b/src/Microsoft.Kinect/StaticMediaBuffer.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.StaticMediaBuffer +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [ComVisible(true)] + [StructLayout(LayoutKind.Sequential)] + internal class StaticMediaBuffer : IMediaBuffer + { + private readonly IntPtr _pData; + private uint _ulSize; + private uint _ulData; + + private StaticMediaBuffer() + { + } + + public void Reset(uint size) + { + this._ulSize = size; + this._ulData = 0U; + } + + public StaticMediaBuffer(IntPtr pData, uint size) + { + this._pData = pData; + this.Reset(size); + } + + public void SetLength(uint ulLength) => this._ulData = ulLength; + + public void GetMaxLength(out uint pcbMaxLength) => pcbMaxLength = this._ulSize; + + public void GetBufferAndLength(IntPtr ppBuffer, out uint cbLength) + { + if (ppBuffer != IntPtr.Zero) + Marshal.WriteIntPtr(ppBuffer, this._pData); + cbLength = this._ulData; + } + } +} diff --git a/src/Microsoft.Kinect/StatusChangedEventArgs.cs b/src/Microsoft.Kinect/StatusChangedEventArgs.cs new file mode 100644 index 0000000..9d716cd --- /dev/null +++ b/src/Microsoft.Kinect/StatusChangedEventArgs.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.StatusChangedEventArgs +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; + +namespace Microsoft.Kinect +{ + public sealed class StatusChangedEventArgs : EventArgs + { + internal StatusChangedEventArgs() + { + } + + public KinectStatus Status { get; internal set; } + + public KinectSensor Sensor { get; internal set; } + } +} diff --git a/src/Microsoft.Kinect/ThreadSafeList`1.cs b/src/Microsoft.Kinect/ThreadSafeList`1.cs new file mode 100644 index 0000000..91649f3 --- /dev/null +++ b/src/Microsoft.Kinect/ThreadSafeList`1.cs @@ -0,0 +1,183 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.ThreadSafeList`1 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Kinect +{ + internal class ThreadSafeList : IList, ICollection, IEnumerable, IEnumerable + { + private readonly object _lock; + private readonly List _list = new List(); + + public ThreadSafeList() + : this(new object()) + { + } + + public ThreadSafeList(object critSec) => this._lock = critSec; + + public void AddRange(IEnumerable collection) + { + lock (this._lock) + this._list.AddRange(collection); + } + + public int IndexOf(T item) + { + lock (this._lock) + return this._list.IndexOf(item); + } + + public void Insert(int index, T item) + { + lock (this._lock) + this._list.Insert(index, item); + } + + public void RemoveAt(int index) + { + lock (this._lock) + this._list.RemoveAt(index); + } + + public T this[int index] + { + get + { + lock (this._lock) + return this._list[index]; + } + set + { + lock (this._lock) + this._list[index] = value; + } + } + + public void Add(T item) + { + lock (this._lock) + this._list.Add(item); + } + + public void Clear() + { + lock (this._lock) + this._list.Clear(); + } + + public bool Contains(T item) + { + lock (this._lock) + return this._list.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + lock (this._lock) + this._list.CopyTo(array, arrayIndex); + } + + public void CopyTo(T[] array) + { + lock (this._lock) + this._list.CopyTo(array); + } + + public int Count + { + get + { + lock (this._lock) + return this._list.Count; + } + } + + public bool IsReadOnly + { + get + { + lock (this._lock) + return false; + } + } + + public bool Remove(T item) + { + lock (this._lock) + return this._list.Remove(item); + } + + private IEnumerator NewEnumerator() => (IEnumerator) new ThreadSafeList.ThreadSafeEnumerator(this); + + IEnumerator IEnumerable.GetEnumerator() + { + lock (this._lock) + return this.NewEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + lock (this._lock) + return (IEnumerator) this.NewEnumerator(); + } + + private class ThreadSafeEnumerator : IEnumerator, IDisposable, IEnumerator + { + private readonly ThreadSafeList _list; + private readonly IEnumerator _enum; + + public ThreadSafeEnumerator(ThreadSafeList list) + { + lock (list._lock) + { + this._list = new ThreadSafeList(); + this._list.AddRange((IEnumerable) list); + this._enum = (IEnumerator) this._list._list.GetEnumerator(); + } + } + + public void Dispose() + { + lock (this._list._lock) + this._enum.Dispose(); + } + + public bool MoveNext() + { + lock (this._list._lock) + return this._enum.MoveNext(); + } + + public void Reset() + { + lock (this._list._lock) + this._enum.Reset(); + } + + public T Current + { + get + { + lock (this._list._lock) + return this._enum.Current; + } + } + + object IEnumerator.Current + { + get + { + lock (this._list._lock) + return (object) this._enum.Current; + } + } + } + } +} diff --git a/src/Microsoft.Kinect/TransformSmoothParameters.cs b/src/Microsoft.Kinect/TransformSmoothParameters.cs new file mode 100644 index 0000000..ba80413 --- /dev/null +++ b/src/Microsoft.Kinect/TransformSmoothParameters.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.TransformSmoothParameters +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace Microsoft.Kinect +{ + [DebuggerDisplay("Smoothing:{Smoothing} Correction:{Correction} Prediction:{Prediction} JitterRadius:{JitterRadius} MaxDeviationRadius:{MaxDeviationRadius}")] + [StructLayout(LayoutKind.Sequential, Size = 24, Pack = 8)] + public struct TransformSmoothParameters + { + public float Smoothing { get; set; } + + public float Correction { get; set; } + + public float Prediction { get; set; } + + public float JitterRadius { get; set; } + + public float MaxDeviationRadius { get; set; } + + public override int GetHashCode() => this.Smoothing.GetHashCode() + this.Correction.GetHashCode() + this.Prediction.GetHashCode() + this.JitterRadius.GetHashCode() + this.MaxDeviationRadius.GetHashCode(); + + public override bool Equals(object obj) => obj is TransformSmoothParameters smoothParameters && this.Equals(smoothParameters); + + public bool Equals(TransformSmoothParameters smoothParameters) => this.Smoothing.Equals(smoothParameters.Smoothing) && this.Correction.Equals(smoothParameters.Correction) && this.Prediction.Equals(smoothParameters.Prediction) && this.JitterRadius.Equals(smoothParameters.JitterRadius) && this.MaxDeviationRadius.Equals(smoothParameters.MaxDeviationRadius); + + public static bool operator ==( + TransformSmoothParameters smoothParameters1, + TransformSmoothParameters smoothParameters2) + { + return smoothParameters1.Equals(smoothParameters2); + } + + public static bool operator !=( + TransformSmoothParameters smoothParameters1, + TransformSmoothParameters smoothParameters2) + { + return !smoothParameters1.Equals(smoothParameters2); + } + } +} diff --git a/src/Microsoft.Kinect/Vector4.cs b/src/Microsoft.Kinect/Vector4.cs new file mode 100644 index 0000000..df4ed81 --- /dev/null +++ b/src/Microsoft.Kinect/Vector4.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.Vector4 +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +using Microsoft.Kinect.Interop; + +namespace Microsoft.Kinect +{ + public struct Vector4 + { + public float X { get; set; } + + public float Y { get; set; } + + public float Z { get; set; } + + public float W { get; set; } + + public override bool Equals(object obj) => obj is Vector4 vector && this.Equals(vector); + + public bool Equals(Vector4 vector) => this.X.Equals(vector.X) && this.Y.Equals(vector.Y) && this.Z.Equals(vector.Z) && this.W.Equals(vector.W); + + public override int GetHashCode() => this.X.GetHashCode() + this.Y.GetHashCode() + this.Z.GetHashCode() + this.W.GetHashCode(); + + public static bool operator ==(Vector4 vector1, Vector4 vector2) => vector1.Equals(vector2); + + public static bool operator !=(Vector4 vector1, Vector4 vector2) => !vector1.Equals(vector2); + + internal static Vector4 CopyFrom(ref _Vector4 vector) => new Vector4() + { + X = vector.x, + Y = vector.y, + Z = vector.z, + W = vector.w + }; + } +} diff --git a/src/Microsoft.Kinect/WAVEFORMATEX.cs b/src/Microsoft.Kinect/WAVEFORMATEX.cs new file mode 100644 index 0000000..fed5c8f --- /dev/null +++ b/src/Microsoft.Kinect/WAVEFORMATEX.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Kinect.WAVEFORMATEX +// Assembly: Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 +// MVID: DB268133-F353-41FE-808D-1E204C642CE2 +// Assembly location: C:\Users\elias\source\repos\VL.Devices.Kinect\lib\net472\Microsoft.Kinect.dll + +namespace Microsoft.Kinect +{ + internal struct WAVEFORMATEX + { + public ushort wFormatTag; + public ushort nChannels; + public uint nSamplesPerSec; + public uint nAvgBytesPerSec; + public ushort nBlockAlign; + public ushort wBitsPerSample; + public ushort cbSize; + } +} diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..adbc755 --- /dev/null +++ b/src/README.md @@ -0,0 +1 @@ +.NET 6 compatible port of [Microsoft.Kinect (1.8.0.595)](https://www.microsoft.com/en-us/download/details.aspx?id=40277) \ No newline at end of file