743 lines
No EOL
23 KiB
C++
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 |