goat3d

view src/xform_node.cc @ 47:498ca7ac7047

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