JD2022-TU1/main/extern/Camcam/LIBS/Input/natal.cpp

743 lines
No EOL
23 KiB
C++

#include "SCENE.h"
#ifdef NATAL_SUPPORT
#include "NATAL.H"
#define ZZZFILENAME ".\\NATEST211.ZZZ"
XCAMERA_PHYSICAL_DETAILS cameraDetails;
ZZZ *pGlouk = NULL;
//#define SAVEMODE
#define PLAYMODE
#define DEBUGINFO
void MAP_ComputePlanes(MAP *ZMap,u16 *PrimsensZMap);
struct ScreenSpaceData
{
INT x;
INT y;
};
static ScreenSpaceData g_ScreenSpaceJoints[ XCAMERA_JOINT_COUNT ];
//--------------------------------------------------------------------------------------
// SimpleSkeletonTracking.cpp
//
// Defines functions used for simple skeleton tracking.
//
// XNA Developer Connection.
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Constants and defines
//--------------------------------------------------------------------------------------
// Define the maximum number of players to track. This value needs to be between 1 and 2.
// NOTE: More computing resources are necessary for more players, so plan ahead and set
// this value appropriately.
XCAMERA_JOINT g_Joints[ XCAMERA_JOINT_COUNT * g_dwMaxPlayersInGame * 16 ];
// The camera will stream in certain data depending on how you initialize it. For this
// sample we initialize the camera to stream in both color and depth data. Note that if
// you're only interested in doing skelton tracking, then these streams don't need to
// be initialized or streamed in.
#define COLOR_STREAM 0
#define DEPTH_STREAM 1
#define NUM_STREAMS 2
//--------------------------------------------------------------------------------------
// Data structures
//--------------------------------------------------------------------------------------
// Define a structure that can store the data of a stream from the camera. (Only needed to
// display the color and depth data)
struct StreamData
{
BYTE* pbData; // Data in the stream
BYTE* pbDataToProcess; // Data in the stream
DWORD dwBufferSize; // Size of the full buffer in bytes
DWORD dwWidth; // Streams could have different widths
DWORD dwHeight; // Streams could have different heights
DWORD StreamType; // The stream type, e.g. color or depth
XCAMERA_FRAME_INFO FrameInfo; // Frame information
OVERLAPPED Overlapped ; // An OVERLAPPED structure to use for asynchronous XCameraReadStream / XJointTrackSkeletons
};
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
// For this simple sample, the camera synchronously copy data into these streams each frame
// (Only needed to display color and depth data)
StreamData g_Streams[ NUM_STREAMS ];
// Declare the output buffers for the skeleton tracking
void ZERZERZERSave()
{
memcpy(g_Joints + XCAMERA_JOINT_COUNT * 2 , g_Joints , XCAMERA_JOINT_COUNT * 2 * sizeof(XCAMERA_JOINT));
}
void ZERZERZERSaveEnergy()
{
memcpy(g_Joints + XCAMERA_JOINT_COUNT * 4 , g_Joints , XCAMERA_JOINT_COUNT * 2 * sizeof(XCAMERA_JOINT));
}
void ZERZERZERRestore()
{
memcpy(g_Joints + XCAMERA_JOINT_COUNT , g_Joints + XCAMERA_JOINT_COUNT * 2, XCAMERA_JOINT_COUNT * sizeof(XCAMERA_JOINT));
}
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT CreateStreamBuffers();
VOID DestroyStreamBuffers();
//--------------------------------------------------------------------------------------
// Name: InitializeSkeletonTracking()
// Desc: Initialize the camera from sensor array and skeleton tracking.
// Also allocate any memory needed for streaming and visualizing data
//--------------------------------------------------------------------------------------
u32 InstanceCounter = 0;
HRESULT InitializeSkeletonTracking()
{
DWORD dwResult ;
// NOTE: Error codes can be looked up in the XDK documentation under "System Error Codes"
if (InstanceCounter)
{
InstanceCounter ++ ;
return S_OK;
}
// Initialize the camera on the default worker thread, synchronously
dwResult = XCameraInitialize( XCAMERA_DEFAULT_WORKER_THREAD_PROCESSOR, NULL );
if (dwResult != ERROR_SUCCESS)
{
goto TRY_PLAYMODE;
}
// Initialize the skeleton tracking with the maximum number of players in the game
dwResult = XJointInitialize( 0, g_dwMaxPlayersInGame );
if ( dwResult != ERROR_SUCCESS )
{
goto TRY_PLAYMODE;
}
// Create buffers where data will be streamed into from the camera
dwResult = CreateStreamBuffers();
if ( dwResult != ERROR_SUCCESS )
{
goto TRY_PLAYMODE;
}
// Retrieve information about the camera, e.g. FOV, focal length, etc.
cameraDetails.cbSize = sizeof( XCAMERA_PHYSICAL_DETAILS ); // Set the structure size
dwResult = XCameraGetPhysicalDetails( &cameraDetails );
if ( dwResult != ERROR_SUCCESS )
{
goto TRY_PLAYMODE;
}
// Enable streaming from the camera. For this sample we want to show the color image as well as the
// depth image, otherwise we could have just used XCAMERA_STREAM_TYPE_JOINT
dwResult = XCameraEnableStreams( XCAMERA_STREAM_TYPE_IMAGE | XCAMERA_STREAM_TYPE_DEPTH | XCAMERA_STREAM_TYPE_JOINT, NULL );
if ( dwResult != ERROR_SUCCESS )
{
goto TRY_PLAYMODE;
}
InstanceCounter ++ ;
return S_OK;
TRY_PLAYMODE:
if (!pGlouk)
{
pGlouk = OpenForRead(ZZZFILENAME);
}
if (!pGlouk)
{
char Name[2048];
memset(Name, 0, sizeof(Name));
CDLG_USR_GetFileName(Name, "ZZZ File|*.ZZZ",NULL,0);
SetFileNameExtend(Name,'.ZZZ');
pGlouk = OpenForRead(Name);
}
if (!pGlouk) return E_FAIL;
InstanceCounter ++ ;
g_Streams[0].dwHeight = 480;
g_Streams[0].dwWidth = 640;
g_Streams[1] = g_Streams[0];
g_Streams[0].pbData = (BYTE*)malloc(640*480*3);
g_Streams[1].pbData = (BYTE*)malloc(640*480*2);
pGlouk->W = 640;
pGlouk->H = 480;
pGlouk->pColorBuffer = (u32*)g_Streams[0].pbData;
pGlouk->pDepthBuffer = (u32*)g_Streams[1].pbData;
InstanceCounter ++ ;
return 0xC0deCafe;
}
//--------------------------------------------------------------------------------------
// Name: ShutDownSkeletonTracking()
// Desc: Shutdown the camera and skeleton tracking
//--------------------------------------------------------------------------------------
VOID ShutDownSkeletonTracking()
{
if (InstanceCounter) InstanceCounter--;
if (InstanceCounter) return;
// First shutdown xjoint, since it is unsafe to first shutdown the camera
XJointShutdown();
XCameraShutdown( NULL );
DestroyStreamBuffers();
}
//--------------------------------------------------------------------------------------
// Name: UpdateSkeletonTracking()
// Desc: For the simple sample we read the data from the camera stream synchronously
// each frame and pass the depthmap on to the skeleton tracking.
//--------------------------------------------------------------------------------------
u32 UpdateSkeletonTracking()
{
DWORD dwResult;
u32 Cool = 0;
// Read the color and depth data from the stream synchronously
for ( UINT i = 0; i < NUM_STREAMS; i++ )
{
dwResult = XCameraGetOverlappedResult( &g_Streams[ i ].Overlapped, NULL );
if ( dwResult == ERROR_SUCCESS )
{
BYTE * pTemp = g_Streams[ i ].pbDataToProcess;
g_Streams[ i ].pbDataToProcess = g_Streams[ i ].pbData;
g_Streams[ i ].pbData = pTemp;
dwResult = XCameraReadStream( g_Streams[ i ].StreamType, g_Streams[ i ].pbDataToProcess,
g_Streams[ i ].dwBufferSize, 0, &g_Streams[ i ].FrameInfo, &g_Streams[ i ].Overlapped );
Cool = 1;
if ( dwResult != ERROR_SUCCESS )
{
//XCameraReadStream failed with dwResult
}
if (i == 1)
{
/* u16 *pBlast = (u16*)g_Streams[ i ].pbData;
u32 Number = g_Streams[ i ].dwHeight * g_Streams[ i ].dwWidth;
while (Number--)
{
*pBlast = *pBlast * 5;
pBlast++;
}*/
}
}
}
// Use the depthmap from the stream buffer to do skeleton tracking so that we keep the visualization and
// the skeleton data in sync. We could increase the frame rate by passing a NULL pointer to
// XJointTrackSkeletons(), at the cose of the visualization stream data not totally being in sync
// with the skeleton data.
if (Cool)
{
VOID* pDepthMap = g_Streams[ DEPTH_STREAM ].pbData;
void ZXOffsetCorrection(s16 *pZBuffer,u32 SX,u32 SY);
ZXOffsetCorrection((s16*)g_Streams[ DEPTH_STREAM ].pbData,g_Streams[ DEPTH_STREAM ].dwWidth,g_Streams[ DEPTH_STREAM ].dwHeight);
// NOTE: This API knows the maximum number of skeletons to track, so don't call this per skeleton, only once per frame
dwResult = XJointTrackSkeletons( 0, pDepthMap, XCAMERA_JOINT_COUNT * g_dwMaxPlayersInGame * sizeof( XCAMERA_JOINT ), g_Joints, NULL, NULL );
if ( dwResult != ERROR_SUCCESS )
{
//XJointTrackSkeletons failed with dwResult=
}
}
return Cool;
}
//--------------------------------------------------------------------------------------
// Name: CreateStreamBuffers()
// Desc: Create memory buffers where camera streaming will be copied to
//--------------------------------------------------------------------------------------
HRESULT CreateStreamBuffers()
{
HRESULT hr = S_OK;
// NOTE: The order of the items in the 'Configs' affects the order of the values returned in the dwConfigSettings array
// when it is filled by XCameraGetConfig. The following const values are declared convenience when reading the data
// from the dwConfigSettings array. If the data in the Configs array changes these values will need to be changed as well
const DWORD dwConfigBufferSizeIndex = 0;
const DWORD dwConfigWidthIndex = 1;
const DWORD dwConfigHeightIndex = 2;
XCAMERA_CONFIG Configs[] = { XCAMERA_CONFIG_BUFFER_SIZE, XCAMERA_CONFIG_WIDTH, XCAMERA_CONFIG_HEIGHT };
DWORD dwConfigSettings[ ARRAYSIZE( Configs ) ];
DWORD dwResult;
// Clear the memory for all streams
for ( UINT i = 0; i < NUM_STREAMS; i++ )
{
ZeroMemory( &g_Streams[ i ], sizeof( StreamData ) );
}
// XCameraGetConfig can be used to query the camera for the current values of one more configuration settings
// The settings values will be return order the identifiers are passed
dwResult = XCameraGetConfig( XCAMERA_STREAM_TYPE_IMAGE, Configs, dwConfigSettings, ARRAYSIZE( Configs ), NULL );
if ( dwResult == ERROR_SUCCESS )
{
// Store the width and height of the color map
g_Streams[ COLOR_STREAM ].dwWidth = dwConfigSettings[ dwConfigWidthIndex ];
g_Streams[ COLOR_STREAM ].dwHeight = dwConfigSettings[ dwConfigHeightIndex ];
// Allocate memory for the color map
g_Streams[ COLOR_STREAM ].pbData = new BYTE[ dwConfigSettings[ dwConfigBufferSizeIndex ] ];
g_Streams[ COLOR_STREAM ].pbDataToProcess = new BYTE[ dwConfigSettings[ dwConfigBufferSizeIndex ] ];
if ( g_Streams[ COLOR_STREAM ].pbData )
{
g_Streams[ COLOR_STREAM ].dwBufferSize = dwConfigSettings[ dwConfigBufferSizeIndex ];
g_Streams[ COLOR_STREAM ].StreamType = XCAMERA_STREAM_TYPE_IMAGE;
}
else
{
// Out of memory
g_Streams[ COLOR_STREAM ].dwBufferSize = 0;
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_FAIL;
}
if ( SUCCEEDED( hr ) )
{
dwResult = XCameraGetConfig( XCAMERA_STREAM_TYPE_DEPTH, Configs, dwConfigSettings, ARRAYSIZE( Configs ), NULL);
if ( dwResult == ERROR_SUCCESS )
{
// Store the width and height of the depth map
g_Streams[ DEPTH_STREAM ].dwWidth = dwConfigSettings[ dwConfigWidthIndex ];
g_Streams[ DEPTH_STREAM ].dwHeight = dwConfigSettings[ dwConfigHeightIndex ];
// Allocate memory for the depth map
g_Streams[ DEPTH_STREAM ].pbData = new BYTE[ dwConfigSettings[ dwConfigBufferSizeIndex ] ];
g_Streams[ DEPTH_STREAM ].pbDataToProcess = new BYTE[ dwConfigSettings[ dwConfigBufferSizeIndex ] ];
if ( g_Streams[ DEPTH_STREAM ].pbData )
{
g_Streams[ DEPTH_STREAM ].dwBufferSize = dwConfigSettings[ dwConfigBufferSizeIndex ];
g_Streams[ DEPTH_STREAM ].StreamType = XCAMERA_STREAM_TYPE_DEPTH;
}
else
{
//
// Out of memory
//
g_Streams[ DEPTH_STREAM ].dwBufferSize = 0;
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_FAIL;
}
}
return hr;
}
//--------------------------------------------------------------------------------------
// Name: DestroyStreamBuffers()
// Desc: Destroy the memory allocated for the streaming buffers
//--------------------------------------------------------------------------------------
void DestroyStreamBuffers()
{
for ( UINT i = 0; i < NUM_STREAMS; i++ )
{
if ( g_Streams[ i ].pbData )
{
delete [] g_Streams[ i ].pbData;
}
ZeroMemory( &g_Streams[ i ], sizeof( StreamData ) );
}
}
#define FLT_EPSILON 1.192092896e-07F
VOID VisualizeSkeleton( MAP *pDST, XCAMERA_JOINT* pJoints )
{
#define uDisplayWidth pDST->SX
#define uDisplayHeight pDST->SY
// Setup constants for projection and drawing
const FLOAT fWidthOver2 = pDST->SX * 0.5f;
const FLOAT fHeightOver2 = pDST->SY * 0.5f;
const FLOAT fInvFocalLength = 1.0f / 571.25909;//cameraDetails.fFocalLength;
const FLOAT fDepthDisplayScaleX = (FLOAT)uDisplayWidth / FLOAT( pDST->SX );
const FLOAT fDepthDisplayScaleY = (FLOAT)uDisplayHeight / FLOAT( pDST->SY );
const INT iDepthDisplayOffsetY = uDisplayHeight / 2;
// Project the world space joints into screen space
for ( u32 i = 0; i < XCAMERA_JOINT_COUNT; i++ )
{
FLOAT fZOverFocalLength = pJoints[ i ].fZ * fInvFocalLength;
// Check for divide by zero
if ( fabs( fZOverFocalLength ) > FLT_EPSILON )
{
g_ScreenSpaceJoints[ i ].x = (INT)( ( fWidthOver2 - pJoints[ i ].fX / fZOverFocalLength ) * fDepthDisplayScaleX );
g_ScreenSpaceJoints[ i ].y = (INT)( ( fHeightOver2 + pJoints[ i ].fY / fZOverFocalLength ) * fDepthDisplayScaleY );
}
else
{
g_ScreenSpaceJoints[ i ].x = 0;
g_ScreenSpaceJoints[ i ].y = 0;
}
}
// Draw each bone in the skeleton using the screen space joints
for ( UINT i = 0; i < g_uNumBones; i++ )
{
// Use the minimum joint confidence for the bone confidence
XCAMERA_JOINT_CONFIDENCE BoneConfidence = min( pJoints[ g_Bones[ i ].StartJoint ].fConfidence,
pJoints[ g_Bones[ i ].EndJoint ].fConfidence );
if ( BoneConfidence >= XCAMERA_JOINT_CONFIDENCE_HIGH )
{
}
else if ( BoneConfidence >= XCAMERA_JOINT_CONFIDENCE_LOW )
{
}
else
{
// A joint in the bone wasn't tracked during skeleton tracking, so just skip over it
continue;
}
// Draw the bone over the color image, clipping y values to the top half of the window
POINT pntArray[ 2 ];
pntArray[ 0 ].x = g_ScreenSpaceJoints[ g_Bones[ i ].StartJoint ].x;
pntArray[ 0 ].y = g_ScreenSpaceJoints[ g_Bones[ i ].StartJoint ].y;
pntArray[ 1 ].x = g_ScreenSpaceJoints[ g_Bones[ i ].EndJoint ].x;
pntArray[ 1 ].y = g_ScreenSpaceJoints[ g_Bones[ i ].EndJoint ].y;
DrawLine(pDST,pntArray[ 0 ].x,pntArray[ 0 ].y,
pntArray[ 1 ].x,pntArray[ 1 ].y,
0x80ffffff);
DrawLine(pDST,pntArray[ 0 ].x,pntArray[ 0 ].y,
pntArray[ 1 ].x,pntArray[ 1 ].y,
0x80ffffff);
DrawLine(pDST,pntArray[ 0 ].x,pntArray[ 0 ].y,
pntArray[ 1 ].x,pntArray[ 1 ].y,
0x80ffffff);
DrawLine(pDST,pntArray[ 0 ].x,pntArray[ 0 ].y,
pntArray[ 1 ].x,pntArray[ 1 ].y,
0x80ffffff);
void DrawCross(MAP *image, POINT p, u32 color, int len, char orient = 3);
DrawCross(pDST,pntArray[ 0 ],0x80ffffff , pDST->SX / 80);
DrawCross(pDST,pntArray[ 1 ],0x80ffffff , pDST->SX / 80);
u8 TEXT[2048];
sprintf((s8*)TEXT,"%d",g_Bones[ i ].StartJoint);
DRawTEXT_Soft_B((u8*)TEXT,(u32*)pDST->GetBase(),pntArray[ 0 ].x , pntArray[ 0 ].y,pDST->PITCH, pDST->SY, 0xffff0000);
sprintf((s8*)TEXT,"%d",g_Bones[ i ].EndJoint);
DRawTEXT_Soft_B((u8*)TEXT,(u32*)pDST->GetBase(),pntArray[ 1 ].x , pntArray[ 1 ].y,pDST->PITCH, pDST->SY, 0xffff0000);
}
}
class NATAL_Grabber:public INPUT_IO
{
public:
u32 STREAMINDEX ;
u32 PlayMode;
u32 SaveMode;
WORLD *pScene;
int INIT (class WORLD*PS){pScene =PS; return 0;};
int FRAME (void);
int END (void);
IOTYPE GetType() {return IOtype_NATAL;};
};
static u32 RRRInit = 100;
static float Energy = 0;
float NATAL_Compare2Players(int I1 , int I2);
int NATAL_Grabber::FRAME()
{
if (!PlayMode)
{
if (STREAMINDEX == 0)
{
ZERZERZERSaveEnergy();
if (!UpdateSkeletonTracking()) return 0;
float LocalSquare = NATAL_Compare2Players(0 , 4);
LocalSquare *= LocalSquare;
LocalSquare *= LocalSquare;
LocalSquare *= LocalSquare;
Energy = Energy * 0.5f + 0.5f * (1.0f - LocalSquare);
if (RRRInit)
{
RRRInit--;
ZERZERZERSave();
}
else
ZERZERZERRestore();
if (SaveMode)
{
if (!pGlouk)
{
char Name[2048];
memset(Name, 0, sizeof(Name));
CDLG_USR_GetFileName(Name, "ZZZ File|*.ZZZ",NULL,0);
SetFileNameExtend(Name,'.ZZZ');
pGlouk = OpenForWrite(Name,Image.SX,Image.SY,sizeof(g_Joints));
}
u32 Voidosdre;
Write(pGlouk, g_Streams[0].pbData, (u16*)g_Streams[1].pbData, (u8*)g_Joints, sizeof(g_Joints));
}
}//*/
}
else
if (STREAMINDEX == 0) //UpdateSkeletonTracking();
{
u32 Voidosdre;
Read(pGlouk, g_Streams[0].pbData, (u16*)g_Streams[1].pbData, (u8*)g_Joints, sizeof(g_Joints));
}
u8 *pBase = (u8*)g_Streams[1].pbData;
u8 *pBaseRGB = (u8*)g_Streams[0].pbData;
u8 *pImage = (u8*)Image.GetBase();
pBase += Image.SY * Image.SX * (2);
pBaseRGB += Image.SY * Image.SX * (3);
for (s32 Y = 0 ;Y<Image.SY ; Y++)
for (s32 X = 0 ;X<Image.SX; X++)
{
if (!STREAMINDEX)
{
pBaseRGB -= 3;
pBase-=2;
u16 Value = *(u16 *)pBase;
if (1)//*(s16*)pBase && (*(s16*)pBase < 4000))//Value)
{
pImage[0] = pBaseRGB[2];
pImage[1] = pBaseRGB[1];
pImage[2] = pBaseRGB[0];
if (*(s16*)pBase && (*(s16*)pBase < 2000))//Value))
pImage[3] = 0xff;
else
pImage[3] = 0;
} else
{
pImage[0] = pImage[1] = pImage[2] = 0;
}
} else
{
pBaseRGB -= 3;
pBase-=2;
u16 Value = *(u16 *)pBase;
if ((Value == 0 ) /*|| (Value > 3000)*/)
{
Value = (X ^ Y) & 32;
pImage[0] = pBaseRGB[2]>>1;
pImage[1] = pBaseRGB[1]>>1;
pImage[2] = pBaseRGB[0]>>1;
pImage[0] = pImage[1] = pImage[2] = 0;
} else
{
Value = 64.0*65536.0f / (float)Value;
pImage[0] = (Value>>0) & 0xff;
if ((Value >>0) & 256) pImage[0] ^= 0xff;
pImage[1] = (Value>>2) & 0xff;
if ((Value >>2) & 256) pImage[1] ^= 0xff;
pImage[2] = (Value>>4) & 0xff;
if ((Value >>3) & 256) pImage[2] ^= 0xff;
if (Value & 0x100) pImage[2] ^= 0xff;
// pImage[0] = pImage[1] = pImage[2] = 0xff;
}
/*if (Value & 64)
{
pImage[0]>>=1;
pImage[1]>>=1;
pImage[2]>>=1;
}*/
//if (pBase[1] & 1) pImage[1] ^= 0xff;
//if (pBase[0] & 1) pImage[1] ^= 0xff;//*/
}
pImage+=4;
}//*/
#ifdef DEBUGINFO
if (STREAMINDEX == 1)
{
VisualizeSkeleton( &Image, g_Joints);
VisualizeSkeleton( &Image, g_Joints + XCAMERA_JOINT_COUNT);
// MAP_ComputePlanes(&Image,(u16*)g_Streams[STREAMINDEX].pbData);
}
#endif
if (pScene && pScene->WebCamXInvert)
{
s32 *ImageB,*ImageE;
ImageB = Image.GetBase();
ImageE = Image.GetBase() + Image.PITCH * Image.SY;
while (ImageB < ImageE)
{
s32 *RB,*RE;
RB = ImageB;
RE = ImageB + Image.SX - 1;
while (RB < RE)
{
s32 Swap;
Swap = *RB;
*RB = *RE;
*RE = Swap;
RB++;
RE--;
}
ImageB+=Image.PITCH;
}
}
if (SaveMode)
{
DRawTEXT_Soft_B2x((u8*)"RECORD",(u32*)Image.GetBase(),20,20,Image.PITCH,Image.SY,0xff0000);
}
return 1;
}
int NATAL_Grabber::END()
{
ShutDownSkeletonTracking();
CC_free(Image.GetBase());
return 0;
};
float NATAL_Compare2Players()
{
if (RRRInit) return RRRInit;
return NATAL_Compare2Players(0,1);
}
void NATAL_GetBone(INPUT_IO *pMedia,u32 Index , Vector *pDst , u32 Oldness)
{
if (pMedia->GetType() == IOtype_NATAL)
{
Oldness &= (g_dwMaxPlayersInGame - 1);
pDst->x = g_Joints[Index + Oldness * XCAMERA_JOINT_COUNT].fX;
pDst->y = g_Joints[Index + Oldness * XCAMERA_JOINT_COUNT].fY;
pDst->z = g_Joints[Index + Oldness * XCAMERA_JOINT_COUNT].fZ;
}
}
float NATAL_GetBone2DPertinence(INPUT_IO *pMedia,u32 Index)
{
if (pMedia->GetType() == IOtype_NATAL)
{
return g_Joints[Index].fConfidence;
}
return 0.0f;
}
void NATAL_GetZMap(INPUT_IO *pMedia,MAP16 *pZMap)
{
if (pMedia->GetType() == IOtype_NATAL)
{
pZMap->SetBase((s16*)g_Streams[1].pbData);
pZMap->PITCH = pZMap->SX = g_Streams[1].dwWidth;
pZMap->SY = g_Streams[1].dwHeight;
}
}
void NATAL_Record(INPUT_IO *pMedia,u32 Record)
{
if (pMedia->GetType() == IOtype_NATAL)
{
if (((NATAL_Grabber*)pMedia)->PlayMode == 0)
((NATAL_Grabber*)pMedia)->SaveMode = Record;
}
}
INPUT_IO *NATAL_CREATE(WORLD *pScene,char *Filename)
{
u32 ZBuf = 0;
if ((Filename[0] == 'z') || (Filename[0] == 'Z')) ZBuf = 1;
FILE *K = CC_fopen(ZZZFILENAME,"rb");
if (K) CC_fclose(K);
HRESULT Res = InitializeSkeletonTracking();
if ((Res == S_OK) || (Res == 0xC0deCafe))
{
INPUT_IO *Ret;
Ret = (INPUT_IO *)new(NATAL_Grabber);
strcpy((char*)Ret->MediaName,Filename);
((NATAL_Grabber*)Ret)->pScene = pScene;
((NATAL_Grabber*)Ret)->STREAMINDEX = ZBuf;
((NATAL_Grabber*)Ret)->PlayMode = 0;
((NATAL_Grabber*)Ret)->SaveMode = 0;
if (Res == 0xC0deCafe)
((NATAL_Grabber*)Ret)->PlayMode = 1;
Ret->Image.SX = 0;
Ret->Image.SY = 0;
Ret->Image.SetBase(NULL);
Ret->dTotalTime = 0;
Ret->dAvgFramePerSecond = 30.0;
Ret->Image.PITCH = Ret->Image.SX = g_Streams[((NATAL_Grabber*)Ret)->STREAMINDEX].dwWidth;
Ret->Image.SY = g_Streams[((NATAL_Grabber*)Ret)->STREAMINDEX].dwHeight;
Ret->Image.SetBase((s32*)CC_malloc(Ret->Image.SX * Ret->Image.SY * 4));
return (INPUT_IO *)Ret;
}
return NULL;
};
#else
class NATAL_Grabber:public INPUT_IO
{
public:
int INIT (class WORLD*){return 0;};
int FRAME (void){return 0;};
int END (void){return 0;};
IOTYPE GetType() {return IOtype_NATAL;};
};
INPUT_IO *NATAL_CREATE(WORLD *pScene,char *Filename)
{
INPUT_IO *Ret;
Ret = (INPUT_IO *)new(NATAL_Grabber);
strcpy((char*)Ret->MediaName,Filename);
Ret->Image.SX = 0;
Ret->Image.SY = 0;
Ret->Image.SetBase(NULL);
Ret->dTotalTime = 0;
Ret->dAvgFramePerSecond = 30.0;
return (INPUT_IO *)Ret;
};
void NATAL_GetZMap(INPUT_IO *pMedia,MAP16 *pZMap)
{
}
#endif