#include #include #include #include #include "animstate.hpp" static void anim_seq_eval(ANIM_SEQUENCE *seq, float time, ANIM_KEYFRAME *frame) { if(seq->num_frames == 0) { frame->time = 0; frame->x = 0; frame->y = 0; frame->angle = 0; } else if(seq->num_frames == 1) { *frame = seq->frames[0]; } else { //time = max(0.0f, min(1.0f, time / duration)); // TODO: use clamp ANIM_KEYFRAME *frame1 = 0; ANIM_KEYFRAME *frame2 = 0; float blend = 0.0f; // TODO: make this smarter.. binary search for (int i = 1; i < seq->num_frames; i++) { if (seq->frames[i-1].time <= time && seq->frames[i].time >= time) { frame1 = &seq->frames[i-1]; frame2 = &seq->frames[i]; blend = (time - frame1->time) / (frame2->time - frame1->time); break; } } if (frame1 && frame2) { frame->time = time; frame->x = mix(frame1->x, frame2->x, blend); frame->y = mix(frame1->y, frame2->y, blend); frame->angle = mix(frame1->angle, frame2->angle, blend); } } } static void anim_add_keyframe(ANIM_KEYFRAME *seq, ANIM_KEYFRAME *added, float amount) { seq->x += added->x*amount; seq->y += added->y*amount; seq->angle += added->angle*amount; } static void anim_add(ANIMSTATE *state, ANIMSTATE *added, float amount) { anim_add_keyframe(&state->body, &added->body, amount); anim_add_keyframe(&state->back_foot, &added->back_foot, amount); anim_add_keyframe(&state->front_foot, &added->front_foot, amount); anim_add_keyframe(&state->attach, &added->attach, amount); } void ANIMSTATE::set(ANIMATION *anim, float time) { anim_seq_eval(&anim->body, time, &body); anim_seq_eval(&anim->back_foot, time, &back_foot); anim_seq_eval(&anim->front_foot, time, &front_foot); anim_seq_eval(&anim->attach, time, &attach); } void ANIMSTATE::add(ANIMATION *anim, float time, float amount) { ANIMSTATE add; add.set(anim, time); anim_add(this, &add, amount); } ANIMSTATE *ANIMSTATE::get_idle() { static ANIMSTATE state; static bool init = true; if(init) { state.set(&data->animations[ANIM_BASE], 0); state.add(&data->animations[ANIM_IDLE], 0, 1.0f); init = false; } return &state; }