goat3dgfx

annotate src/xform_node.cc @ 29:9d581abd0bfb

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