5 static struct erb_key *findkey(struct erb_track *trk, long tm);
6 static int setkey(struct erb_track *trk, long key, float val);
7 static float evalkey(struct erb_track *trk, long key);
9 void erb_node_pos(struct erb_node *n, long tm, float x, float y, float z)
11 setkey(n->track + ERB_TRK_X, tm, x);
12 setkey(n->track + ERB_TRK_Y, tm, y);
13 setkey(n->track + ERB_TRK_Z, tm, z);
16 void erb_node_rot(struct erb_node *n, long tm, float qx, float qy, float qz, float qw)
18 setkey(n->track + ERB_TRK_QX, tm, qx);
19 setkey(n->track + ERB_TRK_QY, tm, qy);
20 setkey(n->track + ERB_TRK_QZ, tm, qz);
21 setkey(n->track + ERB_TRK_QW, tm, qw);
24 void erb_node_rot_axis(struct erb_node *n, long tm, float angle_deg, float x, float y, float z)
27 cgm_qrotation(&q, cgm_deg_to_rad(angle_deg), x, y, z);
28 erb_node_rot(n, tm, q.x, q.y, q.z, q.w);
31 void erb_node_scale(struct erb_node *n, long tm, float sx, float sy, float sz)
33 setkey(n->track + ERB_TRK_SX, tm, sx);
34 setkey(n->track + ERB_TRK_SY, tm, sy);
35 setkey(n->track + ERB_TRK_SZ, tm, sz);
38 void erb_node_update(struct erb_node *n, long tm)
40 erb_node_eval_node_matrix(n, tm, n->node_xform);
42 cgm_mcopy(n->inv_node_xform, n->node_xform);
43 cgm_minverse(n->inv_node_xform);
45 cgm_mcopy(n->xform, n->node_xform);
46 cgm_mcopy(n->inv_xform, n->inv_node_xform);
49 cgm_mmul(n->xform, n->par->xform);
50 cgm_mpremul(n->inv_xform, n->par->inv_xform);
54 void erb_node_setxform(struct erb_node *n, float *mat)
56 cgm_mcopy(n->node_xform, mat);
57 cgm_mcopy(n->inv_node_xform, mat);
58 cgm_minverse(n->inv_node_xform);
60 cgm_mcopy(n->xform, n->node_xform);
61 cgm_mcopy(n->inv_xform, n->inv_node_xform);
64 cgm_mmul(n->xform, n->par->xform);
65 cgm_mpremul(n->inv_xform, n->par->inv_xform);
69 void erb_node_eval_pos(struct erb_node *n, long tm, cgm_vec3 *pos)
71 pos->x = evalkey(n->track + ERB_TRK_X, tm);
72 pos->y = evalkey(n->track + ERB_TRK_Y, tm);
73 pos->z = evalkey(n->track + ERB_TRK_Z, tm);
76 void erb_node_eval_rot(struct erb_node *n, long tm, cgm_quat *rot)
78 rot->x = evalkey(n->track + ERB_TRK_QX, tm);
79 rot->y = evalkey(n->track + ERB_TRK_QY, tm);
80 rot->z = evalkey(n->track + ERB_TRK_QZ, tm);
81 rot->w = evalkey(n->track + ERB_TRK_QW, tm);
84 void erb_node_eval_scale(struct erb_node *n, long tm, cgm_vec3 *scale)
86 scale->x = evalkey(n->track + ERB_TRK_SX, tm);
87 scale->y = evalkey(n->track + ERB_TRK_SY, tm);
88 scale->z = evalkey(n->track + ERB_TRK_SZ, tm);
91 void erb_node_eval_matrix(struct erb_node *n, long tm, float *mat)
93 erb_node_eval_node_matrix(n, tm, mat);
95 cgm_mmul(mat, n->par->xform);
99 void erb_node_eval_node_matrix(struct erb_node *n, long tm, float *mat)
104 erb_node_eval_pos(n, tm, &pos);
105 erb_node_eval_rot(n, tm, &rot);
106 erb_node_eval_scale(n, tm, &scale);
109 cgm_mtranslate(mat, pos.x, pos.y, pos.z);
110 cgm_mrotate_quat(mat, &rot);
111 cgm_mscale(mat, scale.x, scale.y, scale.z);
114 static struct erb_key *findkey(struct erb_track *trk, long tm)
116 struct erb_key *beg, *end, *mid;
118 /* TODO: if num_keys < something_small, do linear search */
119 if(trk->num_keys <= 0) return 0;
122 end = trk->keys + trk->num_keys;
125 mid = beg + ((end - beg) >> 1);
127 if(tm == mid->tm) return mid;
138 static int setkey(struct erb_track *trk, long tm, float val)
143 if((key = findkey(trk, tm)) && key->tm == tm) {
148 if(trk->num_keys >= trk->max_keys) {
149 int newsz = trk->max_keys ? trk->max_keys << 1 : 8;
152 if(!(ptr = realloc(trk->keys, newsz * sizeof *key))) {
153 fprintf(stderr, "erebus: failed to add keyframe (realloc track failed)\n");
157 trk->max_keys = newsz;
161 rest = trk->num_keys - (key - trk->keys);
163 memmove(key + 1, key, rest * sizeof *key);
171 static float evalkey(struct erb_track *trk, long tm)