
#ifndef  __JBXL_CPP_VMD_TOOL_H_
#define  __JBXL_CPP_VMD_TOOL_H_


#include  "common++.h"
#include  "xtools++.h"

#include  "NiJointsTool.h"



#define   VMD_FILE_HD_ID2	"Vocaloid Motion Data 0002"

#define	  VMD_MAX_JOINT_NUM 35
#define   VMD_GRID_UNIT     0.08	// m/grid

#define   VMD_FARME_RATE	30		// FPS




//
#define	  VMD_PARENT		 0
#define	  VMD_CENTER		 1
#define	  VMD_LOWER			 2
#define	  VMD_UPPER			 3
#define	  VMD_UPPER2		 4
#define	  VMD_NECK			 5
#define	  VMD_HEAD			 6
#define	  VMD_SKULL			 7

#define	  VMD_EYES			 8
#define	  VMD_L_EYE			 9
#define	  VMD_R_EYE			10
#define	  VMD_L_BUST		11
#define	  VMD_R_BUST		12
	
#define   VMD_L_SHLDR		13
#define   VMD_L_ARM			14
#define   VMD_L_ARM_TW		15
#define   VMD_L_ELBOW		16
#define   VMD_L_WRIST_TW	17
#define	  VMD_L_WRIST		18
#define	  VMD_L_HAND		19
	
#define   VMD_R_SHLDR		20
#define   VMD_R_ARM			21
#define   VMD_R_ARM_TW	    22
#define   VMD_R_ELBOW		23
#define   VMD_R_WRIST_TW	24
#define	  VMD_R_WRIST		25
#define	  VMD_R_HAND		26

#define	  VMD_L_HIP			27
#define   VMD_L_KNEE		28
#define	  VMD_L_ANKLE		29
#define	  VMD_L_TOE			30
	
#define	  VMD_R_HIP			31
#define	  VMD_R_KNEE		32
#define	  VMD_R_ANKLE		33
#define	  VMD_R_TOE			34








namespace jbxwl {

using namespace jbxl;



typedef struct _vmd_file_header
{
	char		  header[30];
	char		  name[20];
	unsigned int  data_num;
	//
} VMDFileHeader;




typedef struct _vmd_joint_data
{
	char		  name[15];
	unsigned long frm_num;
	float		  posx;
	float		  posy;
	float		  posz;
	float		  qutx;
	float		  quty;
	float		  qutz;
	float		  qutw;
	char		  param[64];
	//
} VMDJointData;




/*
// –¢‘Î‰ž
typedef struct _vmd_face_frame
{
	char		  name[15];
	unsigned long num;
	float		  value;
	//
} VMDFaceFrame;
*/






class CVMDTool : public CBaseFrameTool
{
public:
	CVMDTool(void)  { init();}
	~CVMDTool(void) { clearData();}

	//
	Quaternion		A2TPose;
	double			rate_frame;


public:
	void			init(void);
	void			clearData(void);
	BOOL			readFile(FILE* fp);

	NiFrameData *	getJointsFrame(void);
	unsigned int	getFrameNumber(void) { return dmy_frmnum;}


public:
	VMDFileHeader	vmd_header;
	VMDJointData*	vmd_motion;
	unsigned int	vmd_datnum;

	NiFrameData*	vmd_joints;
	unsigned int	vmd_frmnum;

	NiFrameData*	dmy_joints;
	unsigned int	dmy_frmnum;

	//
	virtual NiJointData* getFrameData(int frmnum);
	//
	NiJointData		frame_data[VMD_MAX_JOINT_NUM];


public:
	//
	VMDFileHeader	readFileHeader(FILE* fp);
	VMDJointData	readJointData (FILE* fp);
	VMDJointData*	readJointsData(FILE* fp, unsigned int& frmnum);

	NiFrameData*	convert2FrameData(VMDJointData* motion_data, unsigned int& frmnum);
	void			calcJointRotation(void);


public:
	// Joints
	void			clearJointsData(double val=-1.0);
	
	Vector<double>	posVect[VMD_MAX_JOINT_NUM];
	Quaternion		rotQuat[VMD_MAX_JOINT_NUM];
};








////////////////////////////////////////////////////////////////////////////////////////////////
//

std::string    VMDJointName(int n);
int			   VMDJointNum(char* name);

int			   VMD2NiJointNum(int joint);




}




#endif