Skip to content

Instantly share code, notes, and snippets.

@UnaNancyOwen
Last active May 19, 2017 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save UnaNancyOwen/af6d465ac01cfb5e826774e0ff361199 to your computer and use it in GitHub Desktop.
Save UnaNancyOwen/af6d465ac01cfb5e826774e0ff361199 to your computer and use it in GitHub Desktop.
Serialize Definitions of Boost.Serialization (XML) for Kinect SDK v2 Body Data
// kinect2_serialization
//
// kinect2_serialization is definitions of Boost.Serialization (XML) for body data that retrieved using Kinect SDK v2.
// You will be able to serialize and deserialize body data using this definitions.
// kinect2_serialization are requires Boost.Serialization and Kinect SDK v2 when serializing data.
// kinect2_serialization are requires only Boost.Serialization when deserialize data.
//
// This source code is licensed under the MIT license. Please see the License in License.txt.
// Copyright (c) 2017 Tsukasa SUGIURA
// t.sugiura0204@gmail.com
#ifndef __KINECT2_SERIALIZATION__
#define __KINECT2_SERIALIZATION__
#include <iostream>
#include <cstdint>
#include <array>
#include <string>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/string.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
// Error Check Macro
#ifndef FAILED
#define FAILED(hr) (((HRESULT)(hr)) < 0)
#endif
#ifndef ERROR_CHECK
#define ERROR_CHECK( ret ) \
if( FAILED( ret ) ){ \
std::stringstream ss; \
ss << "failed " #ret " " << std::hex << ret << std::endl; \
throw std::runtime_error( ss.str().c_str() ); \
}
#endif
// Body Count
#ifndef BODY_COUNT
#define BODY_COUNT 6
#endif
// Joint Type
#ifndef _JointType_
#define _JointType_
typedef enum _JointType JointType;
enum _JointType
{
JointType_SpineBase = 0,
JointType_SpineMid = 1,
JointType_Neck = 2,
JointType_Head = 3,
JointType_ShoulderLeft = 4,
JointType_ElbowLeft = 5,
JointType_WristLeft = 6,
JointType_HandLeft = 7,
JointType_ShoulderRight = 8,
JointType_ElbowRight = 9,
JointType_WristRight = 10,
JointType_HandRight = 11,
JointType_HipLeft = 12,
JointType_KneeLeft = 13,
JointType_AnkleLeft = 14,
JointType_FootLeft = 15,
JointType_HipRight = 16,
JointType_KneeRight = 17,
JointType_AnkleRight = 18,
JointType_FootRight = 19,
JointType_SpineShoulder = 20,
JointType_HandTipLeft = 21,
JointType_ThumbLeft = 22,
JointType_HandTipRight = 23,
JointType_ThumbRight = 24,
JointType_Count = ( JointType_ThumbRight + 1 )
};
#endif
// Tracking State
#ifndef _TrackingState_
#define _TrackingState_
typedef enum _TrackingState TrackingState;
enum _TrackingState
{
TrackingState_NotTracked = 0,
TrackingState_Inferred = 1,
TrackingState_Tracked = 2
};
#endif
// CameraSpacePoint
#ifndef _CameraSpacePoint_
#define _CameraSpacePoint_
typedef struct _CameraSpacePoint
{
float X;
float Y;
float Z;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive& archive, unsigned int version )
{
static_cast<void>( version );
archive & boost::serialization::make_nvp( "X", X );
archive & boost::serialization::make_nvp( "Y", Y );
archive & boost::serialization::make_nvp( "Z", Z );
}
} CameraSpacePoint;
#else
namespace boost
{
namespace serialization
{
template<class Archive>
void serialize( Archive& archive, CameraSpacePoint& position, unsigned int version )
{
static_cast<void>( version );
archive & boost::serialization::make_nvp( "X", position.X );
archive & boost::serialization::make_nvp( "Y", position.Y );
archive & boost::serialization::make_nvp( "Z", position.Z );
}
}
}
#endif
// Joint
#ifndef _Joint_
#define _Joint_
typedef struct _Joint
{
JointType JointType;
CameraSpacePoint Position;
TrackingState TrackingState;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive& archive, unsigned int version )
{
static_cast<void>( version );
archive & boost::serialization::make_nvp( "JointType", JointType );
archive & boost::serialization::make_nvp( "TrackingState", TrackingState );
if( TrackingState == TrackingState::TrackingState_NotTracked ){
return;
}
archive & boost::serialization::make_nvp( "CameraSpacePoint", Position );
}
} Joint;
#else
namespace boost
{
namespace serialization
{
template<class Archive>
void serialize( Archive& archive, Joint& joint, unsigned int version )
{
static_cast<void>( version );
archive & boost::serialization::make_nvp( "JointType", joint.JointType );
archive & boost::serialization::make_nvp( "TrackingState", joint.TrackingState );
if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){
return;
}
archive & boost::serialization::make_nvp( "CameraSpacePoint", joint.Position );
}
}
}
#endif
// Body
#ifndef _Body_
#define _Body_
typedef struct _Body
{
public:
// Constructor
_Body()
{}
#ifdef __IBody_INTERFACE_DEFINED__
// Constructor
_Body( const IBody* cbody )
{
*this = cbody;
}
// Operator Assignment
_Body& operator = ( const IBody* cbody )
{
IBody* body = const_cast<IBody*>( cbody );
BOOLEAN tracked = FALSE;
ERROR_CHECK( body->get_IsTracked( &tracked ) );
set_IsTracked( ( tracked == TRUE ? true : false ) );
UINT64 trackingId = 0;
ERROR_CHECK( body->get_TrackingId( &trackingId ) );
set_TrackingId( trackingId );
std::array<Joint, JointType::JointType_Count> joints;
ERROR_CHECK( body->GetJoints( static_cast<UINT>( joints.size() ), &joints[0] ) );
SetJoints( joints.size(), &joints[0] );
return *this;
}
#endif
// Get Tracking State
const bool get_IsTracked( bool* tracked ) const noexcept
{
*tracked = this->tracked;
return true;
}
// Set Tracking State
const bool set_IsTracked( const bool tracked ) noexcept
{
this->tracked = tracked;
return true;
}
// Get Tracking ID
const bool get_TrackingId( uint64_t* trackingId ) const noexcept
{
*trackingId = this->trackingId;
return true;
}
// Set Tracking ID
const bool set_TrackingId( const uint64_t trackingId ) noexcept
{
this->trackingId = trackingId;
return true;
}
// Get Joints
const bool GetJoints( const size_t capacity, Joint* joints ) const noexcept
{
if( capacity != this->joints.size() ){
return false;
}
std::copy( &this->joints[0], &this->joints[0] + capacity, &joints[0] );
return true;
}
// Set Joints
const bool SetJoints( const size_t capacity, const Joint* joints ) noexcept
{
if( capacity != this->joints.size() ){
return false;
}
std::copy( &joints[0], &joints[0] + capacity, &this->joints[0] );
return true;
}
private:
bool tracked = false;
uint64_t trackingId = 0;
std::array<Joint, JointType::JointType_Count> joints;
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive& archive, unsigned int version )
{
static_cast<void>( version );
archive & boost::serialization::make_nvp( "TrackingState", tracked );
if( !tracked ){
return;
}
archive & boost::serialization::make_nvp( "TrackingID", trackingId );
archive & boost::serialization::make_nvp( "Joint", joints );
}
} Body;
#endif
// Frame
#ifndef _Frame_
#define _Frame_
typedef struct _Frame
{
public:
// Constructor
_Frame()
{}
#ifdef __IBodyFrame_INTERFACE_DEFINED__
// Constructor
_Frame( const IBodyFrame* cframe )
{
*this = cframe;
}
// Operator Assignment
_Frame& operator = ( const IBodyFrame* cframe )
{
IBodyFrame* frame = const_cast<IBodyFrame*>( cframe );
TIMESPAN rerativeTime = 0;
ERROR_CHECK( frame->get_RelativeTime( &rerativeTime ) );
set_RelativeTime( rerativeTime );
std::array<IBody*, BODY_COUNT> bodies = { nullptr };
ERROR_CHECK( frame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
SetBodies( bodies.size(), const_cast<const IBody**>( &bodies[0] ) );
std::for_each( bodies.begin(), bodies.end(), []( IBody*& body ){ if( body != nullptr ){ body->Release(); body = nullptr; } } );
return *this;
}
#endif
// Get RelativeTime
const bool get_RelativeTime( int64_t* relativeTime ) const noexcept
{
*relativeTime = this->relativeTime;
return true;
}
// Set RelativeTime
const bool set_RelativeTime( const int64_t relativeTime ) noexcept
{
this->relativeTime = relativeTime;
return true;
}
// Get Bodies
const bool GetBodies( const size_t capacity, Body* bodies ) const noexcept
{
if( capacity != this->bodies.size() ){
return false;
}
std::copy( &this->bodies[0], &this->bodies[0] + capacity, &bodies[0] );
return true;
}
#ifdef __IBody_INTERFACE_DEFINED__
// Set Bodies
const bool SetBodies( const size_t capacity, const IBody** bodies ) noexcept
{
if( capacity != this->bodies.size() ){
return false;
}
std::copy( &bodies[0], &bodies[0] + capacity, &this->bodies[0] );
return true;
}
#endif
private:
int64_t relativeTime = 0;
std::array<Body, BODY_COUNT> bodies;
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive& archive, unsigned int version )
{
static_cast<void>( version );
archive & boost::serialization::make_nvp( "RerativeTime", relativeTime );
archive & boost::serialization::make_nvp( "Body", bodies );
}
} Frame;
#endif
#endif // __KINECT2_SERIALIZATION__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment