goat3dgfx

annotate src/xform_node.cc @ 21:7c593721547f

integrated support for the multiple animation system of libanim
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 27 Dec 2013 11:59:32 +0200
parents 7d6b667821cf
children 92bfb0206969
rev   line source
nuclear@0 1 #include <assert.h>
nuclear@0 2 #include <algorithm>
nuclear@0 3 #include "xform_node.h"
nuclear@0 4 #include "anim/anim.h"
nuclear@0 5 #include "anim/track.h"
nuclear@0 6
nuclear@15 7 using namespace goatgfx;
nuclear@15 8
nuclear@0 9 static inline anm_interpolator track_interpolator(Interp in);
nuclear@0 10 static inline anm_extrapolator track_extrapolator(Extrap ex);
nuclear@0 11
nuclear@0 12 XFormNode::XFormNode()
nuclear@0 13 {
nuclear@0 14 anm = new anm_node;
nuclear@0 15 anm_init_node(anm);
nuclear@0 16 }
nuclear@0 17
nuclear@0 18 XFormNode::~XFormNode()
nuclear@0 19 {
nuclear@0 20 anm_destroy_node(anm);
nuclear@0 21 delete anm;
nuclear@0 22 }
nuclear@0 23
nuclear@0 24 void XFormNode::set_name(const char *name)
nuclear@0 25 {
nuclear@0 26 anm_set_node_name(anm, name);
nuclear@0 27 }
nuclear@0 28
nuclear@0 29 const char *XFormNode::get_name() const
nuclear@0 30 {
nuclear@0 31 return anm_get_node_name(anm);
nuclear@0 32 }
nuclear@0 33
nuclear@0 34 void XFormNode::set_interpolator(Interp in)
nuclear@0 35 {
nuclear@0 36 anm_set_interpolator(anm, track_interpolator(in));
nuclear@0 37 interp = in;
nuclear@0 38 }
nuclear@0 39
nuclear@0 40 Interp XFormNode::get_interpolator() const
nuclear@0 41 {
nuclear@0 42 return interp;
nuclear@0 43 }
nuclear@0 44
nuclear@0 45 void XFormNode::set_extrapolator(Extrap ex)
nuclear@0 46 {
nuclear@0 47 anm_set_extrapolator(anm, track_extrapolator(ex));
nuclear@0 48 extrap = ex;
nuclear@0 49 }
nuclear@0 50
nuclear@0 51 Extrap XFormNode::get_extrapolator() const
nuclear@0 52 {
nuclear@0 53 return extrap;
nuclear@0 54 }
nuclear@0 55
nuclear@0 56 void XFormNode::add_child(XFormNode *child)
nuclear@0 57 {
nuclear@0 58 children.push_back(child);
nuclear@0 59 anm_link_node(anm, child->anm);
nuclear@0 60 }
nuclear@0 61
nuclear@0 62 void XFormNode::remove_child(XFormNode *child)
nuclear@0 63 {
nuclear@0 64 std::vector<XFormNode*>::iterator it;
nuclear@0 65 it = std::find(children.begin(), children.end(), child);
nuclear@0 66 if(it != children.end()) {
nuclear@0 67 children.erase(it);
nuclear@0 68 anm_unlink_node(anm, child->anm);
nuclear@0 69 }
nuclear@0 70 }
nuclear@0 71
nuclear@0 72 int XFormNode::get_children_count() const
nuclear@0 73 {
nuclear@0 74 return (int)children.size();
nuclear@0 75 }
nuclear@0 76
nuclear@0 77 XFormNode *XFormNode::get_child(int idx)
nuclear@0 78 {
nuclear@0 79 if(idx >= 0 && idx < get_children_count()) {
nuclear@0 80 return children[idx];
nuclear@0 81 }
nuclear@0 82 return 0;
nuclear@0 83 }
nuclear@0 84
nuclear@0 85 const XFormNode *XFormNode::get_child(int idx) const
nuclear@0 86 {
nuclear@0 87 if(idx >= 0 && idx < get_children_count()) {
nuclear@0 88 return children[idx];
nuclear@0 89 }
nuclear@0 90 return 0;
nuclear@0 91 }
nuclear@0 92
nuclear@21 93
nuclear@21 94 void XFormNode::use_animation(int idx)
nuclear@21 95 {
nuclear@21 96 if(idx >= 0) {
nuclear@21 97 anm_use_animation(anm, idx);
nuclear@21 98 }
nuclear@21 99 }
nuclear@21 100
nuclear@21 101 void XFormNode::use_animation(const char *name)
nuclear@21 102 {
nuclear@21 103 anm_use_animation(anm, anm_find_animation(anm, name));
nuclear@21 104 }
nuclear@21 105
nuclear@21 106 void XFormNode::use_animation(int aidx, int bidx, float t)
nuclear@21 107 {
nuclear@21 108 anm_use_animations(anm, aidx, bidx, t);
nuclear@21 109 }
nuclear@21 110
nuclear@21 111 void XFormNode::use_animation(const char *aname, const char *bname, float t)
nuclear@21 112 {
nuclear@21 113 int aidx = anm_find_animation(anm, aname);
nuclear@21 114 int bidx = anm_find_animation(anm, bname);
nuclear@21 115
nuclear@21 116 if(aidx == -1) {
nuclear@21 117 use_animation(bidx);
nuclear@21 118 }
nuclear@21 119 if(bidx == -1) {
nuclear@21 120 use_animation(aidx);
nuclear@21 121 }
nuclear@21 122 anm_use_animations(anm, aidx, bidx, t);
nuclear@21 123 }
nuclear@21 124
nuclear@21 125 int XFormNode::get_active_animation_index(int which) const
nuclear@21 126 {
nuclear@21 127 return anm_get_active_animation_index(anm, which);
nuclear@21 128 }
nuclear@21 129
nuclear@21 130 float XFormNode::get_active_animation_mix() const
nuclear@21 131 {
nuclear@21 132 return anm_get_active_animation_mix(anm);
nuclear@21 133 }
nuclear@21 134
nuclear@21 135 int XFormNode::get_animation_count() const
nuclear@21 136 {
nuclear@21 137 return anm_get_animation_count(anm);
nuclear@21 138 }
nuclear@21 139
nuclear@21 140 void XFormNode::add_animation(const char *name)
nuclear@21 141 {
nuclear@21 142 int idx = get_animation_count();
nuclear@21 143
nuclear@21 144 anm_add_animation(anm);
nuclear@21 145 use_animation(idx);
nuclear@21 146
nuclear@21 147 if(name) {
nuclear@21 148 set_animation_name(name);
nuclear@21 149 }
nuclear@21 150 }
nuclear@21 151
nuclear@21 152 void XFormNode::set_animation_name(const char *name)
nuclear@21 153 {
nuclear@21 154 anm_set_active_animation_name(anm, name);
nuclear@21 155 }
nuclear@21 156
nuclear@21 157 const char *XFormNode::get_animation_name() const
nuclear@21 158 {
nuclear@21 159 return anm_get_active_animation_name(anm);
nuclear@21 160 }
nuclear@21 161
nuclear@21 162
nuclear@21 163
nuclear@0 164 void XFormNode::set_position(const Vector3 &pos, long tmsec)
nuclear@0 165 {
nuclear@0 166 anm_set_position(anm, v3_cons(pos.x, pos.y, pos.z), ANM_MSEC2TM(tmsec));
nuclear@0 167 }
nuclear@0 168
nuclear@0 169 Vector3 XFormNode::get_node_position(long tmsec) const
nuclear@0 170 {
nuclear@0 171 vec3_t p = anm_get_node_position(anm, ANM_MSEC2TM(tmsec));
nuclear@0 172 return Vector3(p.x, p.y, p.z);
nuclear@0 173 }
nuclear@0 174
nuclear@0 175 void XFormNode::set_rotation(const Quaternion &quat, long tmsec)
nuclear@0 176 {
nuclear@0 177 anm_set_rotation(anm, quat_cons(quat.s, quat.v.x, quat.v.y, quat.v.z), ANM_MSEC2TM(tmsec));
nuclear@0 178 }
nuclear@0 179
nuclear@0 180 Quaternion XFormNode::get_node_rotation(long tmsec) const
nuclear@0 181 {
nuclear@0 182 quat_t q = anm_get_node_rotation(anm, ANM_MSEC2TM(tmsec));
nuclear@0 183 return Quaternion(q.w, q.x, q.y, q.z);
nuclear@0 184 }
nuclear@0 185
nuclear@0 186 void XFormNode::set_scaling(const Vector3 &pos, long tmsec)
nuclear@0 187 {
nuclear@0 188 anm_set_scaling(anm, v3_cons(pos.x, pos.y, pos.z), ANM_MSEC2TM(tmsec));
nuclear@0 189 }
nuclear@0 190
nuclear@0 191 Vector3 XFormNode::get_node_scaling(long tmsec) const
nuclear@0 192 {
nuclear@0 193 vec3_t s = anm_get_node_scaling(anm, ANM_MSEC2TM(tmsec));
nuclear@0 194 return Vector3(s.x, s.y, s.z);
nuclear@0 195 }
nuclear@0 196
nuclear@0 197 // these take hierarchy into account
nuclear@0 198 Vector3 XFormNode::get_position(long tmsec) const
nuclear@0 199 {
nuclear@0 200 vec3_t v = anm_get_position(anm, ANM_MSEC2TM(tmsec));
nuclear@0 201 return Vector3(v.x, v.y, v.z);
nuclear@0 202 }
nuclear@0 203
nuclear@0 204 Quaternion XFormNode::get_rotation(long tmsec) const
nuclear@0 205 {
nuclear@0 206 quat_t q = anm_get_rotation(anm, tmsec);
nuclear@0 207 return Quaternion(q.w, q.x, q.y, q.z);
nuclear@0 208 }
nuclear@0 209
nuclear@0 210 Vector3 XFormNode::get_scaling(long tmsec) const
nuclear@0 211 {
nuclear@0 212 vec3_t v = anm_get_scaling(anm, ANM_MSEC2TM(tmsec));
nuclear@0 213 return Vector3(v.x, v.y, v.z);
nuclear@0 214 }
nuclear@0 215
nuclear@0 216 void XFormNode::set_pivot(const Vector3 &pivot)
nuclear@0 217 {
nuclear@0 218 anm_set_pivot(anm, v3_cons(pivot.x, pivot.y, pivot.z));
nuclear@0 219 }
nuclear@0 220
nuclear@0 221 Vector3 XFormNode::get_pivot() const
nuclear@0 222 {
nuclear@0 223 vec3_t p = anm_get_pivot(anm);
nuclear@0 224 return Vector3(p.x, p.y, p.z);
nuclear@0 225 }
nuclear@0 226
nuclear@0 227 void XFormNode::set_local_matrix(const Matrix4x4 &mat)
nuclear@0 228 {
nuclear@0 229 local_matrix = mat;
nuclear@0 230 }
nuclear@0 231
nuclear@0 232 const Matrix4x4 &XFormNode::get_local_matrix() const
nuclear@0 233 {
nuclear@0 234 return local_matrix;
nuclear@0 235 }
nuclear@0 236
nuclear@0 237 void XFormNode::set_bone_matrix(const Matrix4x4 &bmat)
nuclear@0 238 {
nuclear@0 239 bone_matrix = bmat;
nuclear@0 240 }
nuclear@0 241
nuclear@0 242 const Matrix4x4 &XFormNode::get_bone_matrix() const
nuclear@0 243 {
nuclear@0 244 return bone_matrix;
nuclear@0 245 }
nuclear@0 246
nuclear@0 247 #define FOO
nuclear@0 248
nuclear@0 249 void XFormNode::get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat) const
nuclear@0 250 {
nuclear@0 251 anm_time_t tm = ANM_MSEC2TM(tmsec);
nuclear@0 252
nuclear@0 253 if(mat) {
nuclear@0 254 anm_get_node_matrix(anm, (scalar_t(*)[4])mat, tm);
nuclear@0 255 #ifdef FOO
nuclear@0 256 *mat = local_matrix * *mat;
nuclear@0 257 #else
nuclear@0 258 *mat = *mat * local_matrix;
nuclear@0 259 #endif
nuclear@0 260 }
nuclear@0 261 if(inv_mat) {
nuclear@0 262 anm_get_inv_matrix(anm, (scalar_t(*)[4])inv_mat, tm);
nuclear@0 263 }
nuclear@0 264 }
nuclear@0 265
nuclear@0 266 void XFormNode::get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat) const
nuclear@0 267 {
nuclear@0 268 anm_time_t tm = ANM_MSEC2TM(tmsec);
nuclear@0 269
nuclear@0 270 if(mat) {
nuclear@0 271 anm_get_matrix(anm, (scalar_t(*)[4])mat, tm);
nuclear@0 272 #ifdef FOO
nuclear@0 273 *mat = local_matrix * *mat;
nuclear@0 274 #else
nuclear@0 275 *mat = *mat * local_matrix;
nuclear@0 276 #endif
nuclear@0 277 }
nuclear@0 278 if(inv_mat) {
nuclear@0 279 anm_get_inv_matrix(anm, (scalar_t(*)[4])inv_mat, tm);
nuclear@0 280 }
nuclear@0 281 }
nuclear@0 282
nuclear@0 283
nuclear@0 284 // ---- Track ----
nuclear@0 285
nuclear@0 286 Track::Track()
nuclear@0 287 {
nuclear@0 288 trk = new anm_track;
nuclear@0 289 anm_init_track(trk);
nuclear@0 290 }
nuclear@0 291
nuclear@0 292 Track::~Track()
nuclear@0 293 {
nuclear@0 294 anm_destroy_track(trk);
nuclear@0 295 delete trk;
nuclear@0 296 }
nuclear@0 297
nuclear@0 298 Track::Track(const Track &rhs)
nuclear@0 299 {
nuclear@0 300 trk = new anm_track;
nuclear@0 301 anm_init_track(trk);
nuclear@0 302 anm_copy_track(trk, rhs.trk);
nuclear@0 303 interp = rhs.interp;
nuclear@0 304 extrap = rhs.extrap;
nuclear@0 305 }
nuclear@0 306
nuclear@0 307 Track &Track::operator =(const Track &rhs)
nuclear@0 308 {
nuclear@0 309 if(&rhs == this) {
nuclear@0 310 return *this;
nuclear@0 311 }
nuclear@0 312
nuclear@0 313 anm_copy_track(trk, rhs.trk);
nuclear@0 314 interp = rhs.interp;
nuclear@0 315 extrap = rhs.extrap;
nuclear@0 316 return *this;
nuclear@0 317 }
nuclear@0 318
nuclear@0 319
nuclear@0 320 void Track::set_interpolator(Interp in)
nuclear@0 321 {
nuclear@0 322 anm_set_track_interpolator(trk, track_interpolator(in));
nuclear@0 323 interp = in;
nuclear@0 324 }
nuclear@0 325
nuclear@0 326 Interp Track::get_interpolator() const
nuclear@0 327 {
nuclear@0 328 return interp;
nuclear@0 329 }
nuclear@0 330
nuclear@0 331 void Track::set_extrapolator(Extrap ex)
nuclear@0 332 {
nuclear@0 333 anm_set_track_extrapolator(trk, track_extrapolator(ex));
nuclear@0 334 extrap = ex;
nuclear@0 335 }
nuclear@0 336
nuclear@0 337 Extrap Track::get_extrapolator() const
nuclear@0 338 {
nuclear@0 339 return extrap;
nuclear@0 340 }
nuclear@0 341
nuclear@0 342 void Track::set_default(double def)
nuclear@0 343 {
nuclear@0 344 anm_set_track_default(trk, def);
nuclear@0 345 }
nuclear@0 346
nuclear@0 347 void Track::set_value(float val, long tmsec)
nuclear@0 348 {
nuclear@0 349 anm_set_value(trk, ANM_MSEC2TM(tmsec), val);
nuclear@0 350 }
nuclear@0 351
nuclear@0 352 float Track::get_value(long tmsec) const
nuclear@0 353 {
nuclear@0 354 return anm_get_value(trk, ANM_MSEC2TM(tmsec));
nuclear@0 355 }
nuclear@0 356
nuclear@0 357 float Track::operator ()(long tmsec) const
nuclear@0 358 {
nuclear@0 359 return anm_get_value(trk, ANM_MSEC2TM(tmsec));
nuclear@0 360 }
nuclear@0 361
nuclear@0 362
nuclear@0 363 // ---- Track3 ----
nuclear@0 364
nuclear@0 365 void Track3::set_interpolator(Interp in)
nuclear@0 366 {
nuclear@0 367 for(int i=0; i<3; i++) {
nuclear@0 368 track[i].set_interpolator(in);
nuclear@0 369 }
nuclear@0 370 }
nuclear@0 371
nuclear@0 372 Interp Track3::get_interpolator() const
nuclear@0 373 {
nuclear@0 374 return track[0].get_interpolator();
nuclear@0 375 }
nuclear@0 376
nuclear@0 377 void Track3::set_extrapolator(Extrap ex)
nuclear@0 378 {
nuclear@0 379 for(int i=0; i<3; i++) {
nuclear@0 380 track[i].set_extrapolator(ex);
nuclear@0 381 }
nuclear@0 382 }
nuclear@0 383
nuclear@0 384 Extrap Track3::get_extrapolator() const
nuclear@0 385 {
nuclear@0 386 return track[0].get_extrapolator();
nuclear@0 387 }
nuclear@0 388
nuclear@0 389 void Track3::set_default(const Vector3 &def)
nuclear@0 390 {
nuclear@0 391 for(int i=0; i<3; i++) {
nuclear@0 392 track[i].set_default(def[i]);
nuclear@0 393 }
nuclear@0 394 }
nuclear@0 395
nuclear@0 396 void Track3::set_value(const Vector3 &val, long tmsec)
nuclear@0 397 {
nuclear@0 398 for(int i=0; i<3; i++) {
nuclear@0 399 track[i].set_value(val[i], tmsec);
nuclear@0 400 }
nuclear@0 401 }
nuclear@0 402
nuclear@0 403 Vector3 Track3::get_value(long tmsec) const
nuclear@0 404 {
nuclear@0 405 return Vector3(track[0](tmsec), track[1](tmsec), track[2](tmsec));
nuclear@0 406 }
nuclear@0 407
nuclear@0 408 Vector3 Track3::operator ()(long tmsec) const
nuclear@0 409 {
nuclear@0 410 return Vector3(track[0](tmsec), track[1](tmsec), track[2](tmsec));
nuclear@0 411 }
nuclear@0 412
nuclear@0 413
nuclear@0 414 static inline anm_interpolator track_interpolator(Interp in)
nuclear@0 415 {
nuclear@0 416 switch(in) {
nuclear@0 417 case INTERP_STEP:
nuclear@0 418 return ANM_INTERP_STEP;
nuclear@0 419 case INTERP_LINEAR:
nuclear@0 420 return ANM_INTERP_LINEAR;
nuclear@0 421 case INTERP_CUBIC:
nuclear@0 422 return ANM_INTERP_CUBIC;
nuclear@0 423 }
nuclear@0 424
nuclear@0 425 assert(0);
nuclear@0 426 return ANM_INTERP_STEP;
nuclear@0 427 }
nuclear@0 428
nuclear@0 429 static inline anm_extrapolator track_extrapolator(Extrap ex)
nuclear@0 430 {
nuclear@0 431 switch(ex) {
nuclear@0 432 case EXTRAP_EXTEND:
nuclear@0 433 return ANM_EXTRAP_EXTEND;
nuclear@0 434 case EXTRAP_CLAMP:
nuclear@0 435 return ANM_EXTRAP_CLAMP;
nuclear@0 436 case EXTRAP_REPEAT:
nuclear@0 437 return ANM_EXTRAP_REPEAT;
nuclear@0 438 }
nuclear@0 439
nuclear@0 440 assert(0);
nuclear@0 441 return ANM_EXTRAP_EXTEND;
nuclear@0 442 }
nuclear@0 443