00001
00002
00010 #include "xtools.h"
00011 #include "bvh_tool.h"
00012
00013
00014
00016
00017
00018
00019 BVHData* new_BVHData(void)
00020 {
00021 BVHData* bvh = NULL;
00022
00023 bvh = (BVHData*)malloc(sizeof(BVHData));
00024 if (bvh==NULL) return NULL;
00025
00026 init_BVHData(bvh);
00027
00028 return bvh;
00029 }
00030
00031
00032 void del_BVHData(BVHData** bvh)
00033 {
00034 if (bvh==NULL || *bvh==NULL) return;
00035
00036 clear_BVHData(*bvh);
00037 free(*bvh);
00038
00039 *bvh = NULL;
00040 return;
00041 }
00042
00043
00044 void init_BVHData(BVHData* bvh)
00045 {
00046 if (bvh==NULL) return;
00047
00048 memset(bvh, 0, sizeof(BVHData));
00049 bvh->state = JBXL_NORMAL;
00050
00051 return;
00052 }
00053
00054
00055 void clear_BVHData(BVHData* bvh)
00056 {
00057 if (bvh==NULL) return;
00058
00059 if (bvh->hierarchy!=NULL) {
00060 del_tTree(&bvh->hierarchy);
00061 bvh->hierarchy = NULL;
00062 }
00063 if (bvh->motion!=NULL) {
00064 free(bvh->motion);
00065 bvh->motion = NULL;
00066 }
00067 if (bvh->offset!=NULL) {
00068 free(bvh->offset);
00069 bvh->offset = NULL;
00070 }
00071
00072 init_BVHData(bvh);
00073
00074 return;
00075 }
00076
00077
00078
00080
00081
00082
00091 tList* bvh_get_seq_data(FILE* fp)
00092 {
00093 char* pp;
00094 UNUSED(pp);
00095
00096 if (fp==NULL) return NULL;
00097
00098 char line[LBUF+1];
00099 line[LBUF] = '\0';
00100
00101 pp = fgets(line, LBUF, fp);
00102 char* pack = pack_char(line, ' ');
00103 if (pack==NULL) return NULL;
00104
00105 replace_str(pack, LBUF, " :", ":");
00106
00107
00108
00109 tList* list = awk_tList(pack, ' ');
00110 free(pack);
00111
00112 return list;
00113 }
00114
00115
00125 tList* bvh_find_line(FILE* fp, const char* key)
00126 {
00127 if (fp==NULL || key==NULL) return NULL;
00128
00129 tList* list = bvh_get_seq_data(fp);
00130
00131 while (!feof(fp)) {
00132 if (!strcasecmp((char*)list->ldat.key.buf, key)) return list;
00133
00134 del_tList(&list);
00135 list = bvh_get_seq_data(fp);
00136 }
00137
00138 return NULL;
00139 }
00140
00141
00142 int bvh_count_channels(tTree* pp)
00143 {
00144 int cnt = 0;
00145
00146 if (pp==NULL) return 0;
00147 while(pp->esis!=NULL) pp = pp->esis;
00148
00149 do {
00150 cnt += pp->ldat.lv;
00151 if (pp->next!=NULL) cnt += bvh_count_channels(pp->next);
00152 pp = pp->ysis;
00153 } while(pp!=NULL);
00154
00155 return cnt;
00156 }
00157
00158
00159 int bvh_count_joints(tTree* pp)
00160 {
00161 int cnt = 0;
00162
00163 if (pp==NULL) return 0;
00164 while(pp->esis!=NULL) pp = pp->esis;
00165
00166 do {
00167 cnt++;
00168 if (pp->next!=NULL) cnt += bvh_count_joints(pp->next);
00169 pp = pp->ysis;
00170 } while(pp!=NULL);
00171
00172 return cnt;
00173 }
00174
00175
00184 void bvh_get_offset(tTree* pp, vector** vect)
00185 {
00186 if (pp==NULL) return;
00187
00188 while(pp->esis!=NULL) pp = pp->esis;
00189
00190 do {
00191 if (*vect!=NULL) {
00192 **vect = *(vector*)pp->ldat.ptr;
00193 (*vect)++;
00194 }
00195
00196 if (pp->next!=NULL) bvh_get_offset(pp->next, vect);
00197 pp = pp->ysis;
00198 } while(pp!=NULL);
00199
00200 return;
00201 }
00202
00203
00209 void bvh_get_parameter(BVHData* bvh)
00210 {
00211 if (bvh==NULL || bvh->hierarchy==NULL) return;
00212
00213 bvh->joint_num = 0;
00214 bvh->channels = 0;
00215
00216 _bvh_recsv_get_parameter(bvh->hierarchy, bvh);
00217 }
00218
00219
00220 void _bvh_recsv_get_parameter(tTree* pp, BVHData* bvh)
00221 {
00222 if (pp==NULL) return;
00223
00224 while(pp->esis!=NULL) pp = pp->esis;
00225
00226 do {
00227 bvh->channels += pp->ldat.lv;
00228 bvh->joint_num++;
00229
00230 if (pp->next!=NULL) _bvh_recsv_get_parameter(pp->next, bvh);
00231 pp = pp->ysis;
00232 } while(pp!=NULL);
00233
00234 return;
00235 }
00236
00237
00238 void _bvh_space_format(FILE* fp, int depth)
00239 {
00240 int i;
00241
00242 for (i=0; i<depth;i++) fprintf(fp, " ");
00243 }
00244
00245
00246
00248
00249
00250
00255 BVHData* bvh_read_file(const char* fn)
00256 {
00257 BVHData* bvh = NULL;
00258
00259 FILE* fp = fopen(fn, "r");
00260 if (fp==NULL) return NULL;
00261
00262 bvh = bvh_parse_data(fp);
00263 fclose(fp);
00264
00265 return bvh;
00266 }
00267
00268
00278 int bvh_write_file(const char* fn, BVHData* bvh)
00279 {
00280 if (fn==NULL || bvh==NULL) return JBXL_ARGS_ERROR;
00281 if (bvh->hierarchy==NULL || bvh->motion==NULL || bvh->state<0) return JBXL_ARGS_ERROR;
00282
00283 FILE* fp = fopen(fn, "w");
00284 if (fp==NULL) return JBXL_FILE_OPEN_ERROR;
00285
00286 int ret = bvh_print_data(fp, bvh);
00287 fclose(fp);
00288
00289 return ret;
00290 }
00291
00292
00293 int bvh_print_data(FILE* fp, BVHData* bvh)
00294 {
00295 if (bvh==NULL || bvh->hierarchy==NULL || bvh->motion==NULL) return JBXL_ARGS_ERROR;
00296 if (fp==NULL) return JBXL_FILE_OPEN_ERROR;
00297
00298 int ret = JBXL_BVH_HIERARCHY_ERROR;
00299
00300 int hrt = bvh_print_hierarchy(fp, bvh);
00301 if (hrt>=0) {
00302 ret = JBXL_BVH_MOTION_ERROR;
00303 int mrt = bvh_print_motion(fp, bvh);
00304 if (mrt>=0) ret = 0;
00305 }
00306
00307 return ret;
00308 }
00309
00310
00311 int bvh_print_hierarchy(FILE* fp, BVHData* bvh)
00312 {
00313 if (fp==NULL || bvh==NULL || bvh->hierarchy==NULL) return JBXL_ARGS_ERROR;
00314
00315 fprintf(fp, "%s\n", BVH_STR_HIERARCHY);
00316
00317 int ret = _bvh_recsv_print_hierarchy(fp, bvh->hierarchy);
00318 fflush(fp);
00319
00320 return ret;
00321 }
00322
00323
00324 int _bvh_recsv_print_hierarchy(FILE* fp, tTree* tree)
00325 {
00326 if (tree!=NULL) {
00327 while(tree->esis!=NULL) tree = tree->esis;
00328 do {
00329 int i;
00330 tList_data ld = tree->ldat;
00331
00333 if (ld.id==BVH_NODE_ROOT || ld.id==BVH_NODE_JOINT || ld.id==BVH_NODE_END) {
00334 _bvh_space_format(fp, tree->depth-1);
00335
00336 if (ld.id==BVH_NODE_ROOT) fprintf(fp, "%s", BVH_STR_ROOT);
00337 else if (ld.id==BVH_NODE_JOINT) fprintf(fp, "%s", BVH_STR_JOINT);
00338 else fprintf(fp, "%s", BVH_STR_END);
00339
00340
00341 if (ld.key.buf!=NULL) fprintf(fp, " %s", ld.key.buf);
00342 fprintf(fp, "\n");
00343 _bvh_space_format(fp, tree->depth-1);
00344 fprintf(fp, "{\n");
00345
00346
00347 _bvh_space_format(fp, tree->depth);
00348 fprintf(fp, "%s", BVH_STR_OFFSET);
00349 vector* vect = (vector*)ld.ptr;
00350 if (vect!=NULL) {
00351 fprintf(fp, " %f %f %f\n", vect->x, vect->y, vect->z);
00352 }
00353 else {
00354 fprintf(fp, " %f %f %f\n", 0.0, 0.0, 0.0);
00355 }
00356
00357
00358 if (ld.lv>0 && ld.val.buf!=NULL) {
00359 _bvh_space_format(fp, tree->depth);
00360 fprintf(fp, "%s %d", BVH_STR_CHANNELS, ld.lv);
00361 for (i=0; i<ld.lv*2; i+=2) {
00362 if (ld.val.buf[i]=='P') {
00363 if (ld.val.buf[i+1]=='X') fprintf(fp, " %s", BVH_STR_PX);
00364 else if (ld.val.buf[i+1]=='Y') fprintf(fp, " %s", BVH_STR_PY);
00365 else if (ld.val.buf[i+1]=='Z') fprintf(fp, " %s", BVH_STR_PZ);
00366 }
00367 else if (ld.val.buf[i]=='R') {
00368 if (ld.val.buf[i+1]=='X') fprintf(fp, " %s", BVH_STR_RX);
00369 else if (ld.val.buf[i+1]=='Y') fprintf(fp, " %s", BVH_STR_RY);
00370 else if (ld.val.buf[i+1]=='Z') fprintf(fp, " %s", BVH_STR_RZ);
00371 }
00372 }
00373 fprintf(fp, "\n");
00374 }
00375 }
00376
00377
00378 if (tree->next!=NULL) {
00379 _bvh_recsv_print_hierarchy(fp, tree->next);
00380 }
00381
00382 _bvh_space_format(fp, tree->depth-1);
00383 fprintf(fp, "}\n");
00384
00385 tree = tree->ysis;
00386 } while(tree!=NULL);
00387 }
00388
00389 return 0;
00390 }
00391
00392
00393 int bvh_print_motion(FILE* fp, BVHData* bvh)
00394 {
00395 if (fp==NULL || bvh==NULL || bvh->motion==NULL) return JBXL_ARGS_ERROR;
00396
00397 fprintf(fp, "%s\n", BVH_STR_MOTION);
00398 fprintf(fp, "%s %d\n", BVH_STR_FRAMES, bvh->frame_num);
00399 fprintf(fp, "%s %f\n", BVH_STR_FRAME_TIME, bvh->frame_time);
00400
00401 int i, j;
00402
00403 for (j=0; j<bvh->frame_num; j++) {
00404 int jpos = j*bvh->channels;
00405 for (i=0; i<bvh->channels; i++) {
00406 fprintf(fp, "%f ", bvh->motion[jpos+i]);
00407 }
00408 fprintf(fp, "\n");
00409 }
00410
00411 fflush(fp);
00412
00413 return 0;
00414 }
00415
00416
00417
00419
00420
00421
00422 BVHData* bvh_parse_data(FILE* fp)
00423 {
00424 BVHData* bvh = NULL;
00425 tList* list = NULL;
00426
00427 if (fp==NULL) return NULL;
00428
00429
00430 list = bvh_find_line(fp, BVH_STR_HIERARCHY);
00431 if (list==NULL) return bvh;
00432 del_tList(&list);
00433
00434
00435 bvh = new_BVHData();
00436 if (bvh==NULL) return NULL;
00437 bvh->state = JBXL_ERROR;
00438
00439 bvh->hierarchy = bvh_parse_hierarchy(NULL, fp);
00440 if (bvh->hierarchy==NULL) {
00441 del_BVHData(&bvh);
00442 return NULL;
00443 }
00444
00445
00446
00447 bvh_get_parameter(bvh);
00448
00449
00450 bvh->offset = (vector*)malloc(sizeof(vector)*bvh->joint_num);
00451 if (bvh->offset!=NULL) {
00452 memset(bvh->offset, 0, sizeof(vector)*bvh->joint_num);
00453 vector* vect = bvh->offset;
00454 bvh_get_offset(bvh->hierarchy, &vect);
00455 }
00456
00457
00458 list = bvh_find_line(fp, BVH_STR_MOTION);
00459 if (list==NULL) return bvh;
00460 del_tList(&list);
00461
00462 list = bvh_find_line(fp, BVH_STR_FRAMES);
00463 if (list==NULL || list->next==NULL) return bvh;
00464 bvh->frame_num = atoi((char*)list->next->ldat.key.buf);
00465 del_tList(&list);
00466
00467 list = bvh_find_line(fp, BVH_STR_FRAME);
00468 if (list==NULL || list->next==NULL || list->next->next==NULL) return bvh;
00469 if (strcasecmp(BVH_STR_TIME, (char*)list->next->ldat.key.buf)) return bvh;
00470 bvh->frame_time = atof((char*)list->next->next->ldat.key.buf);
00471 if (bvh->frame_time!=0.0) bvh->framepsec = (int)(1./bvh->frame_time);
00472 else bvh->framepsec = 30;
00473 del_tList(&list);
00474
00475
00476 bvh_parse_motion(bvh, fp);
00477 if (bvh->frame_num>0) bvh->state = JBXL_NORMAL;
00478
00479 return bvh;
00480 }
00481
00482
00483
00484 void bvh_parse_motion(BVHData* bvh, FILE* fp)
00485 {
00486 if (bvh==NULL || fp==NULL) return;
00487 if (bvh->channels<=0 || bvh->frame_num<=0) return;
00488
00489 unsigned long int len = bvh->channels*bvh->frame_num*sizeof(double);
00490 bvh->motion = (double*)malloc(len);
00491 if (bvh->motion==NULL) return;
00492 memset(bvh->motion, 0, len);
00493
00494
00495 tList* list = bvh_get_seq_data(fp);
00496
00497 int j = 0;
00498 while (!feof(fp) && list!=NULL) {
00499 if (list->ldat.key.buf==NULL) {
00500 del_tList(&list);
00501 break;
00502 }
00503
00504 int jptr = j*bvh->channels;
00505 tList* lt = list;
00506
00507 int i = 0;
00508 while (i<bvh->channels && lt!=NULL) {
00509 bvh->motion[jptr+i] = atof((char*)lt->ldat.key.buf);
00510 lt = lt->next;
00511 i++;
00512 }
00513 j++;
00514
00515 del_tList(&list);
00516 list = bvh_get_seq_data(fp);
00517 }
00518
00519 bvh->frame_num = j;
00520
00521 return;
00522 }
00523
00524
00525
00526 tTree* bvh_parse_hierarchy(tTree* tree, FILE* fp)
00527 {
00528 int endf = FALSE;
00529 tTree* next = NULL;
00530
00531 tList* list = bvh_get_seq_data(fp);
00532
00533 while (list!=NULL) {
00534
00535 char* cmp = (char*)list->ldat.key.buf;
00536 if (cmp!=NULL) {
00537
00538
00539 if (!strcasecmp(cmp, BVH_STR_ROOT)) {
00540 endf = TRUE;
00541 if (list->next==NULL) {
00542 next = add_tTree_node_bystr(tree, BVH_NODE_ROOT, 0, "", NULL, NULL, 0);
00543 if (tree==NULL) tree = next;
00544 }
00545 else {
00546 next = add_tTree_node_bystr(tree, BVH_NODE_ROOT, 0, (char*)list->next->ldat.key.buf, NULL, NULL, 0);
00547 if (tree==NULL) tree = next;
00548 }
00549 }
00550
00551
00552
00553 else if (!strcasecmp(cmp, BVH_STR_JOINT)) {
00554 if (list->next==NULL) {
00555 next = add_tTree_node_bystr(tree, BVH_NODE_JOINT, 0, "", NULL, NULL, 0);
00556 if (tree==NULL) tree = next;
00557 }
00558 else {
00559 next = add_tTree_node_bystr(tree, BVH_NODE_JOINT, 0, (char*)list->next->ldat.key.buf, NULL, NULL, 0);
00560 if (tree==NULL) tree = next;
00561 }
00562 }
00563
00564
00565
00566 else if (!strcasecmp(cmp, BVH_STR_END)) {
00567 if (list->next==NULL) {
00568 next = add_tTree_node_bystr(tree, BVH_NODE_END, 0, "", NULL, NULL, 0);
00569 }
00570 else {
00571 next = add_tTree_node_bystr(tree, BVH_NODE_END, 0, (char*)list->next->ldat.key.buf, NULL, NULL, 0);
00572 }
00573 }
00574
00575
00576
00577 else if (!strcasecmp(cmp, BVH_STR_OFFSET)) {
00578
00579 tList* lt = list;
00580
00581 vector* vect = (vector*)malloc(sizeof(vector));
00582 memset(vect, 0, sizeof(vector));
00583
00584
00585 if (lt->next!=NULL) {
00586 lt = lt->next;
00587 vect->x = atof((char*)lt->ldat.key.buf);
00588 }
00589 if (lt->next!=NULL) {
00590 lt = lt->next;
00591 vect->y = atof((char*)lt->ldat.key.buf);
00592 }
00593 if (lt->next!=NULL) {
00594 lt = lt->next;
00595 vect->z = atof((char*)lt->ldat.key.buf);
00596 }
00597
00598 if (tree!=NULL) {
00599 tree->ldat.ptr = (void*)vect;
00600 tree->ldat.sz = sizeof(vector);
00601 }
00602 }
00603
00604
00605
00606 else if (!strcasecmp(cmp, BVH_STR_CHANNELS)) {
00607
00608 int i, num = 0;
00609 tList* lt = list;
00610
00611 if (lt->next!=NULL) {
00612 lt = lt->next;
00613 num = atoi((char*)lt->ldat.key.buf);
00614 }
00615 if (tree!=NULL) tree->ldat.lv = num;
00616
00617
00618 if (num>0) {
00619 Buffer channel = make_Buffer(13);
00620
00621 for (i=0; i<num; i++) {
00622 if (lt->next!=NULL) {
00623 lt = lt->next;
00624 if (!strcasecmp((char*)lt->ldat.key.buf, BVH_STR_PX)) {
00625 cat_s2Buffer("PX", &channel);
00626 }
00627 else if (!strcasecmp((char*)lt->ldat.key.buf, BVH_STR_PY)) {
00628 cat_s2Buffer("PY", &channel);
00629 }
00630 else if (!strcasecmp((char*)lt->ldat.key.buf, BVH_STR_PZ)) {
00631 cat_s2Buffer("PZ", &channel);
00632 }
00633 else if (!strcasecmp((char*)lt->ldat.key.buf, BVH_STR_RX)) {
00634 cat_s2Buffer("RX", &channel);
00635 }
00636 else if (!strcasecmp((char*)lt->ldat.key.buf, BVH_STR_RY)) {
00637 cat_s2Buffer("RY", &channel);
00638 }
00639 else if (!strcasecmp((char*)lt->ldat.key.buf, BVH_STR_RZ)) {
00640 cat_s2Buffer("RZ", &channel);
00641 }
00642 }
00643 }
00644
00645 if (tree!=NULL) tree->ldat.val = channel;
00646 }
00647 }
00648
00649
00650 else if (!strcmp(cmp, "{")) {
00651 if (next!=NULL) {
00652 bvh_parse_hierarchy(next, fp);
00653 if (endf) {
00654 del_tList(&list);
00655 return tree;
00656 }
00657 }
00658 }
00659
00660
00661 else if (!strcmp(cmp, "}")) {
00662 del_tList(&list);
00663 return tree;
00664 }
00665 }
00666
00667 del_tList(&list);
00668 list = bvh_get_seq_data(fp);
00669 }
00670
00671 return tree;
00672 }
00673