CNiVMDTool Class Reference

#include <NiVMDTool.h>

Inheritance diagram for CNiVMDTool:
Inheritance graph
[legend]
Collaboration diagram for CNiVMDTool:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 CNiVMDTool (void)
virtual ~CNiVMDTool (void)
void free_data (void)
void clear_data (void)
virtual unsigned int getFramesNumber (void)
virtual NiFrameDatagetFramesData (void)
virtual NiJointDatagetJointsData (int frmnum, int fps)
virtual BOOL readFile (FILE *fp)

Private Member Functions

VMDFileHeader readFileHeader (FILE *fp)
VMDJointData readJointData (FILE *fp)
VMDJointDatareadJointsData (FILE *fp, unsigned int &frmnum)
NiFrameDataconvert2FrameData (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
VMDJointDatavmd_frames
unsigned int vmd_datnum
NiFrameDatadmy_frames
unsigned int dmy_frmnum

Detailed Description

Definition at line 110 of file NiVMDTool.h.


Constructor & Destructor Documentation

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 }

Here is the call graph for this function:


Member Function Documentation

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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の全フレームデータを共通ジョイントのフレームデータに変換する.

Parameters:
[in] datanum データの総数
[out] framenum 一意的なフレームの数
Returns:
(ダミー)フレームデータへのポインタ

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

NiFrameData * getFramesData ( void   )  [virtual]

NiFrameData* CNiVMDTool::getJointsFrame(void)

ジョイントの各フレームデータを計算し,静的なデータとして返す. ただし,VMDでは全フレームのデータがないので,ここではダミーデータを返し,実際のデータは getFrameData()で得る.

See also:
convert2FrameData()
calcJointRotation()

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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;}

Here is the caller graph for this function:

NiJointData * getJointsData ( int  frmnum,
int  fps 
) [virtual]

NiJointData* CNiVMDTool::getJointsData(int frmnum, int fps)

動的にジョイントデータを計算する場合に使用する.
getJointsFrame で返したデータが NULLの場合,代わりにこの関数が呼ばれる.

フレーム frmnum時の 全ジョイントのデータを得る.戻り値は配列.
frmnumのデータが存在しない場合は,補間する.

Parameters:
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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Quaternion<double> A2TPose [private]

Definition at line 129 of file NiVMDTool.h.

Referenced by CNiVMDTool::calcJointRotation(), and CNiVMDTool::CNiVMDTool().

NiFrameData* dmy_frames [private]
unsigned int dmy_frmnum [private]
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 133 of file NiVMDTool.h.

Referenced by CNiVMDTool::CNiVMDTool(), and CNiVMDTool::readFile().


The documentation for this class was generated from the following files:

Generated on 15 Nov 2023 for JunkBox_Win_Lib by  doxygen 1.6.1