goat3dgfx

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