nuclear@0: #include nuclear@0: #include nuclear@0: #include "xform_node.h" nuclear@0: #include "anim/anim.h" nuclear@0: #include "anim/track.h" nuclear@0: nuclear@15: using namespace goatgfx; nuclear@15: nuclear@0: static inline anm_interpolator track_interpolator(Interp in); nuclear@0: static inline anm_extrapolator track_extrapolator(Extrap ex); nuclear@0: nuclear@0: XFormNode::XFormNode() nuclear@0: { nuclear@0: anm = new anm_node; nuclear@0: anm_init_node(anm); nuclear@22: parent = 0; nuclear@22: nuclear@22: // TODO read them from anm to get the correct initial values nuclear@22: interp = INTERP_LINEAR; nuclear@22: extrap = EXTRAP_EXTEND; nuclear@0: } nuclear@0: nuclear@0: XFormNode::~XFormNode() nuclear@0: { nuclear@0: anm_destroy_node(anm); nuclear@0: delete anm; nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_name(const char *name) nuclear@0: { nuclear@0: anm_set_node_name(anm, name); nuclear@0: } nuclear@0: nuclear@0: const char *XFormNode::get_name() const nuclear@0: { nuclear@0: return anm_get_node_name(anm); nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_interpolator(Interp in) nuclear@0: { nuclear@0: anm_set_interpolator(anm, track_interpolator(in)); nuclear@0: interp = in; nuclear@0: } nuclear@0: nuclear@0: Interp XFormNode::get_interpolator() const nuclear@0: { nuclear@0: return interp; nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_extrapolator(Extrap ex) nuclear@0: { nuclear@0: anm_set_extrapolator(anm, track_extrapolator(ex)); nuclear@0: extrap = ex; nuclear@0: } nuclear@0: nuclear@0: Extrap XFormNode::get_extrapolator() const nuclear@0: { nuclear@0: return extrap; nuclear@0: } nuclear@0: nuclear@22: XFormNode *XFormNode::get_parent() nuclear@22: { nuclear@22: return parent; nuclear@22: } nuclear@22: nuclear@22: const XFormNode *XFormNode::get_parent() const nuclear@22: { nuclear@22: return parent; nuclear@22: } nuclear@22: nuclear@0: void XFormNode::add_child(XFormNode *child) nuclear@0: { nuclear@0: children.push_back(child); nuclear@0: anm_link_node(anm, child->anm); nuclear@22: child->parent = this; nuclear@0: } nuclear@0: nuclear@0: void XFormNode::remove_child(XFormNode *child) nuclear@0: { nuclear@0: std::vector::iterator it; nuclear@0: it = std::find(children.begin(), children.end(), child); nuclear@0: if(it != children.end()) { nuclear@0: children.erase(it); nuclear@0: anm_unlink_node(anm, child->anm); nuclear@22: nuclear@22: if(child->parent == this) { nuclear@22: child->parent = 0; nuclear@22: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: int XFormNode::get_children_count() const nuclear@0: { nuclear@0: return (int)children.size(); nuclear@0: } nuclear@0: nuclear@0: XFormNode *XFormNode::get_child(int idx) nuclear@0: { nuclear@0: if(idx >= 0 && idx < get_children_count()) { nuclear@0: return children[idx]; nuclear@0: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: const XFormNode *XFormNode::get_child(int idx) const nuclear@0: { nuclear@0: if(idx >= 0 && idx < get_children_count()) { nuclear@0: return children[idx]; nuclear@0: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@21: nuclear@21: void XFormNode::use_animation(int idx) nuclear@21: { nuclear@21: if(idx >= 0) { nuclear@21: anm_use_animation(anm, idx); nuclear@21: } nuclear@21: } nuclear@21: nuclear@21: void XFormNode::use_animation(const char *name) nuclear@21: { nuclear@21: anm_use_animation(anm, anm_find_animation(anm, name)); nuclear@21: } nuclear@21: nuclear@21: void XFormNode::use_animation(int aidx, int bidx, float t) nuclear@21: { nuclear@21: anm_use_animations(anm, aidx, bidx, t); nuclear@21: } nuclear@21: nuclear@21: void XFormNode::use_animation(const char *aname, const char *bname, float t) nuclear@21: { nuclear@21: int aidx = anm_find_animation(anm, aname); nuclear@21: int bidx = anm_find_animation(anm, bname); nuclear@21: nuclear@21: if(aidx == -1) { nuclear@21: use_animation(bidx); nuclear@21: } nuclear@21: if(bidx == -1) { nuclear@21: use_animation(aidx); nuclear@21: } nuclear@21: anm_use_animations(anm, aidx, bidx, t); nuclear@21: } nuclear@21: nuclear@21: int XFormNode::get_active_animation_index(int which) const nuclear@21: { nuclear@21: return anm_get_active_animation_index(anm, which); nuclear@21: } nuclear@21: nuclear@21: float XFormNode::get_active_animation_mix() const nuclear@21: { nuclear@21: return anm_get_active_animation_mix(anm); nuclear@21: } nuclear@21: nuclear@21: int XFormNode::get_animation_count() const nuclear@21: { nuclear@21: return anm_get_animation_count(anm); nuclear@21: } nuclear@21: nuclear@21: void XFormNode::add_animation(const char *name) nuclear@21: { nuclear@21: int idx = get_animation_count(); nuclear@21: nuclear@21: anm_add_animation(anm); nuclear@21: use_animation(idx); nuclear@21: nuclear@21: if(name) { nuclear@21: set_animation_name(name); nuclear@21: } nuclear@21: } nuclear@21: nuclear@21: void XFormNode::set_animation_name(const char *name) nuclear@21: { nuclear@21: anm_set_active_animation_name(anm, name); nuclear@21: } nuclear@21: nuclear@21: const char *XFormNode::get_animation_name() const nuclear@21: { nuclear@21: return anm_get_active_animation_name(anm); nuclear@21: } nuclear@21: nuclear@21: nuclear@21: nuclear@0: void XFormNode::set_position(const Vector3 &pos, long tmsec) nuclear@0: { nuclear@0: anm_set_position(anm, v3_cons(pos.x, pos.y, pos.z), ANM_MSEC2TM(tmsec)); nuclear@0: } nuclear@0: nuclear@0: Vector3 XFormNode::get_node_position(long tmsec) const nuclear@0: { nuclear@0: vec3_t p = anm_get_node_position(anm, ANM_MSEC2TM(tmsec)); nuclear@0: return Vector3(p.x, p.y, p.z); nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_rotation(const Quaternion &quat, long tmsec) nuclear@0: { nuclear@0: anm_set_rotation(anm, quat_cons(quat.s, quat.v.x, quat.v.y, quat.v.z), ANM_MSEC2TM(tmsec)); nuclear@0: } nuclear@0: nuclear@0: Quaternion XFormNode::get_node_rotation(long tmsec) const nuclear@0: { nuclear@0: quat_t q = anm_get_node_rotation(anm, ANM_MSEC2TM(tmsec)); nuclear@0: return Quaternion(q.w, q.x, q.y, q.z); nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_scaling(const Vector3 &pos, long tmsec) nuclear@0: { nuclear@0: anm_set_scaling(anm, v3_cons(pos.x, pos.y, pos.z), ANM_MSEC2TM(tmsec)); nuclear@0: } nuclear@0: nuclear@0: Vector3 XFormNode::get_node_scaling(long tmsec) const nuclear@0: { nuclear@0: vec3_t s = anm_get_node_scaling(anm, ANM_MSEC2TM(tmsec)); nuclear@0: return Vector3(s.x, s.y, s.z); nuclear@0: } nuclear@0: nuclear@0: // these take hierarchy into account nuclear@0: Vector3 XFormNode::get_position(long tmsec) const nuclear@0: { nuclear@0: vec3_t v = anm_get_position(anm, ANM_MSEC2TM(tmsec)); nuclear@0: return Vector3(v.x, v.y, v.z); nuclear@0: } nuclear@0: nuclear@0: Quaternion XFormNode::get_rotation(long tmsec) const nuclear@0: { nuclear@0: quat_t q = anm_get_rotation(anm, tmsec); nuclear@0: return Quaternion(q.w, q.x, q.y, q.z); nuclear@0: } nuclear@0: nuclear@0: Vector3 XFormNode::get_scaling(long tmsec) const nuclear@0: { nuclear@0: vec3_t v = anm_get_scaling(anm, ANM_MSEC2TM(tmsec)); nuclear@0: return Vector3(v.x, v.y, v.z); nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_pivot(const Vector3 &pivot) nuclear@0: { nuclear@0: anm_set_pivot(anm, v3_cons(pivot.x, pivot.y, pivot.z)); nuclear@0: } nuclear@0: nuclear@0: Vector3 XFormNode::get_pivot() const nuclear@0: { nuclear@0: vec3_t p = anm_get_pivot(anm); nuclear@0: return Vector3(p.x, p.y, p.z); nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_local_matrix(const Matrix4x4 &mat) nuclear@0: { nuclear@0: local_matrix = mat; nuclear@0: } nuclear@0: nuclear@0: const Matrix4x4 &XFormNode::get_local_matrix() const nuclear@0: { nuclear@0: return local_matrix; nuclear@0: } nuclear@0: nuclear@0: void XFormNode::set_bone_matrix(const Matrix4x4 &bmat) nuclear@0: { nuclear@0: bone_matrix = bmat; nuclear@0: } nuclear@0: nuclear@0: const Matrix4x4 &XFormNode::get_bone_matrix() const nuclear@0: { nuclear@0: return bone_matrix; nuclear@0: } nuclear@0: nuclear@0: #define FOO nuclear@0: nuclear@0: void XFormNode::get_node_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat) const nuclear@0: { nuclear@0: anm_time_t tm = ANM_MSEC2TM(tmsec); nuclear@0: nuclear@0: if(mat) { nuclear@0: anm_get_node_matrix(anm, (scalar_t(*)[4])mat, tm); nuclear@0: #ifdef FOO nuclear@0: *mat = local_matrix * *mat; nuclear@0: #else nuclear@0: *mat = *mat * local_matrix; nuclear@0: #endif nuclear@0: } nuclear@0: if(inv_mat) { nuclear@0: anm_get_inv_matrix(anm, (scalar_t(*)[4])inv_mat, tm); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: void XFormNode::get_xform(long tmsec, Matrix4x4 *mat, Matrix4x4 *inv_mat) const nuclear@0: { nuclear@0: anm_time_t tm = ANM_MSEC2TM(tmsec); nuclear@0: nuclear@0: if(mat) { nuclear@0: anm_get_matrix(anm, (scalar_t(*)[4])mat, tm); nuclear@0: #ifdef FOO nuclear@0: *mat = local_matrix * *mat; nuclear@0: #else nuclear@0: *mat = *mat * local_matrix; nuclear@0: #endif nuclear@0: } nuclear@0: if(inv_mat) { nuclear@0: anm_get_inv_matrix(anm, (scalar_t(*)[4])inv_mat, tm); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: nuclear@0: // ---- Track ---- nuclear@0: nuclear@0: Track::Track() nuclear@0: { nuclear@0: trk = new anm_track; nuclear@0: anm_init_track(trk); nuclear@0: } nuclear@0: nuclear@0: Track::~Track() nuclear@0: { nuclear@0: anm_destroy_track(trk); nuclear@0: delete trk; nuclear@0: } nuclear@0: nuclear@0: Track::Track(const Track &rhs) nuclear@0: { nuclear@0: trk = new anm_track; nuclear@0: anm_init_track(trk); nuclear@0: anm_copy_track(trk, rhs.trk); nuclear@0: interp = rhs.interp; nuclear@0: extrap = rhs.extrap; nuclear@0: } nuclear@0: nuclear@0: Track &Track::operator =(const Track &rhs) nuclear@0: { nuclear@0: if(&rhs == this) { nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: anm_copy_track(trk, rhs.trk); nuclear@0: interp = rhs.interp; nuclear@0: extrap = rhs.extrap; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void Track::set_interpolator(Interp in) nuclear@0: { nuclear@0: anm_set_track_interpolator(trk, track_interpolator(in)); nuclear@0: interp = in; nuclear@0: } nuclear@0: nuclear@0: Interp Track::get_interpolator() const nuclear@0: { nuclear@0: return interp; nuclear@0: } nuclear@0: nuclear@0: void Track::set_extrapolator(Extrap ex) nuclear@0: { nuclear@0: anm_set_track_extrapolator(trk, track_extrapolator(ex)); nuclear@0: extrap = ex; nuclear@0: } nuclear@0: nuclear@0: Extrap Track::get_extrapolator() const nuclear@0: { nuclear@0: return extrap; nuclear@0: } nuclear@0: nuclear@0: void Track::set_default(double def) nuclear@0: { nuclear@0: anm_set_track_default(trk, def); nuclear@0: } nuclear@0: nuclear@0: void Track::set_value(float val, long tmsec) nuclear@0: { nuclear@0: anm_set_value(trk, ANM_MSEC2TM(tmsec), val); nuclear@0: } nuclear@0: nuclear@0: float Track::get_value(long tmsec) const nuclear@0: { nuclear@0: return anm_get_value(trk, ANM_MSEC2TM(tmsec)); nuclear@0: } nuclear@0: nuclear@0: float Track::operator ()(long tmsec) const nuclear@0: { nuclear@0: return anm_get_value(trk, ANM_MSEC2TM(tmsec)); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: // ---- Track3 ---- nuclear@0: nuclear@0: void Track3::set_interpolator(Interp in) nuclear@0: { nuclear@0: for(int i=0; i<3; i++) { nuclear@0: track[i].set_interpolator(in); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: Interp Track3::get_interpolator() const nuclear@0: { nuclear@0: return track[0].get_interpolator(); nuclear@0: } nuclear@0: nuclear@0: void Track3::set_extrapolator(Extrap ex) nuclear@0: { nuclear@0: for(int i=0; i<3; i++) { nuclear@0: track[i].set_extrapolator(ex); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: Extrap Track3::get_extrapolator() const nuclear@0: { nuclear@0: return track[0].get_extrapolator(); nuclear@0: } nuclear@0: nuclear@0: void Track3::set_default(const Vector3 &def) nuclear@0: { nuclear@0: for(int i=0; i<3; i++) { nuclear@0: track[i].set_default(def[i]); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: void Track3::set_value(const Vector3 &val, long tmsec) nuclear@0: { nuclear@0: for(int i=0; i<3; i++) { nuclear@0: track[i].set_value(val[i], tmsec); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: Vector3 Track3::get_value(long tmsec) const nuclear@0: { nuclear@0: return Vector3(track[0](tmsec), track[1](tmsec), track[2](tmsec)); nuclear@0: } nuclear@0: nuclear@0: Vector3 Track3::operator ()(long tmsec) const nuclear@0: { nuclear@0: return Vector3(track[0](tmsec), track[1](tmsec), track[2](tmsec)); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: static inline anm_interpolator track_interpolator(Interp in) nuclear@0: { nuclear@0: switch(in) { nuclear@0: case INTERP_STEP: nuclear@0: return ANM_INTERP_STEP; nuclear@0: case INTERP_LINEAR: nuclear@0: return ANM_INTERP_LINEAR; nuclear@0: case INTERP_CUBIC: nuclear@0: return ANM_INTERP_CUBIC; nuclear@0: } nuclear@0: nuclear@0: assert(0); nuclear@0: return ANM_INTERP_STEP; nuclear@0: } nuclear@0: nuclear@0: static inline anm_extrapolator track_extrapolator(Extrap ex) nuclear@0: { nuclear@0: switch(ex) { nuclear@0: case EXTRAP_EXTEND: nuclear@0: return ANM_EXTRAP_EXTEND; nuclear@0: case EXTRAP_CLAMP: nuclear@0: return ANM_EXTRAP_CLAMP; nuclear@0: case EXTRAP_REPEAT: nuclear@0: return ANM_EXTRAP_REPEAT; nuclear@0: } nuclear@0: nuclear@0: assert(0); nuclear@0: return ANM_EXTRAP_EXTEND; nuclear@0: } nuclear@0: