354 lines
No EOL
14 KiB
C++
354 lines
No EOL
14 KiB
C++
// *!* This must be synchronized with the motion capture tool that generates gestures *.example files and then the engine must be synchronized with this tool (the skeleton save/load format)
|
|
|
|
//#include <XnaMath.h>
|
|
#define TARGET_X360
|
|
#define TARGET_DURANGO
|
|
#include "HumanTrackingTypes.h"
|
|
#include "MyExamplesFile.h"
|
|
#include <stdio.h>
|
|
#include <zlib.h>
|
|
#include <string>
|
|
|
|
using namespace Examples;
|
|
|
|
/*
|
|
4 bytes which interpreted as char should be "ISM\0"
|
|
8 bytes which interpreted as u64 is the number of frames
|
|
<frame>
|
|
4 bytes which interpreted as u32 should be 0xBAADF00D
|
|
4 coaches like this:
|
|
<coach>
|
|
<skeleton>
|
|
4 bytes which interpreted as u32 should be 0xDEADBABE
|
|
<joint>
|
|
4 bytes which interpreted as u32 is the joint ID
|
|
4 bytes which interpreted as f32 is the x coordinate of the position of the skeleton joint
|
|
4 bytes which interpreted as f32 is the y coordinate of the position of the skeleton joint
|
|
4 bytes which interpreted as f32 is the z coordinate of the position of the skeleton joint
|
|
</joint>
|
|
</skeleton>
|
|
</coach>
|
|
</frame>
|
|
*/
|
|
|
|
void xmvectorToHTPosition (DirectX::XMVECTOR vect, HT_Position& pos)
|
|
{
|
|
//converts from Kinect space to IISU space(swap y and z axis)
|
|
pos.x = XMVectorGetX(vect);
|
|
pos.z = XMVectorGetY(vect);
|
|
pos.y = XMVectorGetZ(vect);
|
|
}
|
|
|
|
void x360ToIISUSkel(NUI_SKELETON_DATA& skel, HT_Skeleton& newSkel)
|
|
{
|
|
for (int i = 0; i < HT_KEYPOINTS_COUNT; i++)
|
|
newSkel.joints[i].confidence = 1.0f;
|
|
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_HIP_CENTER], newSkel.joints[HT_PELVIS].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_SPINE], newSkel.joints[HT_SPINE_1].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_SHOULDER_CENTER], newSkel.joints[HT_SPINE_2].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_SHOULDER_CENTER], newSkel.joints[HT_NECK].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_HEAD], newSkel.joints[HT_HEAD].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_SHOULDER_RIGHT], newSkel.joints[HT_RIGHT_SHOULDER].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_ELBOW_RIGHT], newSkel.joints[HT_RIGHT_ELBOW].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_WRIST_RIGHT], newSkel.joints[HT_RIGHT_WRIST].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_HAND_RIGHT], newSkel.joints[HT_RIGHT_FINGERS].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_HIP_RIGHT], newSkel.joints[HT_RIGHT_HIP].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_KNEE_RIGHT], newSkel.joints[HT_RIGHT_KNEE].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_ANKLE_RIGHT], newSkel.joints[HT_RIGHT_ANKLE].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_FOOT_RIGHT], newSkel.joints[HT_RIGHT_TOES].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_SHOULDER_LEFT], newSkel.joints[HT_LEFT_SHOULDER].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_ELBOW_LEFT], newSkel.joints[HT_LEFT_ELBOW].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_WRIST_LEFT], newSkel.joints[HT_LEFT_WRIST].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_HAND_LEFT], newSkel.joints[HT_LEFT_FINGERS].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_HIP_LEFT], newSkel.joints[HT_LEFT_HIP].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_KNEE_LEFT], newSkel.joints[HT_LEFT_KNEE].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_ANKLE_LEFT], newSkel.joints[HT_LEFT_ANKLE].position);
|
|
xmvectorToHTPosition (skel.SkeletonPositions[NUI_SKELETON_POSITION_FOOT_LEFT], newSkel.joints[HT_LEFT_TOES].position);
|
|
}
|
|
|
|
void DurangoToIISUSkel(Durango::Body& skel, HT_Skeleton& newSkel)
|
|
{
|
|
for (int i = 0; i < HT_KEYPOINTS_COUNT; i++)
|
|
newSkel.joints[i].confidence = 1.0f;
|
|
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_SPINE_BASE], newSkel.joints[HT_PELVIS].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_SPINE_MID], newSkel.joints[HT_SPINE_1].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_SPINE_SHOULDER], newSkel.joints[HT_SPINE_2].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_NECK], newSkel.joints[HT_NECK].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_HEAD], newSkel.joints[HT_HEAD].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_SHOULDER_RIGHT], newSkel.joints[HT_RIGHT_SHOULDER].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_ELBOW_RIGHT], newSkel.joints[HT_RIGHT_ELBOW].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_WRIST_RIGHT], newSkel.joints[HT_RIGHT_WRIST].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_HAND_RIGHT], newSkel.joints[HT_RIGHT_FINGERS].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_HIP_RIGHT], newSkel.joints[HT_RIGHT_HIP].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_KNEE_RIGHT], newSkel.joints[HT_RIGHT_KNEE].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_ANKLE_RIGHT], newSkel.joints[HT_RIGHT_ANKLE].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_FOOT_RIGHT], newSkel.joints[HT_RIGHT_TOES].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_SHOULDER_LEFT], newSkel.joints[HT_LEFT_SHOULDER].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_ELBOW_LEFT], newSkel.joints[HT_LEFT_ELBOW].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_WRIST_LEFT], newSkel.joints[HT_LEFT_WRIST].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_HAND_LEFT], newSkel.joints[HT_LEFT_FINGERS].position);
|
|
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_HIP_LEFT], newSkel.joints[HT_LEFT_HIP].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_KNEE_LEFT], newSkel.joints[HT_LEFT_KNEE].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_ANKLE_LEFT], newSkel.joints[HT_LEFT_ANKLE].position);
|
|
xmvectorToHTPosition (skel.SkeletonJointPositions[Durango::eBodyJointIndex_FOOT_LEFT], newSkel.joints[HT_LEFT_TOES].position);
|
|
}
|
|
|
|
// function that reads all the frames with the skeletons in Durango format
|
|
// transforms them into IISU format, and puts them in the outfile
|
|
int DurangoToIISU(FILE* file, FILE* outfile, ExampleFrameTableEntry* tableEntries, ExampleHeader& header)
|
|
{
|
|
|
|
ExamplesFrameDurango examplesFrame;
|
|
|
|
u32 FRAME_MAGIC = 0xBAADF00D;
|
|
u32 SKELETON_MAGIC = 0xDEADBABE;
|
|
|
|
int itemsRead;
|
|
bool allFramesHaveSkeletons = true;
|
|
for( UINT64 frameIndex = 0; frameIndex < header.frameCount; ++frameIndex)
|
|
{
|
|
// read in the next compressed frame
|
|
_fseeki64( file, tableEntries[frameIndex].frameOffset, 0 );
|
|
BYTE* compressedFrame = new BYTE[(unsigned int)(tableEntries[frameIndex].frameSize)];
|
|
itemsRead = fread_s( compressedFrame, (size_t)(tableEntries[frameIndex].frameSize), (size_t)(tableEntries[frameIndex].frameSize), 1, file );
|
|
if( itemsRead == 0 )
|
|
{
|
|
printf ("Error at fread_s.\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
// decompress frame
|
|
unsigned long destLength = sizeof( ExamplesFrameDurango );
|
|
int err = uncompress( (BYTE*)&examplesFrame, &destLength, compressedFrame, (unsigned long)tableEntries[frameIndex].frameSize );
|
|
|
|
delete [] compressedFrame;
|
|
|
|
if( err != 0 )
|
|
{
|
|
printf ("Error at uncompress.\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
fwrite (&FRAME_MAGIC, sizeof(FRAME_MAGIC), 1, outfile);
|
|
|
|
Durango::BodyFrame& skeletonFrame = examplesFrame.skeletonFrame;
|
|
bool foundOneGoodSkeletonThisFrame = false;
|
|
// only 4 reference skeletons are transformed
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
|
|
Durango::Body& skel = skeletonFrame.BodyData[i];
|
|
|
|
HT_Skeleton ht_skeleton;
|
|
|
|
DurangoToIISUSkel(skel, ht_skeleton);
|
|
|
|
//if ((ht_skeleton.joints[HT_HEAD].position.x != 0) || (ht_skeleton.joints[HT_HEAD].position.y != 0) || (ht_skeleton.joints[HT_HEAD].position.z != 0))
|
|
{
|
|
fwrite(&SKELETON_MAGIC, sizeof(SKELETON_MAGIC), 1, outfile);
|
|
for(int j = 0; j < HT_KEYPOINTS_COUNT; j++)
|
|
{
|
|
|
|
fwrite (&j, sizeof(u32), 1, outfile);
|
|
fwrite (&ht_skeleton.joints[j].position.x, sizeof(f32), 1, outfile);
|
|
fwrite (&ht_skeleton.joints[j].position.y, sizeof(f32), 1, outfile);
|
|
fwrite (&ht_skeleton.joints[j].position.z, sizeof(f32), 1, outfile);
|
|
}
|
|
foundOneGoodSkeletonThisFrame = true;
|
|
}
|
|
}
|
|
allFramesHaveSkeletons &= foundOneGoodSkeletonThisFrame;
|
|
}
|
|
|
|
if (allFramesHaveSkeletons)
|
|
return 0;
|
|
else
|
|
return -1; // not all frames have skeletons so we return an error of -1 to signal that this example file is not good
|
|
}
|
|
|
|
// function that reads all the frames with the skeletons in X360 format
|
|
// transforms them into IISU format, and puts them in the outfile
|
|
int X360ToIISU(FILE* file, FILE* outfile, ExampleFrameTableEntry* tableEntries, ExampleHeader& header)
|
|
{
|
|
|
|
ExamplesFrameX360 examplesFrame;
|
|
|
|
u32 FRAME_MAGIC = 0xBAADF00D;
|
|
u32 SKELETON_MAGIC = 0xDEADBABE;
|
|
int itemsRead;
|
|
|
|
bool allFramesHaveSkeletons = true;
|
|
for( UINT64 frameIndex = 0; frameIndex < header.frameCount; ++frameIndex)
|
|
{
|
|
// read in the next compressed frame
|
|
_fseeki64( file, tableEntries[frameIndex].frameOffset, 0 );
|
|
BYTE* compressedFrame = new BYTE[(unsigned int)(tableEntries[frameIndex].frameSize)];
|
|
itemsRead = fread_s( compressedFrame, (size_t)(tableEntries[frameIndex].frameSize), (size_t)(tableEntries[frameIndex].frameSize), 1, file );
|
|
if( itemsRead == 0 )
|
|
{
|
|
printf ("Error at fread_s.\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
// decompress frame
|
|
unsigned long destLength = sizeof( ExamplesFrameX360 );
|
|
int err = uncompress( (BYTE*)&examplesFrame, &destLength, compressedFrame, (unsigned long)tableEntries[frameIndex].frameSize );
|
|
|
|
delete [] compressedFrame;
|
|
|
|
if( err != 0 )
|
|
{
|
|
printf ("Error at uncompress.\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
fwrite (&FRAME_MAGIC, sizeof(u32), 1, outfile);
|
|
|
|
NUI_SKELETON_FRAME& skeletonFrame = examplesFrame.skeletonFrame;
|
|
|
|
bool foundOneGoodSkeletonThisFrame = false;
|
|
// only 4 reference skeletons are transformed
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
|
|
NUI_SKELETON_DATA& skel = skeletonFrame.SkeletonData[i];
|
|
HT_Skeleton ht_skeleton;
|
|
|
|
x360ToIISUSkel(skel, ht_skeleton);
|
|
|
|
//if ((ht_skeleton.joints[HT_HEAD].position.x != 0) || (ht_skeleton.joints[HT_HEAD].position.y != 0) || (ht_skeleton.joints[HT_HEAD].position.z != 0))
|
|
{
|
|
fwrite(&SKELETON_MAGIC, sizeof(u32), 1, outfile);
|
|
for(int j = 0; j < HT_KEYPOINTS_COUNT; j++)
|
|
{
|
|
|
|
fwrite (&j, sizeof(u32), 1, outfile);
|
|
fwrite (&ht_skeleton.joints[j].position.x, sizeof(f32), 1, outfile);
|
|
fwrite (&ht_skeleton.joints[j].position.y, sizeof(f32), 1, outfile);
|
|
fwrite (&ht_skeleton.joints[j].position.z, sizeof(f32), 1, outfile);
|
|
}
|
|
foundOneGoodSkeletonThisFrame = true;
|
|
}
|
|
}
|
|
allFramesHaveSkeletons &= foundOneGoodSkeletonThisFrame;
|
|
}
|
|
|
|
if (allFramesHaveSkeletons)
|
|
return 0;
|
|
else
|
|
return -1; // not all frames have skeletons so we return an error of -1 to signal that this example file is not good
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
|
|
if (argc <= 3)
|
|
{
|
|
printf("usage: ParseExample <filename> <outfile> durango|x360");
|
|
return E_FAIL;
|
|
}
|
|
|
|
FILE* file;
|
|
fopen_s (&file, argv[1], "rb");
|
|
if (!file)
|
|
{
|
|
printf ("Input file %s can't be opened.\n", argv[1]);
|
|
return E_FAIL;
|
|
}
|
|
|
|
FILE* outfile;
|
|
fopen_s (&outfile, argv[2], "wb");
|
|
if (!outfile)
|
|
{
|
|
printf ("Output file %s can't be opened.\n", argv[2]);
|
|
return E_FAIL;
|
|
}
|
|
|
|
int platform;
|
|
char EXAMPLES_FILE_HEADER_TAG[4];
|
|
if (strcmp(argv[3], "durango") == 0)
|
|
{
|
|
platform = DURANGO;
|
|
strcpy_s (EXAMPLES_FILE_HEADER_TAG, sizeof(EXAMPLES_FILE_HEADER_TAG_DURANGO), EXAMPLES_FILE_HEADER_TAG_DURANGO);
|
|
}
|
|
|
|
else if (strcmp(argv[3], "x360") == 0)
|
|
{
|
|
|
|
platform = X360;
|
|
strcpy_s (EXAMPLES_FILE_HEADER_TAG, sizeof(EXAMPLES_FILE_HEADER_TAG_X360), EXAMPLES_FILE_HEADER_TAG_X360);
|
|
}
|
|
|
|
else
|
|
{
|
|
printf ("Bad argument 3. Use durango or x360.\n");
|
|
fclose(file);
|
|
fclose(outfile);
|
|
return E_FAIL;
|
|
}
|
|
|
|
printf ("Processing %s -> %s\n", argv[1], argv[2]);
|
|
|
|
// read and check the header of the input file
|
|
ExampleHeader header;
|
|
size_t itemsRead = fread_s( &header, sizeof( header ), sizeof( header ), 1, file );
|
|
if( itemsRead == 0 )
|
|
{
|
|
printf( "\n\nError: fread_s( %s ) failed. Err 0x%08x\n\n", argv[1], errno );
|
|
fclose(file);
|
|
fclose(outfile);
|
|
return E_FAIL;
|
|
}
|
|
|
|
if( strncmp( header.headerTag, EXAMPLES_FILE_HEADER_TAG, 3 ) != 0 )
|
|
{
|
|
printf( "\n\nIncorrect file version. Wanted %s, got %s\n\n", EXAMPLES_FILE_HEADER_TAG, header.headerTag );
|
|
fclose(file);
|
|
fclose(outfile);
|
|
return E_FAIL;
|
|
}
|
|
|
|
// read in the offset table
|
|
ExampleFrameTableEntry* tableEntries = new ExampleFrameTableEntry[(unsigned int)header.frameCount];
|
|
_fseeki64( file, header.frameTableOffset, 0 );
|
|
itemsRead = fread_s( tableEntries, (size_t)(sizeof( ExampleFrameTableEntry ) * header.frameCount), (size_t)(sizeof( ExampleFrameTableEntry ) * header.frameCount), 1, file );
|
|
if( itemsRead == 0 )
|
|
{
|
|
printf( "\n\nError: fread_s( %s ) failed. Err 0x%08x\n\n", argv[1], errno );
|
|
fclose(file);
|
|
fclose(outfile);
|
|
return E_FAIL;
|
|
}
|
|
|
|
// write the header of the outfile
|
|
fwrite ("ISM\0", sizeof(char), 4, outfile);
|
|
fwrite (&header.frameCount, sizeof(u64), 1, outfile);
|
|
|
|
int error = 0;
|
|
if(platform == DURANGO)
|
|
{
|
|
error = DurangoToIISU(file, outfile, tableEntries, header);
|
|
}
|
|
|
|
else
|
|
{
|
|
error = X360ToIISU(file, outfile,tableEntries, header);
|
|
}
|
|
|
|
delete [] tableEntries;
|
|
|
|
fclose(file);
|
|
fclose(outfile);
|
|
|
|
return error;
|
|
} |