00001
00002 #include "WinBaseLib.h"
00003 #include "NiFileTool.h"
00004 #include "MFCio.h"
00005 #include "MessageBoxDLG.h"
00006
00007
00008 using namespace jbxl;
00009 using namespace jbxwl;
00010
00011
00012
00013 CNiFileTool::~CNiFileTool(void)
00014 {
00015 DEBUG_INFO("DESTRUCTOR: CNiFileTool\n");
00016
00017 free_data();
00018 }
00019
00020
00021
00023
00024
00025 void CNiFileTool::free_data(void)
00026 {
00027 clear_data();
00028
00029 if (JTXT_Tool!=NULL) delete(JTXT_Tool);
00030 if (VMD_Tool!=NULL) delete(VMD_Tool);
00031 if (BVH_Tool!=NULL) delete(BVH_Tool);
00032
00033 JTXT_Tool = NULL;
00034 VMD_Tool = NULL;
00035 BVH_Tool = NULL;
00036 }
00037
00038
00039
00040 void CNiFileTool::clear_data(void)
00041 {
00042 close_wfile();
00043 close_rfile();
00044 clearFrameData();
00045
00046 clearStartPosition();
00047 clearJointsData();
00048
00049 frames_data = NULL;
00050 frame_start = 0;
00051 frames_num = 0;
00052 frame_ptr = 0;
00053
00054 frame_timer = 0;
00055 lap_timer = 0;
00056 time_scale = 1.0;
00057
00058 playback_time = 0.0;
00059 playback_fps = 30;
00060 }
00061
00062
00063
00064 void CNiFileTool::init_data(void)
00065 {
00066 m_enable_wfile = FALSE;
00067 m_wfp = NULL;
00068 m_rfp = NULL;
00069 m_lib = NiSDK_None;
00070
00071 frames_data = NULL;
00072 frame_start = 0;
00073 frames_num = 0;
00074 frame_ptr = 0;
00075
00076 frame_timer = 0;
00077 lap_timer = 0;
00078 time_scale = 1.0;
00079
00080 playback_time = 0.0;
00081 playback_fps = 30;
00082
00083 clearStartPosition();
00084 clearJointsData();
00085
00086 JTXT_Tool = NULL;
00087 VMD_Tool = NULL;
00088 BVH_Tool = NULL;
00089 }
00090
00091
00092
00093 void CNiFileTool::init(NiSDK_Lib lib)
00094 {
00095 m_lib = lib;
00096
00097
00098 JTXT_Tool = new CNiJTextTool();
00099 VMD_Tool = new CNiVMDTool();
00100 BVH_Tool = new CNiBVHTool();
00101
00102 frameTool = NULL;
00103 }
00104
00105
00106
00107 BOOL CNiFileTool::open_wfile(LPCTSTR fname, BOOL force)
00108 {
00109 if (m_enable_wfile) return TRUE;
00110 if (m_wfp!=NULL) return FALSE;
00111
00112 if (!force) {
00113 if (file_exist_t(fname)) {
00114 int ret = MessageBoxDLG(IDS_STR_WARN, IDS_STR_ASK_OVERWRITE, MB_YESNO, NULL);
00115 if (ret==IDNO) return FALSE;
00116 }
00117 }
00118
00119
00120 m_wfp = tfopen(fname, _T("wb"));
00121 if (m_wfp==NULL) return FALSE;
00122
00123 m_enable_wfile = TRUE;
00124 return TRUE;
00125 }
00126
00127
00128
00129 void CNiFileTool::write_header(FILE* fp)
00130 {
00131 if (fp==NULL) fp = m_wfp;
00132
00133 JTXT_Tool->writeHeader(fp);
00134 }
00135
00136
00137
00138 BOOL CNiFileTool::open_rfile(LPCTSTR fname)
00139 {
00140 if (m_rfp!=NULL) return FALSE;
00141
00142 m_rfp = tfopen(fname, _T("rb"));
00143 if (m_rfp==NULL) {
00144 return FALSE;
00145 }
00146
00147 return TRUE;
00148 }
00149
00150
00151
00152 void CNiFileTool::close_wfile(void)
00153 {
00154 if (m_wfp!=NULL) {
00155 fclose(m_wfp);
00156 m_wfp = NULL;
00157 m_enable_wfile = FALSE;
00158 }
00159 }
00160
00161
00162
00163 void CNiFileTool::close_rfile(void)
00164 {
00165 if (m_rfp!=NULL) {
00166 fclose(m_rfp);
00167 m_rfp = NULL;
00168 }
00169 }
00170
00171
00172
00173
00175
00176
00177 int CNiFileTool::readJTextFile(LPCTSTR fname)
00178 {
00179 if (fname==NULL) return -1;
00180 clearFrameData();
00181 if (JTXT_Tool==NULL) JTXT_Tool = new CNiJTextTool();
00182
00183 BOOL ret = open_rfile(fname);
00184 if (!ret) return -2;
00185
00186 ret = JTXT_Tool->readFile(m_rfp);
00187 close_rfile();
00188 if (!ret) return -3;
00189
00190 frames_data = JTXT_Tool->getFramesData();
00191 if (frames_data==NULL) return -4;
00192
00193 frames_num = JTXT_Tool->getFramesNumber();
00194 frameTool = JTXT_Tool;
00195
00196 playback_time = (frames_data[frames_num-1].msec - frames_data[0].msec)/1000.f;
00197 playback_fps = JTXT_Tool->getPlayBackFPS();
00198
00199 return frames_num;
00200 }
00201
00202
00203
00204 BOOL CNiFileTool::writeJTextData(FILE* fp, Vector<double>* pos, Quaternion<double>* rot, double* agl, BOOL mirror, NiSDK_Lib lib)
00205 {
00206 if (fp==NULL) return FALSE;
00207
00208 if (JTXT_Tool==NULL) JTXT_Tool = new CNiJTextTool();
00209
00210 if (lib==NiSDK_Default) lib = m_lib;
00211 JTXT_Tool->setPosVect(pos, lib, mirror);
00212 JTXT_Tool->setRotQuat(rot, lib, mirror);
00213 JTXT_Tool->setJntAngl(agl, lib, mirror);
00214 JTXT_Tool->writeCurrentData(fp, GetMsecondsTimer());
00215
00216 return TRUE;
00217 }
00218
00219
00220
00221
00222 BOOL CNiFileTool::saveJTextfromFile(LPCTSTR tempf, LPCTSTR fname, BOOL force)
00223 {
00224 if (!force) {
00225 if (file_exist_t(fname)) {
00226 int ret = MessageBoxDLG(IDS_STR_WARN, IDS_STR_ASK_OVERWRITE, MB_YESNO, NULL);
00227 if (ret==IDNO) return FALSE;
00228 }
00229 }
00230
00231 return copyFileWithCounter(tempf, fname);
00232 }
00233
00234
00235
00236
00237 BOOL CNiFileTool::writeTempJText(Vector<double>* pos, Quaternion<double>* rot, double* agl, BOOL mirror, NiSDK_Lib lib)
00238 {
00239 return writeJTextData(m_wfp, pos, rot, agl, mirror, lib);
00240 }
00241
00242
00243
00244
00246
00247
00248 int CNiFileTool::readBVHFile(LPCTSTR fname)
00249 {
00250 if (fname==NULL) return -1;
00251 clearFrameData();
00252 if (BVH_Tool==NULL) BVH_Tool = new CNiBVHTool();
00253
00254 BOOL ret = open_rfile(fname);
00255 if (!ret) return -2;
00256
00257 ret = BVH_Tool->readFile(m_rfp);
00258 close_rfile();
00259 if (!ret) return -3;
00260
00261 frames_data = BVH_Tool->getFramesData();
00262 if (frames_data==NULL) return -4;
00263
00264 frames_num = BVH_Tool->getFramesNumber();
00265 frameTool = BVH_Tool;
00266
00267 playback_time = (frames_data[frames_num-1].msec - frames_data[0].msec)/1000.f;
00268 playback_fps = BVH_Tool->getPlayBackFPS();
00269
00270 return frames_num;
00271 }
00272
00273
00274
00275
00276 BOOL CNiFileTool::saveBVHfromFile(LPCTSTR tempf, LPCTSTR fname, BVHSaveParam param)
00277 {
00278 int frn = readJTextFile(tempf);
00279 if (frn<=0) return FALSE;
00280
00281 param.scale /= 0.0254f;
00282 BOOL ret = writeBVHFile(fname, param);
00283
00284 return ret;
00285 }
00286
00287
00288
00289 BOOL CNiFileTool::writeBVHFile(LPCTSTR fname, BVHSaveParam param)
00290 {
00291 if (frameTool==NULL) return FALSE;
00292 if (frameTool->getFramesNumber()<=0) return FALSE;
00293
00294
00295
00296
00297
00298 tTree* hrchy = NULL;
00299 if (param.format==BVH_SAVE_FORMAT_QAV) {
00300 hrchy = makeBVH_QAvHierarchy();
00301 }
00302 else if (param.format==BVH_SAVE_FORMAT_SL) {
00303 hrchy = makeBVH_SLHierarchy();
00304 }
00305 else if (param.format==BVH_SAVE_FORMAT_NI) {
00306 hrchy = makeBVH_NiHierarchy();
00307 }
00308 else {
00309 return FALSE;
00310 }
00311 if (param.fps<10) param.fps = 10;
00312 else if (param.fps>60) param.fps = 60;
00313
00314 double frmitm = 1000.0/param.fps;
00315 int frmnum = (int)(frameTool->getPlayBackTime()/frmitm) + 1;
00316
00317
00318 CBVHTool* bvh_tool = new CBVHTool();
00319
00320 bvh_tool->setHierarchy(hrchy);
00321 bvh_tool->frame_num = frmnum;
00322 bvh_tool->frame_time = frmitm/1000.0;
00323 bvh_tool->state = 0;
00324
00325 if (bvh_tool->frame_time!=0.0) bvh_tool->framepsec = (int)(1.0/bvh_tool->frame_time);
00326 else bvh_tool->framepsec = 30;
00327
00328
00329 size_t len = sizeof(vector)*bvh_tool->joint_num;
00330 bvh_tool->offset = (vector*)malloc(len);
00331 if (bvh_tool->offset==NULL) {
00332 delete(bvh_tool);
00333 return FALSE;
00334 }
00335 memset(bvh_tool->offset, 0, len);
00336
00337 len = sizeof(double)*frmnum*bvh_tool->channels;
00338 bvh_tool->motion = (double*)malloc(len);
00339 if (bvh_tool->motion==NULL) {
00340 delete(bvh_tool);
00341 return FALSE;
00342 }
00343 memset(bvh_tool->motion, 0, len);
00344
00345
00346
00347
00348 double r2d = 180.0/PI;
00349 tList* namelist = setBVHJointName();
00350
00351 Vector<double> vt[NI_TOTAL_JOINT_NUM];
00352 Quaternion<double> qt[NI_TOTAL_JOINT_NUM];
00353
00354
00355 for (int f=0; f<frmnum; f++) {
00356
00357 int frm = f*bvh_tool->channels;
00358 NiJointData* jdat = frameTool->getJointsData(f, param.fps);
00359
00360 for (int j=0; j<NI_TOTAL_JOINT_NUM; j++) {
00361 vt[j].set(0.0, 0.0, 0.0, 0.0, -1.0);
00362 qt[j].set(1.0, 0.0, 0.0, 0.0, 0.0, -1.0);
00363 }
00364 for (int j=0; j<frameTool->getJointsNumber(); j++) {
00365 int n = jdat[j].joint;
00366 if (n>=0 && n<NI_TOTAL_JOINT_NUM) {
00367 vt[n] = jdat[j].vect;
00368 qt[n] = jdat[j].quat;
00369 }
00370 }
00371
00372 if (param.recalc) Vector2Quaternion(vt, qt);
00373
00374
00375 for (int j=0; j<bvh_tool->joint_num; j++) {
00376 int chnum = bvh_tool->channel_num[j];
00377 int index = bvh_tool->channel_idx[j];
00378 char* tpchr = (char*)&(bvh_tool->flex_joint.buf[index*2]);
00379
00380
00381 Vector<double> vect(0.0, 0.0, 0.0, 0.0, -1.0);
00382 Vector<double> eulr(0.0, 0.0, 0.0, 0.0, -1.0);
00383
00384 int jnum = BVHJoint2NiJointNum(namelist, bvh_tool->joint_name[j]);
00385 if (jnum>=0 && jnum<NI_TOTAL_JOINT_NUM) {
00386 vect = vt[jnum];
00387 eulr = Quaternion2ExtEulerXYZ(qt[jnum]);
00388 }
00389
00390
00391 for (int k=0; k<chnum; k++) {
00392 int midx = frm + index;
00393 if (tpchr[k*2]=='P') {
00394 if (tpchr[k*2+1]=='X') bvh_tool->motion[midx+k] = vect.y*param.scale;
00395 else if (tpchr[k*2+1]=='Y') bvh_tool->motion[midx+k] = vect.z*param.scale;
00396 else if (tpchr[k*2+1]=='Z') bvh_tool->motion[midx+k] = vect.x*param.scale;
00397 }
00398 else if (tpchr[k*2]=='R') {
00399 if (tpchr[k*2+1]=='X') bvh_tool->motion[midx+k] = eulr.y*r2d;
00400 else if (tpchr[k*2+1]=='Y') bvh_tool->motion[midx+k] = eulr.z*r2d;
00401 else if (tpchr[k*2+1]=='Z') bvh_tool->motion[midx+k] = eulr.x*r2d;
00402 }
00403 }
00404 }
00405 }
00406
00407
00408
00409
00410 for (int j=0; j<bvh_tool->joint_num; j++) {
00411 bvh_tool->offset[j].x = 0.0;
00412 bvh_tool->offset[j].y = 0.0;
00413 bvh_tool->offset[j].z = 0.0;
00414 }
00415
00416
00417 if (param.format==BVH_SAVE_FORMAT_QAV) {
00418 for (int j=0; j<bvh_tool->joint_num; j++) {
00419 bvh_tool->offset[j] = getQAvBVHOffset(j);
00420 }
00421 }
00422
00423
00424 else {
00425 NiJointData* jdat = frameTool->getJointsData(0, param.fps);
00426
00427 for (int j=0; j<NI_TOTAL_JOINT_NUM; j++) {
00428 vt[j].set(0.0, 0.0, 0.0, 0.0, -1.0);
00429 qt[j].set(1.0, 0.0, 0.0, 0.0, 0.0, -1.0);
00430 }
00431 for (int j=0; j<frameTool->getJointsNumber(); j++) {
00432 int n = jdat[j].joint;
00433 if (n>=0 && n<NI_TOTAL_JOINT_NUM) {
00434 vt[n] = jdat[j].vect;
00435 qt[n] = jdat[j].quat;
00436 }
00437 }
00438
00439
00440 for (int j=0; j<bvh_tool->joint_num; j++) {
00441 int jnum = BVHJoint2NiJointNum(namelist, bvh_tool->joint_name[j]);
00442 if (jnum>=0 && jnum<NI_TOTAL_JOINT_NUM) {
00443 bvh_tool->offset[j].x = vt[jnum].y*param.scale;
00444 bvh_tool->offset[j].y = vt[jnum].z*param.scale;
00445 bvh_tool->offset[j].z = vt[jnum].x*param.scale;
00446 }
00447 }
00448 }
00449
00450
00451
00452
00453 BOOL ret = FALSE;
00454
00455 if (param.divtm>0) {
00456 char* fn = ::ts2mbs(fname);
00457 ret = bvh_tool->writeMultiFile(fn, param.divtm, Max(param.divtm, 10));
00458 ::free(fn);
00459 }
00460 else {
00461
00462 ret = open_wfile(fname, FALSE);
00463 if (ret) {
00464 ret = bvh_tool->printBVH(m_wfp);
00465 close_wfile();
00466 }
00467 else {
00468 DEBUG_ERROR("CNiFileTool::writeBVHFile(): ERROR: Already other file for write is opened!\n");
00469 }
00470 }
00471
00472 del_tList(&namelist);
00473 delete(bvh_tool);
00474
00475 return ret;
00476 }
00477
00478
00479
00480
00482
00483
00484 int CNiFileTool::readVMDFile(LPCTSTR fname)
00485 {
00486 if (fname==NULL) return -1;
00487 clearFrameData();
00488 if (VMD_Tool==NULL) VMD_Tool = new CNiVMDTool();
00489
00490 BOOL ret = open_rfile(fname);
00491 if (!ret) return -2;
00492
00493 ret = VMD_Tool->readFile(m_rfp);
00494 close_rfile();
00495 if (!ret) return -3;
00496
00497
00498 frames_data = VMD_Tool->getFramesData();
00499 if (frames_data==NULL) return -4;
00500
00501 frames_num = VMD_Tool->getFramesNumber();
00502 frameTool = VMD_Tool;
00503
00504 playback_time = (frames_data[frames_num-1].msec - frames_data[0].msec)/1000.f;
00505 playback_fps = VMD_Tool->getPlayBackFPS();
00506
00507 return frames_num;
00508 }
00509
00510
00511
00512
00513 BOOL CNiFileTool::saveVMDfromFile(LPCTSTR tempf, LPCTSTR fname)
00514 {
00515
00516 return FALSE;
00517 }
00518
00519
00520
00521
00523
00524
00525 void CNiFileTool::setFrame(int frame)
00526 {
00527 frame_start = 0;
00528 if (frames_num!=0) {
00529 frame_start = frame%frames_num;
00530 }
00531
00532 frame_ptr = frame_start;
00533 }
00534
00535
00536
00537
00538
00539
00540 BOOL CNiFileTool::startFrame(int start)
00541 {
00542 if (frames_num==0 || start<0 || start>=frames_num) return FALSE;
00543
00544 lap_timer = GetMsecondsTimer();
00545 frame_timer = (int)(frames_data[start].msec*time_scale);
00546 setFrame(start);
00547
00548 return TRUE;
00549 }
00550
00551
00552
00553
00554
00555
00556 BOOL CNiFileTool::nextFrame(BOOL next)
00557 {
00558 if (next) {
00559 frame_ptr++;
00560 if (frame_ptr>frames_num) {
00561
00562 DEBUG_INFO("CNiFileTool::nextFrame(): frame ptr = %d, frame num = %d\n", frame_ptr, frames_num);
00563 return FALSE;
00564 }
00565 }
00566
00567
00568 int msec = 0;
00569 if (frame_ptr==frames_num) {
00570 if (frames_num!=1) {
00571 msec = (int)((2*frames_data[frame_ptr-1].msec - frames_data[frame_ptr-2].msec)*time_scale);
00572 }
00573 }
00574 else {
00575 msec = (int)(frames_data[frame_ptr].msec*time_scale);
00576 }
00577
00578
00579 unsigned short ctime;
00580 frame_timer += GetMsecondsLapTimer(lap_timer, &ctime);
00581 lap_timer = ctime;
00582
00583 if (frame_timer>=msec) {
00584 return TRUE;
00585 }
00586 else if (msec>frame_timer+5000) {
00587 DEBUG_INFO("CNiFileTool::nextFrame(): next frame = %d, current frame = %d\n", msec, frame_timer);
00588 return FALSE;
00589 }
00590
00591
00592 do {
00593 ::DisPatcher();
00594 int slptm = Min(msec-frame_timer, 100);
00595 if (slptm>0) ::Sleep(slptm);
00596 frame_timer += GetMsecondsLapTimer(lap_timer, &ctime);
00597 lap_timer = ctime;
00598 } while (msec>frame_timer);
00599
00600 return TRUE;
00601 }
00602
00603
00604
00605
00607
00608
00609 void CNiFileTool::clearFrameData(void)
00610 {
00611
00612 frames_data = NULL;
00613 frames_num = 0;
00614 frame_ptr = 0;
00615
00616 if (JTXT_Tool!=NULL) JTXT_Tool->clear_data();
00617 if (BVH_Tool!=NULL) BVH_Tool->clear_data();
00618 if (VMD_Tool!=NULL) VMD_Tool->clear_data();
00619
00620 frameTool = NULL;
00621
00622 return;
00623 }
00624
00625
00626
00627
00629
00630
00631 void CNiFileTool::clearJointsData(void)
00632 {
00633 for (int i=0; i<NI_TOTAL_JOINT_NUM; i++) {
00634 rotQuat[i].init(-1.0);
00635 posVect[i].init(-1.0);
00636 }
00637 currentPos.init(-1.0);
00638 }
00639
00640
00641
00642 void CNiFileTool::getJointsDataSeq(BOOL mirror, int frame)
00643 {
00644 if (frame>=0) setFrame(frame);
00645
00646
00647 NiJointData* joint_data = frames_data[frame_ptr].jdat;
00648 int joint_num = frames_data[frame_ptr].jnum;
00649
00650
00651 if (joint_data==NULL) {
00652 if (frameTool!=NULL) {
00653 joint_data = frameTool->getJointsData(frame_ptr, playback_fps);
00654 }
00655 }
00656 if (joint_data==NULL) return;
00657
00658
00659 for (int j=0; j<joint_num; j++) {
00660
00661 int n = joint_data[j].joint;
00662 if (n>=0 && n<NI_TOTAL_JOINT_NUM) {
00663 if (mirror) n = NiMirrorJointNum(n);
00664
00665 posVect[n] = joint_data[j].vect;
00666 rotQuat[n] = joint_data[j].quat;
00667
00668 if (mirror) {
00669 posVect[n].y = - posVect[n].y;
00670 rotQuat[n].x = - rotQuat[n].x;
00671 rotQuat[n].z = - rotQuat[n].z;
00672 }
00673 }
00674 }
00675 return;
00676 }
00677