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