#ifndef MOTIONCAPTURER_H #define MOTIONCAPTURER_H #include "proj.h" // for bvh parser, assume MAX MAX_CHILDREN joints from a root typedef enum { ROOT = 0, JOINT = 1, END_SITE = 2 } Segtype; typedef struct Ancestry{ Node *node; Ancestry *child; } Ancestry; struct Node { char name[40]; Segtype type; double offset[4]; // translation offset. offset[3]=1=w(homogenous thing) int e_off; // offset WITHIN A FRAME to the euler array in MotionCapturer. int q_off; // offset WITHIN A FRAME to the quatern array in MotionCapturer. int chan_cnt; // has to be 3 or 6 bool b_first3trans; /* indicate order of chans: 3 trans channels first or rot first true if first 3 chan are transl, false if rot first only used during parsing for generalized parsing. */ Node *children[MAX_CHILDREN]; int children_cnt; Node *parent; // parent joint. // for proj3 Ancestry *ancestors; GLuint pickname; // for 3D picking Point4D gb_curPos; // 4D(x,y,z,w) coord of this node at cur frame in last iteration Point4D lc_goalPos; // goal's local pos in local coord Point4D gb_potPos; // potential 4D(x,y,z,w) coord of this node at cur frame in next iter Bone *bone; double dist_root2node_nat; // natural dist to root: = node pos - root pos double dist_root2node_max; // max dist to root = all bone len to get to root double v4_dist_root2node[4]; double v4_dist_root2node_nat[4]; }; struct Bone { Node *pnode; Node *cnode; JointType joint_type; double jAxis_ang; double j_ang_lim; double ang_twist_lim; double ang_twist; double v4_natural[4]; double v4_central[4]; double q_nat2cen[4]; // quat to rot from natural to central vec double len; }; class MotionCapturer { public: Node *root; int rot_cnt; // number of nodes having rotations (root + joints) int ends_cnt; // number of endsites int frame_cnt; // number of frames in this anim double frame_time; // time in sec for each frame double *trans; /* arr of root's translation at each frame. arr size = 3 * root_cnt * frame_cnt, root_cnt is usually 1 */ double *euler; /* arr of euler rotations read from .bvh file. each rotation angle in zxy order. and each rotation specified in hierachy order. Also all rotations are specified for one frame before the next frame. arr size = 3 * node_cnt * frame_cnt. */ double *quatern; /* arr of quatern rotations converted from the 3 euler rotations for each node. and each rotation specified in hierachy order. Also all rotations are specified for one frame before the next frame. arr size = 3 * node_cnt * frame_cnt. */ double *expmap; /* arr of exponential map rotations converted from the 3 euler rotations for each node. and each rotation specified in hierachy order. Also all rotations are specified for one frame before the next frame. arr size = 4 * node_cnt * frame_cnt. */ double *einterp; /* arr to store euler interp rot data. same size as euler */ double *qinterp; /* arr to store quatern interp rot data. same size as quatern */ double *minterp; /* arr to store expmap interp rot data. same size as expmap */ double *mqinterp; /* conv emap to q for interp */ // for 3D picking GLuint pickname_cur; // next avail pick name Node **pickarr; // array for picking, use name to index into arr to find corspd node. Node *endsites[MAX_ENDSITES]; bool b_read_flex_success; MotionCapturer::MotionCapturer(); ~MotionCapturer(); // fill in the rot angle lim spec Status read_input_flex( FILE *fin, Node *node ); private: }; /* returns a node's pos in a more global/upstream node's coord, returns global pos if ancestral_node=NULL */ void lc_to_ac_nodePos( double return_val[4], Node *ancestral_node, Node *selNode, RotType rotType, double *trans, double *rot ); /* find all ancestors from the root down to this node, set its child to NULL in ancestrial chain. return the ancestry chain start from root to this node (inclusive */ Ancestry *find_my_ancestors(Node *node); // del the ancestral chain headed by ancestors void del_ancestry(Ancestry* &ancestors); // connect joints w/ bones recursively void make_skeleton(Node* node); void init_bones(Node *root); /* recursively find all end sites and fill the array of endsites init es_cnt to 0 before 1st call*/ void create_endsite_list(Node **endsites, Node *node, int &es_cnt); //--------- parser functions ------------- //Status read_bvh_file(FILE *file, MotionCapturer *motionCapturer, FileType type); /* *****API**** called in viewer.cpp. read in file and fill a MotionCapturer object w/ hierarchical and motion data info return SUCCESS if read file ok FAILURE otherwise */ //--------- end parser functions----------- #endif