#include <NiVMDTool.h>
Public Member Functions | |
CNiVMDTool (void) | |
virtual | ~CNiVMDTool (void) |
void | free_data (void) |
void | clear_data (void) |
virtual unsigned int | getFramesNumber (void) |
virtual NiFrameData * | getFramesData (void) |
virtual NiJointData * | getJointsData (int frmnum, int fps) |
virtual BOOL | readFile (FILE *fp) |
Private Member Functions | |
VMDFileHeader | readFileHeader (FILE *fp) |
VMDJointData | readJointData (FILE *fp) |
VMDJointData * | readJointsData (FILE *fp, unsigned int &frmnum) |
NiFrameData * | convert2FrameData (VMDJointData *motion_data, unsigned int datnum, unsigned int &frmnum) |
void | calcJointRotation (void) |
void | calcJointIK (int fnum) |
void | calcLegIK_CCD (Vector< double > *vect, Vector< double > ik, Quaternion< double > *quat, int rpmax) |
Private Attributes | |
Quaternion< double > | A2TPose |
double | rate_frame |
VMDFileHeader | vmd_header |
VMDJointData * | vmd_frames |
unsigned int | vmd_datnum |
NiFrameData * | dmy_frames |
unsigned int | dmy_frmnum |
Definition at line 110 of file NiVMDTool.h.
CNiVMDTool | ( | void | ) |
Definition at line 154 of file NiVMDTool.cpp.
References CNiVMDTool::A2TPose, CNiVMDTool::dmy_frames, CNiVMDTool::dmy_frmnum, CBaseFrameTool::joints_num, CBaseFrameTool::posVect, CNiVMDTool::rate_frame, CBaseFrameTool::rotQuat, CNiVMDTool::vmd_datnum, VMD_FARME_RATE, CNiVMDTool::vmd_frames, CNiVMDTool::vmd_header, and VMD_JOINT_NUM.
00155 { 00156 memset(&vmd_header, 0, sizeof(VMDFileHeader)); 00157 00158 vmd_frames = NULL; 00159 vmd_datnum = 0; 00160 dmy_frames = NULL; 00161 dmy_frmnum = 0; 00162 joints_num = VMD_JOINT_NUM; 00163 00164 rate_frame = VMD_FARME_RATE/30.0; 00165 A2TPose.setRotation(37.0/180.0*PI, 1.0, 0.0, 0.0, 1.0); 00166 00167 posVect = (Vector<double>*)malloc(sizeof(Vector<double>)*VMD_JOINT_NUM); 00168 rotQuat = (Quaternion<double>*)malloc(sizeof(Quaternion<double>)*VMD_JOINT_NUM); 00169 }
~CNiVMDTool | ( | void | ) | [virtual] |
Definition at line 173 of file NiVMDTool.cpp.
References CNiVMDTool::free_data().
00174 { 00175 DEBUG_INFO("DESTRUCTOR: CNiVMDTool\n"); 00176 00177 free_data(); 00178 }
void calcJointIK | ( | int | fnum | ) | [private] |
Definition at line 562 of file NiVMDTool.cpp.
References CNiVMDTool::calcLegIK_CCD(), CBaseFrameTool::framesData, NiJointData::index, NiFrameData::jdat, NiJointData::joint, CBaseFrameTool::posVect, CBaseFrameTool::rotQuat, VMD_CENTER, VMD_L_ANKLE_IK, VMD_L_HIP, VMD_L_KNEE, VMD_R_ANKLE_IK, VMD_R_HIP, and VMD_R_KNEE.
Referenced by CNiVMDTool::calcJointRotation().
00563 { 00564 // 軸 00565 Vector<double> vect_Y(0.0, 1.0, 0.0, 1.0); 00566 Vector<double> vect_Z(0.0, 0.0,-1.0, 1.0); 00567 Vector<double> cnt_vect_Y = VectorRotation(vect_Y, rotQuat[VMD_CENTER]); 00568 Vector<double> cnt_vect_Z = VectorRotation(vect_Z, rotQuat[VMD_CENTER]); 00569 00570 // 足の方向 00571 Vector<double> l_leg_vect = VectorRotation(cnt_vect_Z, rotQuat[VMD_L_HIP]); 00572 Vector<double> r_leg_vect = VectorRotation(cnt_vect_Z, rotQuat[VMD_R_HIP]); 00573 00574 // エフェクタ: センターからの初期相対位置 00575 Vector<double> l_ank_vect = vect_Y*0.10 + vect_Z*0.83; 00576 Vector<double> r_ank_vect = -vect_Y*0.10 + vect_Z*0.83; 00577 00578 // エフェクタ: 移動後のセンターからの相対位置 00579 Vector<double> l_end_vect = cnt_vect_Y*0.10 + l_leg_vect*0.83; 00580 Vector<double> r_end_vect = -cnt_vect_Y*0.10 + r_leg_vect*0.83; 00581 00582 // 到達目標 00583 Vector<double> l_ik_vect = l_ank_vect + posVect[VMD_L_ANKLE_IK] - posVect[VMD_CENTER] - l_end_vect; 00584 Vector<double> r_ik_vect = r_ank_vect + posVect[VMD_R_ANKLE_IK] - posVect[VMD_CENTER] - r_end_vect; 00585 00586 // 到達目標(ローカル座標系) 00587 l_ik_vect = VectorRotation(l_ik_vect, ~rotQuat[VMD_CENTER]); 00588 r_ik_vect = VectorRotation(r_ik_vect, ~rotQuat[VMD_CENTER]); 00589 00590 // 00591 Vector<double> l_vect[3], r_vect[3]; 00592 Quaternion<double> l_quat[3], r_quat[3]; 00593 00594 // 膝,腰の相対位置 00595 l_vect[0].set(0.0, 0.0, 0.0); 00596 r_vect[0].set(0.0, 0.0, 0.0); 00597 00598 l_vect[1] = -l_leg_vect*0.58; 00599 r_vect[1] = -r_leg_vect*0.58; 00600 l_vect[2] = -l_leg_vect*1.18; 00601 r_vect[2] = -r_leg_vect*1.18; 00602 00603 // ローカル座標系 00604 l_vect[1] = VectorRotation(l_vect[1], ~rotQuat[VMD_CENTER]); 00605 r_vect[1] = VectorRotation(r_vect[1], ~rotQuat[VMD_CENTER]); 00606 l_vect[2] = VectorRotation(l_vect[2], ~rotQuat[VMD_CENTER]); 00607 r_vect[2] = VectorRotation(r_vect[2], ~rotQuat[VMD_CENTER]); 00608 00610 calcLegIK_CCD(l_vect, l_ik_vect, l_quat, 50); 00611 calcLegIK_CCD(r_vect, r_ik_vect, r_quat, 50); 00613 00614 // HIP 00615 if (rotQuat[VMD_L_HIP].c>0.0) rotQuat[VMD_L_HIP] = l_quat[2]*rotQuat[VMD_L_HIP]; 00616 else rotQuat[VMD_L_HIP] = l_quat[2]; 00617 if (rotQuat[VMD_R_HIP].c>0.0) rotQuat[VMD_R_HIP] = r_quat[2]*rotQuat[VMD_R_HIP]; 00618 else rotQuat[VMD_R_HIP] = r_quat[2]; 00619 00620 framesData[fnum].jdat[VMD_L_HIP].joint = VMD_L_HIP; 00621 framesData[fnum].jdat[VMD_R_HIP].joint = VMD_R_HIP; 00622 framesData[fnum].jdat[VMD_L_HIP].index = fnum; 00623 framesData[fnum].jdat[VMD_R_HIP].index = fnum; 00624 00625 // KNEE 00626 rotQuat[VMD_L_KNEE] = l_quat[1]; 00627 rotQuat[VMD_R_KNEE] = r_quat[1]; 00628 // 00629 double dot = vect_Y*rotQuat[VMD_L_KNEE].getVector(); 00630 if (dot>=0.0) { 00631 framesData[fnum].jdat[VMD_L_KNEE].joint = VMD_L_KNEE; 00632 framesData[fnum].jdat[VMD_L_KNEE].index = fnum; 00633 } 00634 else { 00635 framesData[fnum].jdat[VMD_L_KNEE].joint = -1; 00636 framesData[fnum].jdat[VMD_L_KNEE].index = -1; 00637 } 00638 00639 dot = vect_Y*rotQuat[VMD_R_KNEE].getVector(); 00640 if (dot>=0.0) { 00641 framesData[fnum].jdat[VMD_R_KNEE].joint = VMD_R_KNEE; 00642 framesData[fnum].jdat[VMD_R_KNEE].index = fnum; 00643 } 00644 else { 00645 framesData[fnum].jdat[VMD_R_KNEE].joint = -1; 00646 framesData[fnum].jdat[VMD_R_KNEE].index = -1; 00647 } 00648 00649 return; 00650 }
void calcJointRotation | ( | void | ) | [private] |
void CNiVMDTool::calcJointRotation(void)
全ジョイントのクオータニオンを計算し直す.
Definition at line 472 of file NiVMDTool.cpp.
References CNiVMDTool::A2TPose, CNiVMDTool::calcJointIK(), CBaseFrameTool::clearVectorData(), CBaseFrameTool::frames_num, CBaseFrameTool::framesData, NiJointData::index, NiFrameData::jdat, NiFrameData::jnum, NiJointData::joint, CBaseFrameTool::posVect, NiJointData::quat, CBaseFrameTool::rotQuat, NiJointData::vect, VMD_CENTER, VMD_EYES, VMD_JOINT_NUM, VMD_L_ANKLE_IK, VMD_L_ARM, VMD_L_ARM_TW, VMD_L_ELBOW, VMD_L_EYE, VMD_L_WRIST, VMD_L_WRIST_TW, VMD_R_ANKLE_IK, VMD_R_ARM, VMD_R_ARM_TW, VMD_R_ELBOW, VMD_R_EYE, VMD_R_WRIST, and VMD_R_WRIST_TW.
Referenced by CNiVMDTool::getFramesData().
00473 { 00474 if (framesData==NULL || frames_num<=0) return; 00475 00476 if (posVect==NULL) posVect = (Vector<double>*)malloc(sizeof(Vector<double>)*VMD_JOINT_NUM); 00477 if (rotQuat==NULL) rotQuat = (Quaternion<double>*)malloc(sizeof(Quaternion<double>)*VMD_JOINT_NUM); 00478 if (posVect==NULL || rotQuat==NULL) return; 00479 clearVectorData(VMD_JOINT_NUM); 00480 00481 NiJointData prevJoint[VMD_JOINT_NUM]; // joints_num = VMD_JOINT_NUM 00482 for (int j=0; j<VMD_JOINT_NUM; j++) { 00483 prevJoint[j].joint = -1; 00484 prevJoint[j].index = -1; 00485 prevJoint[j].vect.init(-1.0); 00486 prevJoint[j].quat.init(-1.0); 00487 } 00488 00489 // 関節の変換 00490 for (unsigned int i=0; i<frames_num; i++) { 00491 // 00492 NiJointData* jdata = framesData[i].jdat; 00493 00494 jdata[VMD_CENTER].vect.c = 1.0; 00495 jdata[VMD_CENTER].quat.c = 1.0; 00496 00497 for (int j=0; j<framesData[i].jnum; j++) { 00498 // 00499 if (jdata[j].joint>=0) { 00500 posVect[j] = jdata[j].vect; 00501 rotQuat[j] = jdata[j].quat; 00502 if (posVect[j].c<0.0) posVect[j] = prevJoint[j].vect; 00503 if (rotQuat[j].c<0.0) rotQuat[j] = prevJoint[j].quat; 00504 } 00505 // 00506 else { 00507 posVect[j] = prevJoint[j].vect; 00508 rotQuat[j] = prevJoint[j].quat; 00509 } 00510 } 00511 00513 calcJointIK(i); // IK 00515 00516 // 00517 for (int j=0; j<framesData[i].jnum; j++) { 00518 if (jdata[j].joint>=0) { 00519 prevJoint[j] = jdata[j]; 00520 } 00521 } 00522 00523 // 00524 rotQuat[VMD_L_WRIST] = rotQuat[VMD_L_WRIST]*rotQuat[VMD_L_WRIST_TW]; 00525 rotQuat[VMD_L_ELBOW] = rotQuat[VMD_L_ELBOW]*rotQuat[VMD_L_ARM_TW]; 00526 rotQuat[VMD_R_WRIST] = rotQuat[VMD_R_WRIST]*rotQuat[VMD_R_WRIST_TW]; 00527 rotQuat[VMD_R_ELBOW] = rotQuat[VMD_R_ELBOW]*rotQuat[VMD_R_ARM_TW]; 00528 00529 rotQuat[VMD_L_EYE] = rotQuat[VMD_L_EYE]*rotQuat[VMD_EYES]; 00530 rotQuat[VMD_R_EYE] = rotQuat[VMD_R_EYE]*rotQuat[VMD_EYES]; 00531 00533 rotQuat[VMD_L_WRIST] = A2TPose*rotQuat[VMD_L_WRIST]*~A2TPose; 00534 rotQuat[VMD_L_ELBOW] = A2TPose*rotQuat[VMD_L_ELBOW]*~A2TPose; 00535 rotQuat[VMD_L_ARM] = rotQuat[VMD_L_ARM]*~A2TPose; 00536 00537 rotQuat[VMD_R_WRIST] = ~A2TPose*rotQuat[VMD_R_WRIST]*A2TPose; 00538 rotQuat[VMD_R_ELBOW] = ~A2TPose*rotQuat[VMD_R_ELBOW]*A2TPose; 00539 rotQuat[VMD_R_ARM] = rotQuat[VMD_R_ARM]*A2TPose; 00540 00541 // 足首の回転は省略 00542 rotQuat[VMD_L_ANKLE_IK].set(1.0, 0.0, 0.0, 0.0, 1.0); 00543 rotQuat[VMD_R_ANKLE_IK].set(1.0, 0.0, 0.0, 0.0, 1.0); 00544 00545 //rotQuat[VMD_CENTER] = rotQuat[VMD_CENTER]*~rotQuat[VMD_PARENT]; 00546 //posVect[VMD_CENTER] = posVect[VMD_CENTER] + posVect[VMD_PARENT]; 00547 00548 // 00549 for (int j=0; j<framesData[i].jnum; j++) { 00550 jdata[j].joint = prevJoint[j].joint; 00551 jdata[j].index = prevJoint[j].index; 00552 jdata[j].vect = posVect[j]; 00553 jdata[j].quat = rotQuat[j]; 00554 } 00555 } 00556 00557 return; 00558 }
void calcLegIK_CCD | ( | Vector< double > * | vect, | |
Vector< double > | ik_vect, | |||
Quaternion< double > * | quat, | |||
int | rpmax | |||
) | [private] |
HIP(2) -> KNEE(1) -> ANKLE(0) の IK をCCDで解く.
Definition at line 657 of file NiVMDTool.cpp.
Referenced by CNiVMDTool::calcJointIK().
00658 { 00659 Vector<double> vect_Y(0.0, 1.0, 0.0, 1.0); 00660 Vector<double> effect, target; 00661 Quaternion<double> rot; 00662 00663 for (int j=0; j<3; j++) quat[j].init(); 00664 00665 for (int i=0; i<rpmax; i++) { 00666 // 00667 int cnt = 0; 00668 for (int j=1; j<3; j++) { 00669 // 00670 if (i==0 && j==1) { 00671 rot.setRotation((double)PI_DIV2, vect_Y); // 最初にひざを曲げる 00672 } 00673 else { 00674 effect = vect[0] - vect[j]; 00675 target = ik_vect - vect[j]; 00676 rot = V2VQuaternion(effect, target); 00677 } 00678 00679 // 00680 if (rot.c>0.0) { 00681 rot.normalize(); 00682 if (rot.s<1.00-Zero_Eps) { 00683 //if (rot.s<1.00) { 00684 quat[j] = quat[j]*rot; 00685 for (int k=0; k<j; k++) { 00686 vect[k] = VectorRotation(vect[k]-vect[j], rot) + vect[j]; 00687 } 00688 } 00689 else cnt++; 00690 } 00691 else cnt++; 00692 } 00693 if (cnt==2) break; 00694 } 00695 00696 return; 00697 }
void clear_data | ( | void | ) |
Reimplemented from CBaseFrameTool.
Definition at line 197 of file NiVMDTool.cpp.
References CNiVMDTool::free_data().
Referenced by CNiFileTool::clearFrameData(), CNiVMDTool::free_data(), CNiVMDTool::getFramesData(), and CNiVMDTool::readFile().
00198 { 00199 CBaseFrameTool::free_data(); 00200 }
NiFrameData * convert2FrameData | ( | VMDJointData * | motion_data, | |
unsigned int | datanum, | |||
unsigned int & | framenum | |||
) | [private] |
NiFrameData* CNiVMDTool::convert2FrameData(VMDJointData* motion_data, unsigned int datanum, unsigned int& framenum)
VMDの全フレームデータを共通ジョイントのフレームデータに変換する.
[in] | datanum | データの総数 |
[out] | framenum | 一意的なフレームの数 |
Definition at line 388 of file NiVMDTool.cpp.
References VMDJointData::frm_num, NiFrameData::frmn, NiJointData::index, NiFrameData::jdat, NiJointData::joint, CBaseFrameTool::joints_num, jbxwl::makeFramesData(), NiFrameData::msec, VMDJointData::posx, VMDJointData::posy, VMDJointData::posz, NiJointData::quat, VMDJointData::qutw, VMDJointData::qutx, VMDJointData::quty, VMDJointData::qutz, NiJointData::vect, VMD_GRID_UNIT, and jbxwl::VMDJointNum().
Referenced by CNiVMDTool::getFramesData().
00389 { 00390 framenum = 0; 00391 if (motion_data==NULL || datanum<=0) return NULL; 00392 00393 // VMDのデータをフレーム番号でソート 00394 VMDJointData swap_motion; 00395 unsigned int k = datanum - 1; 00396 while (k>0) { 00397 unsigned int j = 0; 00398 for (unsigned int i=0; i<k; i++) { 00399 if (motion_data[i].frm_num>motion_data[i+1].frm_num) { 00400 swap_motion = motion_data[i]; 00401 motion_data[i] = motion_data[i+1]; 00402 motion_data[i+1] = swap_motion; 00403 j = i; 00404 } 00405 } 00406 k = j; 00407 } 00408 00409 // 一意的なフレーム数を数える 00410 unsigned int uniq_frame = 1; 00411 00412 unsigned int frm_num = motion_data[0].frm_num; 00413 for (unsigned int i=1; i<datanum; i++) { 00414 if (frm_num!=motion_data[i].frm_num) { 00415 uniq_frame++; 00416 frm_num = motion_data[i].frm_num; 00417 } 00418 } 00419 00420 NiFrameData* ni_joints = makeFramesData((int)uniq_frame, joints_num, NULL); 00421 if (ni_joints==NULL) return NULL; 00422 framenum = uniq_frame; 00423 00424 // Joints 00425 unsigned int datacnt = 0; 00426 for (unsigned int i=0; i<uniq_frame; i++) { 00427 frm_num = motion_data[datacnt].frm_num; 00428 ni_joints[i].frmn = frm_num; 00429 ni_joints[i].msec = (int)(frm_num*33.3333333333333); // msec 00430 // 00431 while (frm_num==motion_data[datacnt].frm_num) { 00432 int joint = VMDJointNum(motion_data[datacnt].name); 00433 if (joint>=0) { 00434 NiJointData* jdat = &(ni_joints[i].jdat[joint]); 00435 jdat->joint = joint; 00436 jdat->index = i; 00437 jdat->vect.x = -motion_data[datacnt].posz*(double)VMD_GRID_UNIT; 00438 jdat->vect.y = motion_data[datacnt].posx*(double)VMD_GRID_UNIT; 00439 jdat->vect.z = motion_data[datacnt].posy*(double)VMD_GRID_UNIT; 00440 jdat->quat.x = motion_data[datacnt].qutz; 00441 jdat->quat.y = -motion_data[datacnt].qutx; 00442 jdat->quat.z = -motion_data[datacnt].quty; 00443 jdat->quat.s = motion_data[datacnt].qutw; 00444 if (jdat->quat.s<0.0) jdat->quat = - jdat->quat; 00445 jdat->quat.normalize(); 00446 00447 // 00448 if (jdat->vect.x!=0.0 || jdat->vect.y!=0.0 || jdat->vect.z!=0.0) { 00449 jdat->vect.c = 1.0; 00450 } 00451 if (jdat->quat.x!=0.0 || jdat->quat.y!=0.0 || jdat->quat.z!=0.0 || jdat->quat.s!=0.0) { 00452 jdat->quat.c = 1.0; 00453 } 00454 } 00455 00456 datacnt++; 00457 if (datacnt==datanum) break; 00458 } 00459 } 00460 00461 // 00462 return ni_joints; 00463 }
void free_data | ( | void | ) |
Reimplemented from CBaseFrameTool.
Definition at line 182 of file NiVMDTool.cpp.
References CNiVMDTool::clear_data(), CNiVMDTool::dmy_frames, CNiVMDTool::dmy_frmnum, jbxwl::freeFramesData(), CNiVMDTool::vmd_datnum, and CNiVMDTool::vmd_frames.
Referenced by CNiVMDTool::clear_data(), and CNiVMDTool::~CNiVMDTool().
00183 { 00184 if (dmy_frames!=NULL) ::freeFramesData(dmy_frames, dmy_frmnum); 00185 if (vmd_frames!=NULL) ::free(vmd_frames); 00186 00187 vmd_frames = NULL; 00188 vmd_datnum = 0; 00189 dmy_frames = NULL; 00190 dmy_frmnum = 0; 00191 00192 clear_data(); 00193 }
NiFrameData * getFramesData | ( | void | ) | [virtual] |
NiFrameData* CNiVMDTool::getJointsFrame(void)
ジョイントの各フレームデータを計算し,静的なデータとして返す. ただし,VMDでは全フレームのデータがないので,ここではダミーデータを返し,実際のデータは getFrameData()で得る.
Reimplemented from CBaseFrameTool.
Definition at line 330 of file NiVMDTool.cpp.
References CNiVMDTool::calcJointRotation(), CNiVMDTool::clear_data(), CNiVMDTool::convert2FrameData(), CNiVMDTool::dmy_frames, CNiVMDTool::dmy_frmnum, CBaseFrameTool::exec_time, CBaseFrameTool::frames_num, CBaseFrameTool::framesData, NiFrameData::frmn, NiFrameData::jdat, NiFrameData::jnum, NiJointData::joint, CBaseFrameTool::joints_num, jbxwl::makeFramesData(), NiFrameData::msec, CNiVMDTool::rate_frame, CBaseFrameTool::start_time, CBaseFrameTool::stop_time, jbxwl::VMD2NiJointNum(), CNiVMDTool::vmd_datnum, CNiVMDTool::vmd_frames, and VMD_JOINT_NUM.
Referenced by CNiFileTool::readVMDFile().
00331 { 00332 joints_num = VMD_JOINT_NUM; 00333 00335 if (framesData!=NULL) clear_data(); 00336 framesData = convert2FrameData(vmd_frames, vmd_datnum, frames_num); 00337 if (framesData==NULL) return NULL; 00338 00339 calcJointRotation(); 00341 00342 // ジョイント番号の書き換え 00343 for (unsigned int i=0; i<frames_num; i++) { 00344 // 00345 for (int j=0; j<framesData[i].jnum; j++) { 00346 int n = VMD2NiJointNum(framesData[i].jdat[j].joint); 00347 framesData[i].jdat[j].joint = n; 00348 } 00349 } 00350 00351 00352 dmy_frmnum = (int)(framesData[frames_num-1].frmn*rate_frame); 00353 dmy_frames = makeFramesData(dmy_frmnum, 0, NULL); 00354 if (dmy_frames==NULL) { 00355 dmy_frmnum = frames_num; 00356 return framesData; 00357 } 00358 00359 for (unsigned int i=0; i<dmy_frmnum; i++) { 00360 dmy_frames[i].jnum = joints_num; 00361 dmy_frames[i].msec = (int)(i*(100.0/(rate_frame*3.0))); 00362 } 00363 if (rate_frame!=1.0) { 00364 for (unsigned int i=0; i<frames_num; i++) { 00365 framesData[i].frmn = (int)(framesData[i].frmn*rate_frame); 00366 framesData[i].msec = (int)(framesData[i].msec/rate_frame); 00367 } 00368 } 00369 00370 start_time = framesData[0].msec; 00371 stop_time = framesData[frames_num-1].msec; 00372 exec_time = stop_time - start_time; 00373 00374 return dmy_frames; 00375 }
virtual unsigned int getFramesNumber | ( | void | ) | [inline, virtual] |
Reimplemented from CBaseFrameTool.
Definition at line 121 of file NiVMDTool.h.
References CNiVMDTool::dmy_frmnum.
Referenced by CNiFileTool::readVMDFile().
00121 { return dmy_frmnum;}
NiJointData * getJointsData | ( | int | frmnum, | |
int | fps | |||
) | [virtual] |
NiJointData* CNiVMDTool::getJointsData(int frmnum, int fps)
動的にジョイントデータを計算する場合に使用する.
getJointsFrame で返したデータが NULLの場合,代わりにこの関数が呼ばれる.
フレーム frmnum時の 全ジョイントのデータを得る.戻り値は配列.
frmnumのデータが存在しない場合は,補間する.
frmnum | フレーム数 | |
fps | FPS. |
Reimplemented from CBaseFrameTool.
Definition at line 713 of file NiVMDTool.cpp.
References CBaseFrameTool::clearJointsData(), CBaseFrameTool::frames_num, CBaseFrameTool::framesData, NiJointData::index, NiFrameData::jdat, NiJointData::joint, CBaseFrameTool::joints_num, CBaseFrameTool::jointsData, NiJointData::quat, NiJointData::vect, and VMD_FARME_RATE.
00714 { 00715 clearJointsData(joints_num); 00716 00717 frmnum = (int)((double)frmnum*VMD_FARME_RATE/(double)fps); 00718 00719 // 00720 for (int j=0; j<joints_num; j++) { 00721 // 00722 int n = framesData[0].jdat[j].joint; 00723 if (n>=0) { 00724 unsigned int st_index = 0; 00725 unsigned int en_index = 0; 00726 00727 while (en_index<frames_num && framesData[en_index].frmn<frmnum) en_index++; 00728 if (en_index==frames_num) break; 00729 00730 if (en_index==0 || (framesData[en_index].frmn==frmnum && en_index==framesData[en_index].jdat[j].index)) { 00731 jointsData[j].vect = framesData[en_index].jdat[j].vect; 00732 jointsData[j].quat = framesData[en_index].jdat[j].quat; 00733 } 00734 else { 00735 st_index = framesData[en_index-1].jdat[j].index; 00736 while (en_index<frames_num && en_index!=framesData[en_index].jdat[j].index) en_index++; 00737 00738 if (en_index==frames_num) { 00739 jointsData[j].vect = framesData[st_index].jdat[j].vect; 00740 jointsData[j].quat = framesData[st_index].jdat[j].quat; 00741 } 00742 else { 00743 NiJointData st_joint = framesData[st_index].jdat[j]; 00744 NiJointData en_joint = framesData[en_index].jdat[j]; 00745 double tparam = ((double)(frmnum - framesData[st_index].frmn))/(framesData[en_index].frmn - framesData[st_index].frmn); 00746 jointsData[j].vect = BSplineInterp4 (st_joint.vect, en_joint.vect, tparam); 00747 jointsData[j].quat = SlerpQuaternion(st_joint.quat, en_joint.quat, tparam); 00748 } 00749 } 00750 00751 jointsData[j].joint = n; 00752 jointsData[j].index = frmnum; 00753 jointsData[j].vect.c = 1.0; 00754 jointsData[j].quat.c = 1.0; 00755 } 00756 } 00757 00758 return jointsData; 00759 }
BOOL readFile | ( | FILE * | fp | ) | [virtual] |
BOOL CNiVMDTool::readFile(FILE* fp)
VMDファイルを読み込む
Reimplemented from CBaseFrameTool.
Definition at line 213 of file NiVMDTool.cpp.
References CNiVMDTool::clear_data(), CBaseFrameTool::clearJointsData(), CBaseFrameTool::clearVectorData(), VMDFileHeader::data_num, CBaseFrameTool::joints_num, CBaseFrameTool::jointsData, CBaseFrameTool::posVect, CNiVMDTool::readFileHeader(), CNiVMDTool::readJointsData(), CBaseFrameTool::rotQuat, CNiVMDTool::vmd_datnum, CNiVMDTool::vmd_frames, CNiVMDTool::vmd_header, and VMD_JOINT_NUM.
Referenced by CNiFileTool::readVMDFile().
00214 { 00215 if (fp==NULL) return FALSE; 00216 00217 clear_data(); 00218 00219 vmd_datnum = 0; 00220 vmd_header = readFileHeader(fp); // ヘッダ部 00221 if (vmd_header.data_num==0) return FALSE; 00222 00223 vmd_frames = readJointsData(fp, vmd_header.data_num); // 全フレームのデータ 00224 if (vmd_frames==NULL) return FALSE; 00225 vmd_datnum = vmd_header.data_num; 00226 00227 // 00228 joints_num = VMD_JOINT_NUM; 00229 if (jointsData!=NULL) ::free(jointsData); 00230 jointsData = (NiJointData*)malloc(sizeof(NiJointData)*joints_num); 00231 if (jointsData==NULL) { 00232 clear_data(); 00233 return FALSE; 00234 } 00235 clearJointsData(joints_num); 00236 00237 if (posVect==NULL) posVect = (Vector<double>*)malloc(sizeof(Vector<double>)*VMD_JOINT_NUM); 00238 if (rotQuat==NULL) rotQuat = (Quaternion<double>*)malloc(sizeof(Quaternion<double>)*VMD_JOINT_NUM); 00239 if (posVect==NULL || rotQuat==NULL) { 00240 clear_data(); 00241 return FALSE; 00242 } 00243 clearVectorData(VMD_JOINT_NUM); 00244 00245 return TRUE; 00246 }
VMDFileHeader readFileHeader | ( | FILE * | fp | ) | [private] |
VMDFileHeader CNiVMDTool::readFileHeader(FILE* fp)
VMDファイルのヘッダ部を読み込む
Definition at line 255 of file NiVMDTool.cpp.
References VMDFileHeader::data_num, VMDFileHeader::header, VMDFileHeader::name, and VMD_FILE_HD_ID2.
Referenced by CNiVMDTool::readFile().
00256 { 00257 VMDFileHeader fhd; 00258 00259 fread(fhd.header, 30, 1, fp); 00260 fread(fhd.name, 20, 1, fp); 00261 fread(&fhd.data_num, 4, 1, fp); 00262 00263 if (strcmp(VMD_FILE_HD_ID2, fhd.header)) { 00264 fhd.data_num = 0; 00265 } 00266 00267 return fhd; 00268 }
VMDJointData readJointData | ( | FILE * | fp | ) | [private] |
VMDJointData CNiVMDTool::readJointData(FILE* fp)
VMDファイルから 1フレーム(ジョイント)の VMDJointDataを読み込む.
sizeof(VMDJointData)==15 + (4+4x7+64)
Definition at line 278 of file NiVMDTool.cpp.
References VMDJointData::frm_num, and VMDJointData::name.
Referenced by CNiVMDTool::readJointsData().
00279 { 00280 VMDJointData frame; 00281 00282 fread(frame.name, 15, 1, fp); 00283 fread(&frame.frm_num, 96, 1, fp); // 4 + 4x7 + 64 00284 00285 return frame; 00286 }
VMDJointData * readJointsData | ( | FILE * | fp, | |
unsigned int & | frmnum | |||
) | [private] |
VMDJointData* CNiVMDTool::readJointsData(FILE* fp, unsigned int& frmnum)
全フレーム&ジョイントの VMDJointDataを読み込む.
ジョイント間でフレームの同期は取られていない.
Definition at line 296 of file NiVMDTool.cpp.
References CNiVMDTool::readJointData().
Referenced by CNiVMDTool::readFile().
00297 { 00298 VMDJointData* motion_data = (VMDJointData*)malloc(frmnum*sizeof(VMDJointData)); 00299 if (motion_data==NULL) return NULL; 00300 memset(motion_data, 0, frmnum*sizeof(VMDJointData)); 00301 00302 // 00303 unsigned int num = 0; 00304 while(num<frmnum) { 00305 motion_data[num] = readJointData(fp); 00306 if (feof(fp)) break; 00307 num++; 00308 } 00309 00310 frmnum = num; 00311 if (frmnum==0) { 00312 ::free(motion_data); 00313 motion_data = NULL; 00314 } 00315 00316 return motion_data; 00317 }
Quaternion<double> A2TPose [private] |
Definition at line 129 of file NiVMDTool.h.
Referenced by CNiVMDTool::calcJointRotation(), and CNiVMDTool::CNiVMDTool().
NiFrameData* dmy_frames [private] |
Definition at line 138 of file NiVMDTool.h.
Referenced by CNiVMDTool::CNiVMDTool(), CNiVMDTool::free_data(), and CNiVMDTool::getFramesData().
unsigned int dmy_frmnum [private] |
Definition at line 139 of file NiVMDTool.h.
Referenced by CNiVMDTool::CNiVMDTool(), CNiVMDTool::free_data(), CNiVMDTool::getFramesData(), and CNiVMDTool::getFramesNumber().
double rate_frame [private] |
Definition at line 130 of file NiVMDTool.h.
Referenced by CNiVMDTool::CNiVMDTool(), and CNiVMDTool::getFramesData().
unsigned int vmd_datnum [private] |
Definition at line 135 of file NiVMDTool.h.
Referenced by CNiVMDTool::CNiVMDTool(), CNiVMDTool::free_data(), CNiVMDTool::getFramesData(), and CNiVMDTool::readFile().
VMDJointData* vmd_frames [private] |
Definition at line 134 of file NiVMDTool.h.
Referenced by CNiVMDTool::CNiVMDTool(), CNiVMDTool::free_data(), CNiVMDTool::getFramesData(), and CNiVMDTool::readFile().
VMDFileHeader vmd_header [private] |
Definition at line 133 of file NiVMDTool.h.
Referenced by CNiVMDTool::CNiVMDTool(), and CNiVMDTool::readFile().