JD2022-TU1/main/extern/KinectGesture/Src/KinectGestureDetector.cpp

297 lines
9.5 KiB
C++

#pragma once
#include "KinectGestureDetector.h"
#include "GestureDetector.h"
#ifdef DURANGO
using namespace DirectX;
using namespace Microsoft::Xbox::Input::Nui;
#endif
#if defined(WIN32) && defined(ITF_WIN32)
using namespace DirectX;
using namespace Microsoft::Win32::Input::Nui;
#endif
namespace KinectGesture
{
struct GestureData
{
GestureData()
{
inUse = FALSE;
}
GestureDetector detector;
BOOL inUse;
};
static XMVECTOR normalToGravity = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
static GestureData* gestures = NULL;
static UINT gestureCount = 0;
MallocFunction mallocFunction = NULL;
FreeFunction freeFunction = NULL;
AssertFunction assertFunction = NULL;
bool g_endianSwapOnRead = false;
void SetEndianSwapOnRead( const bool endianSwapOnRead )
{
g_endianSwapOnRead = endianSwapOnRead;
}
bool GetEndianSwapOnRead()
{
#if defined( __ORBIS__ ) || defined( ITF_ORBIS ) ||\
defined( DURANGO ) || defined( ITF_DURANGO ) ||\
defined(WIN32) || defined(ITF_WIN32)
return g_endianSwapOnRead;
#elif defined(TARGET_X360) && defined(GESTURE_EVALUATOR)
return true;
#else
return false;
#endif
}
void Assert( bool expression, const char* message )
{
if( KinectGesture::assertFunction )
{
KinectGesture::assertFunction( expression, message );
}
}
void* AllocateAligned( unsigned int size, unsigned int alignment )
{
if( KinectGesture::mallocFunction == NULL )
{
Assert( false, "No allocation function specified" );
return NULL;
}
return mallocFunction( size, alignment );
}
void FreeAligned( void* memory )
{
if( KinectGesture::freeFunction == NULL )
{
Assert( false, "No free function specified" );
return;
}
return freeFunction( memory );
}
#ifdef GESTURE_EVALUATOR
void Initialise(unsigned int gestureCount)
{
KinectGesture::gestureCount = gestureCount;
KinectGesture::mallocFunction = (MallocFunction) _aligned_malloc;
KinectGesture::freeFunction = (FreeFunction)_aligned_free;
KinectGesture::assertFunction = NULL;
Initialise(gestureCount,mallocFunction,freeFunction,assertFunction);
}
#endif
void Initialise( unsigned int gestureCount,
MallocFunction mallocFunction,
FreeFunction freeFunction,
AssertFunction assertFunction )
{
KinectGesture::mallocFunction = mallocFunction;
KinectGesture::freeFunction = freeFunction;
KinectGesture::assertFunction = assertFunction;
// allocate all our stuff
KinectGesture::gestureCount = gestureCount;
gestures = (GestureData*)AllocateAligned( KinectGesture::gestureCount * sizeof( GestureData ), 16 );
for( UINT uiIndex = 0; uiIndex < KinectGesture::gestureCount; ++uiIndex )
{
gestures[uiIndex].inUse = FALSE;
}
// reset up vector
normalToGravity = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
}
void Shutdown()
{
// free all our stuff
for( UINT slotIndex = 0; slotIndex < gestureCount; ++slotIndex )
{
if( KinectGesture::gestures[slotIndex].inUse )
{
DestroyGesture( slotIndex );
}
}
FreeAligned( gestures );
KinectGesture::gestures = NULL;
KinectGesture::gestureCount = 0;
//free static ClassifierData
GestureDetector::FreeClassifierData();
}
void SetNormalToGravity( const float* normalToGravity )
{
#if defined(WIN32) || defined(WIN64)
KinectGesture::normalToGravity.m128_f32[0] = normalToGravity[0];
KinectGesture::normalToGravity.m128_f32[1] = normalToGravity[1];
KinectGesture::normalToGravity.m128_f32[2] = normalToGravity[2];
KinectGesture::normalToGravity.m128_f32[3] = normalToGravity[3];
#elif defined( _XBOX ) || defined( TARGET_X360 ) || defined( ITF_X360 ) ||\
defined( DURANGO ) || defined( TARGET_DURANGO ) || defined( ITF_DURANGO )
KinectGesture::normalToGravity.x = normalToGravity[0];
KinectGesture::normalToGravity.y = normalToGravity[1];
KinectGesture::normalToGravity.z = normalToGravity[2];
KinectGesture::normalToGravity.w = normalToGravity[3];
#elif defined( __ORBIS__ ) || defined( TARGET_ORBIS ) || defined( ITF_ORBIS )
KinectGesture::normalToGravity.x = normalToGravity[0];
KinectGesture::normalToGravity.y = normalToGravity[1];
KinectGesture::normalToGravity.z = normalToGravity[2];
#else
#error unsuported platform
#endif
}
void Update( unsigned int playerIndex, const void* skeletonData, float deltaTimeInSeconds, const VelocityGrid* opticalFlowGrid )
{
if ( playerIndex >= KINECT_GESTURE_MAX_SIMULTANEOUS_GESTURES )
{
Assert( false, "Player index invalid" );
return;
}
KinectGesture::GestureDetector::Update( playerIndex, (GESTURE_SKELETON_TYPE*)skeletonData, deltaTimeInSeconds, KinectGesture::normalToGravity, FALSE, opticalFlowGrid );
}
void NewPlayer( unsigned int playerIndex, const void* skeletonData )
{
if ( playerIndex >= KINECT_GESTURE_MAX_SIMULTANEOUS_GESTURES )
{
Assert( false, "Player index invalid" );
return;
}
KinectGesture::GestureDetector::ResetPlayer( playerIndex, (GESTURE_SKELETON_TYPE*)skeletonData, KinectGesture::normalToGravity );
}
GestureHandle CreateGesture( void* buffer )
{
// find a free slot
GestureHandle gesture = INVALID_GESTURE_HANDLE;
for( UINT slotIndex = 0; slotIndex < gestureCount; ++slotIndex )
{
if( !KinectGesture::gestures[slotIndex].inUse )
{
gesture = slotIndex;
break;
}
}
if( gesture == INVALID_GESTURE_HANDLE )
{
// no more space left for gestures
Assert( false, "No more space left for gestures" );
return INVALID_GESTURE_HANDLE;
}
new ( &KinectGesture::gestures[gesture].detector ) GestureDetector();
if( SUCCEEDED( KinectGesture::gestures[gesture].detector.LoadFromMemory( buffer ) ) )
{
KinectGesture::gestures[gesture].inUse = TRUE;
return gesture;
}
else
{
return INVALID_GESTURE_HANDLE;
}
}
void DestroyGesture( GestureHandle gesture )
{
if( gesture >= KinectGesture::gestureCount || !KinectGesture::gestures[gesture].inUse )
{
// gesture invalid or not in use
Assert( false, "Gesture invalid or not in use" );
return;
}
KinectGesture::gestures[gesture].detector.~GestureDetector();
KinectGesture::gestures[gesture].inUse = FALSE;
}
float DetectGesture( GestureHandle gesture, unsigned int playerIndex )
{
if ( playerIndex >= KINECT_GESTURE_MAX_SIMULTANEOUS_GESTURES )
{
Assert( false, "Player index invalid" );
return 0.0f;
}
if( gesture >= KinectGesture::gestureCount || !KinectGesture::gestures[gesture].inUse )
{
// gesture invalid or not in use
Assert( false, "Gesture invalid or not in use" );
return 0.0f;
}
KinectGesture::GestureDetector::Results results;
KinectGesture::gestures[gesture].detector.Detect( playerIndex, &results, FALSE );
float fMin = KinectGesture::gestures[gesture].detector.GetMean( KinectGesture::StrongClassifier::eLabel_Incorrect ) +
KinectGesture::gestures[gesture].detector.GetStdDev( KinectGesture::StrongClassifier::eLabel_Incorrect );
float fMax = KinectGesture::gestures[gesture].detector.GetDetectionThreshold();
// return raw result (so external clients can clamp if they want)
return ( results.m_fConfidence - fMin ) / ( fMax - fMin );
}
void GetGestureBoneWeights( GestureHandle gesture, FLOAT *weights, UINT numWeights )
{
if( gesture >= KinectGesture::gestureCount || !KinectGesture::gestures[gesture].inUse )
{
// gesture invalid or not in use
Assert( false, "Gesture invalid or not in use" );
return;
}
KinectGesture::gestures[gesture].detector.GetBoneWeights( weights, numWeights );
}
float GetGestureEnergyMean( GestureHandle gesture )
{
if( gesture >= KinectGesture::gestureCount || !KinectGesture::gestures[gesture].inUse )
{
// gesture invalid or not in use
Assert( false, "Gesture invalid or not in use" );
return 0.0f;
}
return KinectGesture::gestures[gesture].detector.GetEnergyMean();
}
float GetGestureEnergyStdDev( GestureHandle gesture )
{
if( gesture >= KinectGesture::gestureCount || !KinectGesture::gestures[gesture].inUse )
{
// gesture invalid or not in use
Assert( false, "Gesture invalid or not in use" );
return 0.0f;
}
return KinectGesture::gestures[gesture].detector.GetEnergyStdDev();
}
float GetEnergyLevel( unsigned int playerIndex )
{
if ( playerIndex >= KINECT_GESTURE_MAX_SIMULTANEOUS_GESTURES )
{
Assert( false, "Player index invalid" );
return 0.0f;
}
return KinectGesture::GestureDetector::GetEnergyLevel( playerIndex );
}
}