JD2022-TU1/main/extern/KinectPC_Sdk/v1.8/inc/NuiSkeleton.h

772 lines
28 KiB
C

/************************************************************************
* *
* NuiSkeleton.h -- This module defines the APIs for the Natural *
* User Interface(NUI) skeleton services. *
* *
* Copyright (c) Microsoft Corp. All rights reserved. *
* *
************************************************************************/
#pragma once
#ifndef NUIAPI
#error "You must include nuiapi.h rather than including nuiskeleton.h directly"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */
#endif
#ifndef _Matrix4_
#define _Matrix4_
typedef struct _Matrix4
{
FLOAT M11;
FLOAT M12;
FLOAT M13;
FLOAT M14;
FLOAT M21;
FLOAT M22;
FLOAT M23;
FLOAT M24;
FLOAT M31;
FLOAT M32;
FLOAT M33;
FLOAT M34;
FLOAT M41;
FLOAT M42;
FLOAT M43;
FLOAT M44;
} Matrix4;
#endif
#ifndef __NuiSensor_h__
#ifndef _Vector4_
#define _Vector4_
typedef struct _Vector4
{
FLOAT x;
FLOAT y;
FLOAT z;
FLOAT w;
} Vector4;
#endif
#ifdef __XNAMATH_H__
#ifndef _Vector4_Functions_
#define _Vector4_Functions_
inline XMVECTOR XMVectorFromVector4(const Vector4& vec4)
{
return XMVectorSet(vec4.x, vec4.y, vec4.z, vec4.w);
}
inline Vector4 XMVectorToVector4(FXMVECTOR V)
{
Vector4 vec4 = { XMVectorGetX(V), XMVectorGetY(V), XMVectorGetZ(V), XMVectorGetW(V) };
return vec4;
}
#endif
#endif
typedef enum _NUI_SKELETON_POSITION_INDEX
{
NUI_SKELETON_POSITION_HIP_CENTER = 0,
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
} NUI_SKELETON_POSITION_INDEX;
//
// Number of NUI_SKELETON_DATA elements in NUI_SKELETON_FRAME
//
#define NUI_SKELETON_COUNT 6
#endif // __NuiSensor_h__
//
// Number of NUI_SKELETON_DATA elements that can be in the NUI_SKELETON_TRACKED state
//
#define NUI_SKELETON_MAX_TRACKED_COUNT 2
//
// Tracking IDs start at 1
//
#define NUI_SKELETON_INVALID_TRACKING_ID 0
#ifndef __NuiSensor_h__
typedef enum _NUI_SKELETON_POSITION_TRACKING_STATE
{
NUI_SKELETON_POSITION_NOT_TRACKED = 0,
NUI_SKELETON_POSITION_INFERRED,
NUI_SKELETON_POSITION_TRACKED
} NUI_SKELETON_POSITION_TRACKING_STATE;
typedef enum _NUI_SKELETON_TRACKING_STATE
{
NUI_SKELETON_NOT_TRACKED = 0,
NUI_SKELETON_POSITION_ONLY,
NUI_SKELETON_TRACKED
} NUI_SKELETON_TRACKING_STATE;
typedef struct _NUI_SKELETON_DATA
{
NUI_SKELETON_TRACKING_STATE eTrackingState;
DWORD dwTrackingID;
DWORD dwEnrollmentIndex;
DWORD dwUserIndex;
Vector4 Position;
Vector4 SkeletonPositions[NUI_SKELETON_POSITION_COUNT];
NUI_SKELETON_POSITION_TRACKING_STATE eSkeletonPositionTrackingState[NUI_SKELETON_POSITION_COUNT];
DWORD dwQualityFlags;
} NUI_SKELETON_DATA;
#endif // __NuiSensor_h__
//
// Force a link error if the size of NUI_SKELETON_DATA is different
// between the static library and the header included by the title.
//
__declspec(selectany) DWORD NuiSkeletonDataSize = sizeof(NUI_SKELETON_DATA);
#define NUI_SKELETON_QUALITY_CLIPPED_RIGHT 0x00000001
#define NUI_SKELETON_QUALITY_CLIPPED_LEFT 0x00000002
#define NUI_SKELETON_QUALITY_CLIPPED_TOP 0x00000004
#define NUI_SKELETON_QUALITY_CLIPPED_BOTTOM 0x00000008
#ifndef __NuiSensor_h__
#pragma pack(push, 16)
typedef struct _NUI_SKELETON_FRAME
{
LARGE_INTEGER liTimeStamp;
DWORD dwFrameNumber;
DWORD dwFlags;
Vector4 vFloorClipPlane;
Vector4 vNormalToGravity;
NUI_SKELETON_DATA SkeletonData[NUI_SKELETON_COUNT];
} NUI_SKELETON_FRAME;
#pragma pack(pop)
typedef struct _NUI_TRANSFORM_SMOOTH_PARAMETERS
{
FLOAT fSmoothing; // [0..1], lower values closer to raw data
FLOAT fCorrection; // [0..1], lower values slower to correct towards the raw data
FLOAT fPrediction; // [0..n], the number of frames to predict into the future
FLOAT fJitterRadius; // The radius in meters for jitter reduction
FLOAT fMaxDeviationRadius; // The maximum radius in meters that filtered positions are allowed to deviate from raw data
} NUI_TRANSFORM_SMOOTH_PARAMETERS;
#endif // __NuiSensor_h__
// Flags returned by NuiSkeletonGetNextFrame in the dwFlags field of the NUI_SKELETON_FRAME structure
#define NUI_SKELETON_FRAME_FLAG_SEATED_SUPPORT_ENABLED 0x00000008
// Flags for use with the NuiSkeletonTrackingEnable function
#define NUI_SKELETON_TRACKING_FLAG_SUPPRESS_NO_FRAME_DATA 0x00000001
#define NUI_SKELETON_TRACKING_FLAG_TITLE_SETS_TRACKED_SKELETONS 0x00000002
#define NUI_SKELETON_TRACKING_FLAG_ENABLE_SEATED_SUPPORT 0x00000004
#define NUI_SKELETON_TRACKING_FLAG_ENABLE_IN_NEAR_RANGE 0x00000008
#ifndef __NuiSensor_h__
typedef struct _NUI_SKELETON_BONE_ROTATION
{
Matrix4 rotationMatrix;
Vector4 rotationQuaternion;
} NUI_SKELETON_BONE_ROTATION;
typedef struct _NUI_SKELETON_BONE_ORIENTATION
{
NUI_SKELETON_POSITION_INDEX endJoint;
NUI_SKELETON_POSITION_INDEX startJoint;
NUI_SKELETON_BONE_ROTATION hierarchicalRotation;
NUI_SKELETON_BONE_ROTATION absoluteRotation;
} NUI_SKELETON_BONE_ORIENTATION;
#endif // __NuiSensor_h__
/// <summary>
/// Enables skeleton tracking.
/// </summary>
/// <param name="hNextFrameEvent">
/// A handle to an application-allocated, manual reset event that will be set whenever a new frame
/// of skeleton data is available, and will be reset whenever the latest frame data is returned.
/// This can be NULL.
/// </param>
/// <param name="dwFlags">
/// Flags that control skeleton tracking, as a bitwise-OR combination NUI_SKELETON_TRACKING values.
/// </param>
/// <returns>
/// Returns S_OK if successful; otherwise, returns one of the following failure codes:
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>__HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION)</term>
/// <description>The device is uninitialized or the sensor is not initialized with the NUI_INITIALIZE_FLAG_USES_SKELETON flag. <see cref="NuiInitialize"/>.</description>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <description>The <paramref name="dwFlags"/> parameter includes invalid flags.</description>
/// </item>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <description>Allocation failed.</description>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// The following flags are supported:
/// <list type="table">
/// <item>
/// <term>NUI_SKELETON_TRACKING_FLAG_SUPPRESS_NO_FRAME_DATA</term>
/// <description>Prevents NuiSkeletonGetNextFrame from returning E_NUI_FRAME_NO_DATA errors. Instead, calls to NuiSkeletonGetNextFrame block until data is available or the timeout period passes.</description>
/// </item>
/// <item>
/// <term>NUI_SKELETON_TRACKING_FLAG_TITLE_SETS_TRACKED_SKELETONS</term>
/// <description>Disables the default player selection mode and enables the title to manage which players have tracked skeletons.</description>
/// </item>
/// <item>
/// <term>NUI_SKELETON_TRACKING_FLAG_ENABLE_SEATED_SUPPORT</term>
/// <description>Uses seated skeleton tracking mode. The 10 lower-body joints of each skeleton will not be tracked.</description>
/// </item>
/// </list>
/// </remarks>
_Check_return_ HRESULT NUIAPI NuiSkeletonTrackingEnable(
_In_opt_ HANDLE hNextFrameEvent,
_In_ DWORD dwFlags
);
/// <summary>
/// Disables skeleton tracking.
/// </summary>
/// <returns>
/// Returns S_OK if successful; otherwise, returns one of the following error codes:
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>__HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION)</term>
/// <description>The device is uninitialized or the sensor is not initialized with the NUI_INITIALIZE_FLAG_USES_SKELETON flag. <see cref="NuiInitialize"/>.</description>
/// </item>
/// </list>
/// </returns>
_Check_return_ HRESULT NUIAPI NuiSkeletonTrackingDisable(
);
/// <summary>
/// Gets the next frame of data from the skeleton stream.
/// </summary>
/// <param name="dwMillisecondsToWait">The timeout (in milliseconds) before returning without a new frame.</param>
/// <param name="pSkeletonFrame">
/// A pointer to a NUI_SKELETON_FRAME structure that receives the next image frame in the skeleton
/// stream. This must not be NULL.
/// </param>
/// <returns>
/// Returns S_OK if successful; otherwise, returns one of the following error codes:
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>S_FALSE</term>
/// <description>The wait timeout expired before a new frame was available and NuiSkeletonTrackingEnable was passed the NUI_SKELETON_TRACKING_FLAG_TITLE_SETS_TRACKED_SKELETONS flag.</description>
/// </item>
/// <item>
/// <term>E_NUI_FRAME_NO_DATA</term>
/// <description>The wait timeout expired before a new frame was available.</description>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <description>The <paramref name="pSkeletonFrame"/> parameter is NULL.</description>
/// </item>
/// </list>
/// </returns>
/// <seealso cref="NuiSkeletonTrackingEnable"/>
_Check_return_ HRESULT NUIAPI NuiSkeletonGetNextFrame(
_In_ DWORD dwMillisecondsToWait,
_Inout_ NUI_SKELETON_FRAME *pSkeletonFrame
);
/// <summary>
/// Sets an array of IDs for skeletal tracking.
/// </summary>
/// <param name="TrackingIDs">A pointer to the first DWORD in an array of tracking IDs, one for each skeleton.</param>
/// <returns>
/// <para>Returns S_OK if successful; otherwise, returns one of the following error codes:
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <description>The <paramref name="TrackingIDs"/> parameter is NULL.</description>
/// </item>
/// <item>
/// <term>E_NUI_STREAM_NOT_ENABLED</term>
/// <description>The device is uninitialized or the sensor is not initialized with the NUI_INITIALIZE_FLAG_USES_SKELETON flag. <see cref="NuiInitialize"/>.</description>
/// </item>
/// <item>
/// <term>E_NUI_FEATURE_NOT_INITIALIZED</term>
/// <description>Skeletal tracking is not enabled with the NUI_SKELETON_TRACKING_FLAG_TITLE_SETS_TRACKED_SKELETONS flag.</description>
/// </item>
/// </list>
/// </returns>
_Check_return_ HRESULT NUIAPI NuiSkeletonSetTrackedSkeletons(
_In_count_c_(NUI_SKELETON_MAX_TRACKED_COUNT) DWORD TrackingIDs[NUI_SKELETON_MAX_TRACKED_COUNT]
);
#ifdef __cplusplus
} //close extern "C"
// Assuming a pixel resolution of 320x240
// x_meters = (x_pixelcoord - 160) * NUI_CAMERA_DEPTH_IMAGE_TO_SKELETON_MULTIPLIER_320x240 * z_meters;
// y_meters = (y_pixelcoord - 120) * NUI_CAMERA_DEPTH_IMAGE_TO_SKELETON_MULTIPLIER_320x240 * z_meters;
#define NUI_CAMERA_DEPTH_IMAGE_TO_SKELETON_MULTIPLIER_320x240 (NUI_CAMERA_DEPTH_NOMINAL_INVERSE_FOCAL_LENGTH_IN_PIXELS)
// Assuming a pixel resolution of 320x240
// x_pixelcoord = (x_meters) * NUI_CAMERA_SKELETON_TO_DEPTH_IMAGE_MULTIPLIER_320x240 / z_meters + 160;
// y_pixelcoord = (y_meters) * NUI_CAMERA_SKELETON_TO_DEPTH_IMAGE_MULTIPLIER_320x240 / z_meters + 120;
#define NUI_CAMERA_SKELETON_TO_DEPTH_IMAGE_MULTIPLIER_320x240 (NUI_CAMERA_DEPTH_NOMINAL_FOCAL_LENGTH_IN_PIXELS)
/// <summary>
/// Returns the depth space coordinates of the specified point in skeleton space.
/// </summary>
/// <param name="vPoint">
/// The point to transform, in skeleton space coordinates. This point must have a valid depth value.
/// </param>
/// <param name="pfDepthX">
/// A pointer to a FLOAT that receives the X coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <param name="pfDepthY">
/// A pointer to a FLOAT that receives the Y coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <param name="pusDepthValue">
/// <para>A pointer to a USHORT that receives the depth value of the point in depth space. This
/// pointer must be non-NULL when you call the function. If this is a NULL pointer, this function
/// returns without doing anything.</para>
///
/// <para>The format of this value is the same as that for points in other depth images: the least
/// significant three bits contain a player index that is always zero, and the remaining bits are
/// the depth value, in millimeters. This value is suitable for comparison with values from an
/// image from any of the depth streams, provided that the player index information is masked
/// appropriately from the other image.</para>
/// </param>
/// <param name="eResolution">
/// A NUI_IMAGE_RESOLUTION value that specifies the resolution of the depth image.
/// </param>
/// <remarks>
/// You can use this function to place virtual objects into the color image with depth-based
/// occlusion. Call this function to determine which skeleton-space vertices of a virtual object
/// are in front of, or behind, real objects that are visible in the depth map image. After
/// occluded parts of the virtual objects have been culled, use the
/// NuiImageGetColorPixelCoordinatesFromDepthPixel function to overlay the virtual object's
/// vertices into color image pixel coordinates for rendering.
/// </remarks>
inline
VOID
NuiTransformSkeletonToDepthImage(
_In_ Vector4 vPoint,
_Out_ LONG *plDepthX,
_Out_ LONG *plDepthY,
_Out_ USHORT *pusDepthValue,
_In_ NUI_IMAGE_RESOLUTION eResolution
)
{
if((plDepthX == NULL) || (plDepthY == NULL) || (pusDepthValue == NULL))
{
return;
}
//
// Requires a valid depth value.
//
if(vPoint.z > FLT_EPSILON)
{
DWORD width;
DWORD height;
NuiImageResolutionToSize( eResolution, width, height );
//
// Center of depth sensor is at (0,0,0) in skeleton space, and
// and (width/2,height/2) in depth image coordinates. Note that positive Y
// is up in skeleton space and down in image coordinates.
//
// The 0.5f is to correct for casting to int truncating, not rounding
*plDepthX = static_cast<INT>( width / 2 + vPoint.x * (width/320.f) * NUI_CAMERA_SKELETON_TO_DEPTH_IMAGE_MULTIPLIER_320x240 / vPoint.z + 0.5f);
*plDepthY = static_cast<INT>( height / 2 - vPoint.y * (height/240.f) * NUI_CAMERA_SKELETON_TO_DEPTH_IMAGE_MULTIPLIER_320x240 / vPoint.z + 0.5f);
//
// Depth is in meters in skeleton space.
// The depth image pixel format has depth in millimeters shifted left by 3.
//
*pusDepthValue = static_cast<USHORT>(vPoint.z *1000) << 3;
} else
{
*plDepthX = 0;
*plDepthY = 0;
*pusDepthValue = 0;
}
}
/// <summary>
/// Returns the depth space coordinates of the specified point in skeleton space.
/// </summary>
/// <param name="vPoint">
/// The point to transform, in skeleton space coordinates. This point must have a valid depth value.
/// </param>
/// <param name="pfDepthX">
/// A pointer to a FLOAT that receives the X coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <param name="pfDepthY">
/// A pointer to a FLOAT that receives the Y coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <param name="pusDepthValue">
/// <para>A pointer to a USHORT that receives the depth value of the point in depth space. This
/// pointer must be non-NULL when you call the function. If this is a NULL pointer, this function
/// returns without doing anything.</para>
///
/// <para>The format of this value is the same as that for points in other depth images: the least
/// significant three bits contain a player index that is always zero, and the remaining bits are
/// the depth value, in millimeters. This value is suitable for comparison with values from an
/// image from any of the depth streams, provided that the player index information is masked
/// appropriately from the other image.</para>
/// </param>
/// <remarks>
/// You can use this function to place virtual objects into the color image with depth-based
/// occlusion. Call this function to determine which skeleton-space vertices of a virtual object
/// are in front of, or behind, real objects that are visible in the depth map image. After
/// occluded parts of the virtual objects have been culled, use the
/// NuiImageGetColorPixelCoordinatesFromDepthPixel function to overlay the virtual object's
/// vertices into color image pixel coordinates for rendering.
/// </remarks>
inline
VOID
NuiTransformSkeletonToDepthImage(
_In_ Vector4 vPoint,
_Out_ LONG *plDepthX,
_Out_ LONG *plDepthY,
_Out_ USHORT *pusDepthValue
)
{
NuiTransformSkeletonToDepthImage( vPoint, plDepthX, plDepthY, pusDepthValue, NUI_IMAGE_RESOLUTION_320x240);
}
/// <summary>
/// Returns the depth space coordinates of the specified point in skeleton space.
/// </summary>
/// <param name="vPoint">
/// The point to transform, in skeleton space coordinates. This point must have a valid depth value.
/// </param>
/// <param name="pfDepthX">
/// A pointer to a FLOAT that receives the X coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <param name="pfDepthY">
/// A pointer to a FLOAT that receives the Y coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <param name="eResolution">
/// A NUI_IMAGE_RESOLUTION value that specifies the resolution of the depth image.
/// </param>
/// <remarks>
/// You can use this function to place virtual objects into the color image with depth-based
/// occlusion. Call this function to determine which skeleton-space vertices of a virtual object
/// are in front of, or behind, real objects that are visible in the depth map image. After
/// occluded parts of the virtual objects have been culled, use the
/// NuiImageGetColorPixelCoordinatesFromDepthPixel function to overlay the virtual object's
/// vertices into color image pixel coordinates for rendering.
/// </remarks>
inline
VOID
NuiTransformSkeletonToDepthImage(
_In_ Vector4 vPoint,
_Out_ FLOAT *pfDepthX,
_Out_ FLOAT *pfDepthY,
_In_ NUI_IMAGE_RESOLUTION eResolution
)
{
if((pfDepthX == NULL) || (pfDepthY == NULL))
{
return;
}
//
// Requires a valid depth value.
//
if(vPoint.z > FLT_EPSILON)
{
DWORD width;
DWORD height;
NuiImageResolutionToSize( eResolution, width, height );
//
// Center of depth sensor is at (0,0,0) in skeleton space, and
// and (width/2,height/2) in depth image coordinates. Note that positive Y
// is up in skeleton space and down in image coordinates.
//
*pfDepthX = width / 2 + vPoint.x * (width/320.f) * NUI_CAMERA_SKELETON_TO_DEPTH_IMAGE_MULTIPLIER_320x240 / vPoint.z;
*pfDepthY = height / 2 - vPoint.y * (height/240.f) * NUI_CAMERA_SKELETON_TO_DEPTH_IMAGE_MULTIPLIER_320x240 / vPoint.z;
} else
{
*pfDepthX = 0.0f;
*pfDepthY = 0.0f;
}
}
/// <summary>
/// Returns the depth space coordinates of the specified point in skeleton space.
/// </summary>
/// <param name="vPoint">
/// The point to transform, in skeleton space coordinates. This point must have a valid depth value.
/// </param>
/// <param name="pfDepthX">
/// A pointer to a FLOAT that receives the X coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <param name="pfDepthY">
/// A pointer to a FLOAT that receives the Y coordinate of the point in depth space. This pointer
/// must be non-NULL when you call the function. If this is a NULL pointer, this function returns
/// without doing anything.
/// </param>
/// <remarks>
/// You can use this function to place virtual objects into the color image with depth-based
/// occlusion. Call this function to determine which skeleton-space vertices of a virtual object
/// are in front of, or behind, real objects that are visible in the depth map image. After
/// occluded parts of the virtual objects have been culled, use the
/// NuiImageGetColorPixelCoordinatesFromDepthPixel function to overlay the virtual object's
/// vertices into color image pixel coordinates for rendering.
/// </remarks>
inline
VOID
NuiTransformSkeletonToDepthImage(
_In_ Vector4 vPoint,
_Out_ FLOAT *pfDepthX,
_Out_ FLOAT *pfDepthY
)
{
NuiTransformSkeletonToDepthImage(vPoint, pfDepthX, pfDepthY, NUI_IMAGE_RESOLUTION_320x240);
}
/// <summary>
/// Returns the depth space coordinates of the specified point in skeleton space.
/// </summary>
/// <param name="lDepthX">The X coordinate of the depth pixel.</param>
/// <param name="lDepthY">The Y coordinate of the depth pixel.</param>
/// <param name="usDepthValue">
/// The depth value (in millimeters) of the depth image pixel, shifted left by three bits. The left
/// shift enables you to pass the value from the depth image directly into this function.
/// </param>
/// <param name="eResolution">
/// A NUI_IMAGE_RESOLUTION value that specifies the resolution of the depth image.
/// </param>
/// <returns>
/// Returns the skeleton space coordinates of the given depth image pixel (in meters).
/// </returns>
inline
Vector4
NuiTransformDepthImageToSkeleton(
_In_ LONG lDepthX,
_In_ LONG lDepthY,
_In_ USHORT usDepthValue,
_In_ NUI_IMAGE_RESOLUTION eResolution
)
{
DWORD width;
DWORD height;
NuiImageResolutionToSize( eResolution, width, height );
//
// Depth is in meters in skeleton space.
// The depth image pixel format has depth in millimeters shifted left by 3.
//
FLOAT fSkeletonZ = static_cast<FLOAT>(usDepthValue >> 3) / 1000.0f;
//
// Center of depth sensor is at (0,0,0) in skeleton space, and
// and (width/2,height/2) in depth image coordinates. Note that positive Y
// is up in skeleton space and down in image coordinates.
//
FLOAT fSkeletonX = (lDepthX - width/2.0f) * (320.0f/width) * NUI_CAMERA_DEPTH_IMAGE_TO_SKELETON_MULTIPLIER_320x240 * fSkeletonZ;
FLOAT fSkeletonY = -(lDepthY - height/2.0f) * (240.0f/height) * NUI_CAMERA_DEPTH_IMAGE_TO_SKELETON_MULTIPLIER_320x240 * fSkeletonZ;
//
// Return the result as a vector.
//
Vector4 v4;
v4.x = fSkeletonX;
v4.y = fSkeletonY;
v4.z = fSkeletonZ;
v4.w = 1.0f;
return v4;
}
/// <summary>
/// Returns the depth space coordinates of the specified point in skeleton space.
/// </summary>
/// <param name="lDepthX">The X coordinate of the depth pixel.</param>
/// <param name="lDepthY">The Y coordinate of the depth pixel.</param>
/// <param name="usDepthValue">
/// The depth value (in millimeters) of the depth image pixel, shifted left by three bits. The left
/// shift enables you to pass the value from the depth image directly into this function.
/// </param>
/// <returns>
/// Returns the skeleton space coordinates of the given depth image pixel (in meters).
/// </returns>
inline
Vector4
NuiTransformDepthImageToSkeleton(
_In_ LONG lDepthX,
_In_ LONG lDepthY,
_In_ USHORT usDepthValue
)
{
return NuiTransformDepthImageToSkeleton(lDepthX, lDepthY, usDepthValue, NUI_IMAGE_RESOLUTION_320x240);
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
/// <summary>
/// Filters skeleton positions to reduce jitter between frames.
/// </summary>
/// <param name="pSkeletonFrame">
/// On entry, points to a NUI_SKELETON_FRAME structure that contains the skeleton data to be
/// smoothed. On exit, the skeleton data in the structure has been replaced by smoothed data. If
/// this function does not return S_OK, this data is unchanged.
/// </param>
/// <param name="pSmoothingParams">
/// The parameters for the smoothing function. See the NUI_TRANSFORM_SMOOTH_PARAMETERS structure
/// for a description of the parameters.
/// </param>
/// <returns>
/// Returns S_OK if successful; otherwise, returns one of the following error codes:
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>E_OUTOFMEMORY</term>
/// <description>Failed allocation.</description>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <description>The <paramref name="pSkeletonFrame"/> parameter is NULL.</description>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// The filter used is based on the Holt Double Exponential Smoothing method used for statistical
/// analysis of economic data, which provides smoothing with less latency than other smoothing
/// filter algorithms. A single call of this function updates all currently-tracked skeletons.
/// </remarks>
_Check_return_ HRESULT NUIAPI NuiTransformSmooth(
_Inout_ NUI_SKELETON_FRAME *pSkeletonFrame,
_In_opt_ CONST NUI_TRANSFORM_SMOOTH_PARAMETERS *pSmoothingParams
);
/// <summary>
/// Calculate bone orientations for a skeleton.
/// </summary>
/// <param name="pSkeletonData">
/// Pointer to the skeleton data to calculate joint angles for.
/// </param>
/// <param name="pBoneOrientations">
/// Pointer to an array of NUI_SKELETON_BONE_ORIENTATION of dimension NUI_SKELETON_POSITION_COUNT (20).
/// This array must be allocated by the user before calling this function.
/// </param>
/// <returns>
/// Returns S_OK if successful; otherwise, returns one of the following error codes:
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <description>The <paramref name="pSkeletonData"/> parameter is NULL.</description>
/// </item>
/// <item>
/// <term>E_POINTER</term>
/// <description>The <paramref name="pBoneOrientations"/> parameter is NULL.</description>
/// </item>
/// </list>
/// <item>
/// <term>S_FALSE</term>
/// <description>The joints required to calculate the skeleton root are not visible. Hierarchical bone rotations are set to Identity.</description>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// The function calculates hierarchical and absolute joint angles for the skeleton, which can
/// be used in animating an avatar (Avateering). The HipCenter joint is the root of the hierarchy,
/// and describes an absolute rotation in the right-hand camera coordinate system. All other
/// joints describe rotations relative to their parent joint orientation. The angles are returned
/// in the same order as the joints are defined.
/// </remarks>
_Check_return_ STDMETHODIMP
NuiSkeletonCalculateBoneOrientations(
_In_ const NUI_SKELETON_DATA *pSkeletonData,
_Out_cap_c_(NUI_SKELETON_POSITION_COUNT) NUI_SKELETON_BONE_ORIENTATION *pBoneOrientations);
#ifdef __cplusplus
} //close extern "C"
#endif