/* * Next frame and next anim calculation function. */ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) { float dt; int32_t new_frame; animation_frame_p next_anim = ss_anim->model->animations + ss_anim->next_animation; state_change_p stc = Anim_FindStateChangeByID(next_anim, ss_anim->next_state); ss_anim->frame_time = (ss_anim->frame_time >= 0.0f) ? (ss_anim->frame_time) : (0.0f); ss_anim->frame_time += time; new_frame = ss_anim->frame_time / ss_anim->period; dt = ss_anim->frame_time - (float)new_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; ss_anim->changing_next = 0x00; ss_anim->changing_curr = 0x00; /* * Flag has a highest priority */ if((new_frame + 1 >= next_anim->max_frame) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) { ss_anim->next_frame = next_anim->max_frame - 1; ss_anim->current_frame = ss_anim->next_frame; ss_anim->current_animation = ss_anim->next_animation; ss_anim->lerp = 0.0f; ss_anim->frame_time = (float)ss_anim->next_frame * ss_anim->period; return 0x00; } else if(ss_anim->anim_frame_flags == ANIM_FRAME_LOCK) { ss_anim->current_frame = 0; ss_anim->current_frame = ss_anim->next_frame; ss_anim->current_animation = ss_anim->next_animation; ss_anim->lerp = 0.0f; ss_anim->frame_time = 0.0f; return 0x00; } /* * State change check */ if(stc) { anim_dispatch_p disp = stc->anim_dispatch; for(uint16_t i = 0; i < stc->anim_dispatch_count; i++, disp++) { if((next_anim->max_frame == 1) || (disp->frame_high >= disp->frame_low) && ((new_frame >= disp->frame_low) && (new_frame <= disp->frame_high))) { ss_anim->current_animation = ss_anim->next_animation; ss_anim->current_frame = ss_anim->next_frame; ss_anim->next_animation = disp->next_anim; ss_anim->next_frame = disp->next_frame; ss_anim->frame_time = (float)ss_anim->next_frame * ss_anim->period + dt; ss_anim->current_state = ss_anim->model->animations[ss_anim->next_animation].state_id; ss_anim->next_state = ss_anim->current_state; ss_anim->changing_curr = ss_anim->changing_next; ss_anim->changing_next = 0x03; return 0x03; } } } /* * Check next anim if frame >= max_frame */ if(new_frame >= next_anim->max_frame) { ss_anim->current_animation = ss_anim->next_animation; ss_anim->current_frame = ss_anim->next_frame; ss_anim->next_frame = next_anim->next_frame; ss_anim->next_animation = next_anim->next_anim->id; ss_anim->frame_time = (float)ss_anim->next_frame * ss_anim->period + dt; ss_anim->current_state = ss_anim->model->animations[ss_anim->next_animation].state_id; ss_anim->next_state = ss_anim->current_state; ss_anim->changing_curr = ss_anim->changing_next; ss_anim->changing_next = 0x02; return 0x02; } if(ss_anim->next_frame != new_frame) { ss_anim->current_animation = ss_anim->next_animation; ss_anim->current_frame = ss_anim->next_frame; ss_anim->next_frame = new_frame; ss_anim->changing_curr = ss_anim->changing_next; ss_anim->changing_next = 0x01; return 0x01; } return 0x00; }
/* * Next frame and next anim calculation function. */ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) { float dt; int32_t new_frame; animation_frame_p current_anim = ss_anim->model->animations + ss_anim->current_animation; state_change_p stc = (ss_anim->target_state >= 0) ? (Anim_FindStateChangeByID(current_anim, ss_anim->target_state)) : (NULL); if(ss_anim->heavy_state && (current_anim->state_id == ss_anim->target_state) && (current_anim->next_anim->state_id == ss_anim->target_state)) { ss_anim->heavy_state = 0x00; } ss_anim->frame_time = (ss_anim->frame_time >= 0.0f) ? (ss_anim->frame_time) : (0.0f); ss_anim->frame_time += time; new_frame = ss_anim->frame_time / ss_anim->period; dt = ss_anim->frame_time - (float)new_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; ss_anim->frame_changing_state = 0x00; /* * Flag has a highest priority */ if(ss_anim->anim_frame_flags & ANIM_FRAME_LOCK) { ss_anim->prev_frame = 0; ss_anim->prev_frame = ss_anim->current_frame; ss_anim->prev_animation = ss_anim->current_animation; ss_anim->lerp = 0.0f; ss_anim->frame_time = 0.0f; return 0x00; } else if((new_frame + 1 >= current_anim->max_frame) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) { ss_anim->current_frame = current_anim->max_frame - 1; ss_anim->prev_frame = ss_anim->current_frame; ss_anim->prev_animation = ss_anim->current_animation; ss_anim->lerp = 0.0f; ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period; return 0x00; } /* * State change check */ if(stc) { anim_dispatch_p disp = stc->anim_dispatch; for(uint16_t i = 0; i < stc->anim_dispatch_count; i++, disp++) { if((current_anim->max_frame == 1) || (new_frame >= disp->frame_low) && (new_frame <= disp->frame_high) || (ss_anim->current_frame <= disp->frame_high) && (new_frame >= disp->frame_high)) { ss_anim->prev_animation = ss_anim->current_animation; ss_anim->prev_frame = ss_anim->current_frame; ss_anim->current_animation = disp->next_anim; ss_anim->current_frame = disp->next_frame; BoneFrame_Copy(&ss_anim->prev_bf, &ss_anim->current_bf); BoneFrame_Copy(&ss_anim->current_bf, ss_anim->model->animations[ss_anim->current_animation].frames + ss_anim->current_frame); ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; ss_anim->target_state = ss_anim->heavy_state ? ss_anim->target_state : -1; ss_anim->frame_changing_state = 0x03; return 0x03; } } } if(new_frame >= current_anim->max_frame) { ss_anim->prev_animation = ss_anim->current_animation; ss_anim->prev_frame = ss_anim->current_frame; ss_anim->current_frame = current_anim->next_frame; ss_anim->current_animation = current_anim->next_anim->id; BoneFrame_Copy(&ss_anim->prev_bf, &ss_anim->current_bf); BoneFrame_Copy(&ss_anim->current_bf, ss_anim->model->animations[ss_anim->current_animation].frames + ss_anim->current_frame); ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; ss_anim->target_state = ss_anim->heavy_state ? ss_anim->target_state : -1; ss_anim->frame_changing_state = 0x02; return 0x02; } if(ss_anim->current_frame != new_frame) { ss_anim->prev_animation = ss_anim->current_animation; ss_anim->prev_frame = ss_anim->current_frame; ss_anim->current_frame = new_frame; BoneFrame_Copy(&ss_anim->prev_bf, &ss_anim->current_bf); BoneFrame_Copy(&ss_anim->current_bf, ss_anim->model->animations[ss_anim->current_animation].frames + ss_anim->current_frame); ss_anim->frame_changing_state = 0x01; return 0x01; } return 0x00; }