From 04f31de4d0e42e557a8f45ded412aa3e0c2c7e49 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Tue, 2 Aug 2016 21:40:51 +0400 Subject: [PATCH 01/24] starting frame system rewriting: compilable only, not playable; --- scripts/autoexec.lua | 12 ++-- src/character_controller.cpp | 134 +++++++++++++++++------------------ src/engine.cpp | 4 +- src/entity.cpp | 38 +++++----- src/game.cpp | 2 +- src/gui.cpp | 6 +- src/resource.cpp | 31 ++++---- src/script.cpp | 55 ++++---------- src/skeletal_model.c | 58 +++++++-------- src/skeletal_model.h | 15 ++-- src/world.cpp | 2 +- 11 files changed, 163 insertions(+), 194 deletions(-) diff --git a/scripts/autoexec.lua b/scripts/autoexec.lua index fce163874..8fbb29a6c 100644 --- a/scripts/autoexec.lua +++ b/scripts/autoexec.lua @@ -238,13 +238,13 @@ setModelCollisionMap(0, 12, 6); setModelCollisionMap(0, 13, 10); -- braces 3 setModelCollisionMap(0, 14, 13); -setAnimCommandTransform(0, 147, 0, 0x00); -- roll animation smooth fix -setAnimCommandTransform(0, 146, -2, 0x03); +--setAnimCommandTransform(0, 147, 0, 0x00); -- roll animation smooth fix +--setAnimCommandTransform(0, 146, -2, 0x03); -if(getLevelVersion() >= TR_II) then - setAnimCommandTransform(0, 205, 1, 0x00); - setAnimCommandTransform(0, 203, -2, 0x03); -end +--if(getLevelVersion() >= TR_II) then +-- setAnimCommandTransform(0, 205, 1, 0x00); +-- setAnimCommandTransform(0, 203, -2, 0x03); +--end -- Generate UV rotation texture animations for waterfalls in TR4+ versions diff --git a/src/character_controller.cpp b/src/character_controller.cpp index a05f180c9..26ee86aaa 100644 --- a/src/character_controller.cpp +++ b/src/character_controller.cpp @@ -2413,9 +2413,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ent->character->cmd.ready_weapon) // ready weapon { ss_anim->current_animation = 2; - ss_anim->next_animation = 2; ss_anim->current_frame = 0; - ss_anim->next_frame = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_HIDE_TO_READY; ent->character->weapon_current_state = WEAPON_STATE_IDLE; @@ -2431,20 +2429,20 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - ss_anim->next_frame = (ss_anim->current_frame + 1) % t; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = (ss_anim->current_frame + 1) % t; + //ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - ss_anim->next_frame = 0; - ss_anim->next_animation = 0; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 0; } else { ss_anim->current_frame = 0; ss_anim->current_animation = 0; - ss_anim->next_frame = 0; - ss_anim->next_animation = 0; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE; } @@ -2453,14 +2451,14 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * case WEAPON_STATE_IDLE: ss_anim->current_frame = 0; ss_anim->current_animation = 0; - ss_anim->next_frame = 0; - ss_anim->next_animation = 0; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 2; - ss_anim->next_animation = 2; - ss_anim->current_frame = ss_anim->next_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; + //ss_anim->next_animation = 2; + //ss_anim->current_frame = ss_anim->next_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; } @@ -2484,13 +2482,13 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = t - 1 - ss_anim->current_frame; if(ss_anim->current_frame > 0) { - ss_anim->next_frame = ss_anim->current_frame - 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame - 1; + //ss_anim->next_animation = ss_anim->current_animation; } else { - ss_anim->next_frame = ss_anim->current_frame = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame = 0; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_IDLE; } break; @@ -2505,7 +2503,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 2; - ss_anim->next_animation = 2; + //ss_anim->next_animation = 2; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; break; @@ -2527,20 +2525,20 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - ss_anim->next_frame = ss_anim->current_frame + 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame + 1; + //ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - ss_anim->next_frame = 0; - ss_anim->next_animation = 3; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 3; } else if(!silent && ent->character->cmd.action) { ss_anim->current_frame = 0; - ss_anim->next_frame = 1; + //ss_anim->next_frame = 1; ss_anim->current_animation = 3; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_FIRE; } else @@ -2567,28 +2565,28 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - ss_anim->next_frame = ss_anim->current_frame + 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame + 1; + //ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - ss_anim->next_frame = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = ss_anim->current_animation; } else { ss_anim->frame_time = dt; ss_anim->current_frame = 0; - ss_anim->next_frame = 1; + //ss_anim->next_frame = 1; } } else { ss_anim->frame_time = 0.0; ss_anim->current_animation = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; - ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); + //ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } break; @@ -2603,13 +2601,13 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = t - 1 - ss_anim->current_frame; if(ss_anim->current_frame > 0) { - ss_anim->next_frame = ss_anim->current_frame - 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame - 1; + //ss_anim->next_animation = ss_anim->current_animation; } else { - ss_anim->next_frame = ss_anim->current_frame = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame = 0; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_HIDE; ent->character->weapon_current_state = WEAPON_STATE_HIDE; Character_SetWeaponModel(ent, ent->character->current_weapon, WEAPON_STATE_HIDE); @@ -2659,9 +2657,9 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ent->character->cmd.ready_weapon) // ready weapon { ss_anim->current_animation = 1; - ss_anim->next_animation = 1; + //ss_anim->next_animation = 1; ss_anim->current_frame = 0; - ss_anim->next_frame = 0; + //ss_anim->next_frame = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_HIDE_TO_READY; ent->character->weapon_current_state = WEAPON_STATE_IDLE; @@ -2677,20 +2675,20 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - ss_anim->next_frame = (ss_anim->current_frame + 1) % t; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = (ss_anim->current_frame + 1) % t; + //ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - ss_anim->next_frame = 0; - ss_anim->next_animation = 0; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 0; } else { ss_anim->current_frame = 0; ss_anim->current_animation = 0; - ss_anim->next_frame = 0; - ss_anim->next_animation = 0; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE; } @@ -2699,14 +2697,14 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * case WEAPON_STATE_IDLE: ss_anim->current_frame = 0; ss_anim->current_animation = 0; - ss_anim->next_frame = 0; - ss_anim->next_animation = 0; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 3; - ss_anim->next_animation = 3; - ss_anim->current_frame = ss_anim->next_frame = 0; + //ss_anim->next_animation = 3; + //ss_anim->current_frame = ss_anim->next_frame = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; } @@ -2730,13 +2728,13 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = t - 1 - ss_anim->current_frame; if(ss_anim->current_frame > 0) { - ss_anim->next_frame = ss_anim->current_frame - 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame - 1; + //ss_anim->next_animation = ss_anim->current_animation; } else { - ss_anim->next_frame = ss_anim->current_frame = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame = 0; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_IDLE; } break; @@ -2751,7 +2749,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 3; - ss_anim->next_animation = 3; + //ss_anim->next_animation = 3; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; break; @@ -2773,20 +2771,20 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - ss_anim->next_frame = ss_anim->current_frame + 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame + 1; + //ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - ss_anim->next_frame = 0; - ss_anim->next_animation = 2; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = 2; } else if(ent->character->cmd.action) { ss_anim->current_frame = 0; - ss_anim->next_frame = 1; + //ss_anim->next_frame = 1; ss_anim->current_animation = 2; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_FIRE; } else @@ -2813,28 +2811,28 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - ss_anim->next_frame = ss_anim->current_frame + 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame + 1; + //ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - ss_anim->next_frame = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = 0; + //ss_anim->next_animation = ss_anim->current_animation; } else { ss_anim->frame_time = dt; ss_anim->current_frame = 0; - ss_anim->next_frame = 1; + //ss_anim->next_frame = 1; } } else { ss_anim->frame_time = 0.0; ss_anim->current_animation = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; - ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); + //ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } break; @@ -2847,13 +2845,13 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->lerp = dt / ss_anim->period; if(ss_anim->current_frame < t - 1) { - ss_anim->next_frame = ss_anim->current_frame + 1; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame + 1; + //ss_anim->next_animation = ss_anim->current_animation; } else { - ss_anim->next_frame = ss_anim->current_frame = 0; - ss_anim->next_animation = ss_anim->current_animation; + //ss_anim->next_frame = ss_anim->current_frame = 0; + //ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_HIDE; ent->character->weapon_current_state = WEAPON_STATE_HIDE; Character_SetWeaponModel(ent, ent->character->current_weapon, WEAPON_STATE_HIDE); diff --git a/src/engine.cpp b/src/engine.cpp index aa9017614..b3d0253ae 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -865,8 +865,8 @@ void ShowDebugInfo() entity_p ent = World_GetPlayer(); if(ent && ent->character) { - GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, next_anim = %03d, curr_st = %03d, next_st = %03d", ent->bf->animations.current_animation, ent->bf->animations.next_animation, ent->bf->animations.current_state, ent->bf->animations.next_state); - GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, next_anim = %03d, curr_frame = %03d, next_frame = %03d", ent->bf->animations.current_animation, ent->bf->animations.next_animation, ent->bf->animations.current_frame, ent->bf->animations.next_frame); + GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_st = %03d, next_st = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_state, ent->bf->animations.next_state); + GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_frame = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_frame); GLText_OutTextXY(30.0f, y += dy, "posX = %f, posY = %f, posZ = %f", ent->transform[12], ent->transform[13], ent->transform[14]); } } diff --git a/src/entity.cpp b/src/entity.cpp index c38131b50..2f9b2e915 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -940,18 +940,17 @@ void Entity_SetAnimation(entity_p entity, int anim_type, int animation, int fram } -void Entity_DoAnimTransformCommand(entity_p entity, int16_t *anim, int16_t *frame) +void Entity_DoAnimTransformCommand(entity_p entity) { if(entity->bf->animations.model != NULL) { animation_frame_p curr_af = entity->bf->animations.model->animations + entity->bf->animations.current_animation; - bone_frame_p curr_bf = curr_af->frames + entity->bf->animations.current_frame; - if(curr_bf->command & ANIM_CMD_JUMP) + if(curr_af->anim_command & ANIM_CMD_JUMP) { - Character_SetToJump(entity, -curr_bf->v_Vertical, curr_bf->v_Horizontal); + Character_SetToJump(entity, -curr_af->v_Vertical, curr_af->v_Horizontal); } - if(curr_bf->command & ANIM_CMD_CHANGE_DIRECTION) + /*if(curr_af->anim_command & ANIM_CMD_CHANGE_DIRECTION) { //Con_Printf("ROTATED: anim = %d, frame = %d of %d", entity->bf->animations.current_animation, entity->bf->animations.current_frame, entity->bf->animations.model->animations[entity->bf->animations.current_animation].frames_count); entity->angles[0] += 180.0f; @@ -967,16 +966,14 @@ void Entity_DoAnimTransformCommand(entity_p entity, int16_t *anim, int16_t *fram { entity->dir_flag = ENT_MOVE_BACKWARD; } - Entity_UpdateTransform(entity); Entity_SetAnimation(entity, ANIM_TYPE_BASE, curr_af->next_anim->id, curr_af->next_frame); - *anim = entity->bf->animations.current_animation; - *frame = entity->bf->animations.current_frame; - } - if(curr_bf->command & ANIM_CMD_MOVE) + Entity_UpdateTransform(entity); + }*/ + if(curr_af->anim_command & ANIM_CMD_MOVE) { float tr[3]; - Mat4_vec3_rot_macro(tr, entity->transform, curr_bf->move); - vec3_add(entity->transform+12, entity->transform+12, tr); + Mat4_vec3_rot_macro(tr, entity->transform, curr_af->move); + vec3_add(entity->transform + 12, entity->transform + 12, tr); } } } @@ -1048,16 +1045,19 @@ void Entity_Frame(entity_p entity, float time) else if(ss_anim->model && !(ss_anim->anim_frame_flags & ANIM_FRAME_LOCK) && ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->frames_count > 1))) { - int16_t new_frame, new_anim; + int16_t new_frame, new_anim, was_last_anim; uint16_t frame_switch_state = 0x00; ss_anim->lerp = 0.0; stc = Anim_FindStateChangeByID(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); - Anim_GetNextFrame(ss_anim, time, stc, &new_frame, &new_anim, ss_anim->anim_frame_flags); + Anim_GetNextFrame(ss_anim, time, stc, &new_frame, &new_anim, &was_last_anim); if(ss_anim->current_animation != new_anim) { frame_switch_state = 0x02; Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); - Entity_DoAnimTransformCommand(entity, &new_anim, &new_frame); + if(was_last_anim) + { + Entity_DoAnimTransformCommand(entity); + } Entity_SetAnimation(entity, ss_anim->type, new_anim, new_frame); stc = Anim_FindStateChangeByID(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); @@ -1066,7 +1066,10 @@ void Entity_Frame(entity_p entity, float time) { frame_switch_state = 0x01; Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); - Entity_DoAnimTransformCommand(entity, &new_anim, &new_frame); + if(was_last_anim) + { + Entity_DoAnimTransformCommand(entity); + } } af = ss_anim->model->animations + ss_anim->current_animation; @@ -1076,7 +1079,7 @@ void Entity_Frame(entity_p entity, float time) dt = ss_anim->frame_time - (float)t * ss_anim->period; ss_anim->frame_time = (float)new_frame * ss_anim->period + dt; ss_anim->lerp = dt / ss_anim->period; - Anim_GetNextFrame(ss_anim, ss_anim->period, stc, &ss_anim->next_frame, &ss_anim->next_animation, ss_anim->anim_frame_flags); + //Anim_GetNextFrame(ss_anim, ss_anim->period, stc, &ss_anim->next_frame, &ss_anim->next_animation, &was_last_anim); // Update acceleration. // With variable framerate, we don't know when we'll reach final @@ -1096,7 +1099,6 @@ void Entity_Frame(entity_p entity, float time) } ss_anim->current_frame = new_frame; - if(ss_anim->onEndFrame != NULL) { ss_anim->onEndFrame(entity, ss_anim, frame_switch_state); diff --git a/src/game.cpp b/src/game.cpp index 91094a05b..3a62abbc4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -283,7 +283,7 @@ void Save_Entity(FILE **f, entity_p ent) for(ss_anim = &ent->bf->animations; ss_anim; ss_anim = ss_anim->next) { - fprintf(*f, "\nsetEntityAnim(%d, %d, %d, %d, %d, %d);", ent->id, ss_anim->type, ss_anim->current_animation, ss_anim->current_frame, ss_anim->next_animation, ss_anim->next_frame); + fprintf(*f, "\nsetEntityAnim(%d, %d, %d, %d, %d, %d);", ent->id, ss_anim->type, ss_anim->current_animation, ss_anim->current_frame); fprintf(*f, "\nsetEntityAnimState(%d, %d, %d, %d);", ent->id, ss_anim->type, ss_anim->next_state, ss_anim->current_state); fprintf(*f, "\nentitySSAnimSetTarget(%d, %d, %d, %.2f, %.2f, %.2f, %.6f, %.6f, %.6f);", ent->id, ss_anim->type, ss_anim->targeting_bone, ss_anim->target[0], ss_anim->target[1], ss_anim->target[2], diff --git a/src/gui.cpp b/src/gui.cpp index 4792551f7..7128f9c77 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -271,14 +271,14 @@ void Gui_Render() */ void Item_Frame(struct ss_bone_frame_s *bf, float time) { - int16_t frame, anim; + int16_t frame, anim, was_last_anim; long int t; float dt; state_change_p stc; bf->animations.lerp = 0.0; stc = Anim_FindStateChangeByID(bf->animations.model->animations + bf->animations.current_animation, bf->animations.next_state); - Anim_GetNextFrame(&bf->animations, time, stc, &frame, &anim, 0x00); + Anim_GetNextFrame(&bf->animations, time, stc, &frame, &anim, &was_last_anim); if(anim != bf->animations.current_animation) { /*frame %= bf->model->animations[anim].frames_count; @@ -303,7 +303,7 @@ void Item_Frame(struct ss_bone_frame_s *bf, float time) dt = bf->animations.frame_time - (float)t * bf->animations.period; bf->animations.frame_time = (float)frame * bf->animations.period + dt; bf->animations.lerp = dt / bf->animations.period; - Anim_GetNextFrame(&bf->animations, bf->animations.period, stc, &bf->animations.next_frame, &bf->animations.next_animation, 0x00); + //Anim_GetNextFrame(&bf->animations, bf->animations.period, stc, &bf->animations.next_frame, &bf->animations.next_animation, &was_last_anim); SSBoneFrame_Update(bf, time); } diff --git a/src/resource.cpp b/src/resource.cpp index cf8e3d8e3..9ba951fb5 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1174,17 +1174,17 @@ void GenerateAnimCommandsTransform(skeletal_model_p model, int16_t *base_anim_co { case TR_ANIMCOMMAND_SETPOSITION: // This command executes ONLY at the end of animation. - af->frames[af->frames_count-1].move[0] = (float)(*++pointer); // x = x; - af->frames[af->frames_count-1].move[2] =-(float)(*++pointer); // z =-y - af->frames[af->frames_count-1].move[1] = (float)(*++pointer); // y = z - af->frames[af->frames_count-1].command |= ANIM_CMD_MOVE; + af->move[0] = (float)(*++pointer); // x = x; + af->move[2] =-(float)(*++pointer); // z =-y + af->move[1] = (float)(*++pointer); // y = z + af->command_flags |= ANIM_CMD_MOVE; //Sys_DebugLog("anim_transform.txt", "move[anim = %d, frame = %d, frames = %d]", anim, af->frames_count-1, af->frames_count); break; case TR_ANIMCOMMAND_JUMPDISTANCE: - af->frames[af->frames_count-1].v_Vertical = *++pointer; - af->frames[af->frames_count-1].v_Horizontal = *++pointer; - af->frames[af->frames_count-1].command |= ANIM_CMD_JUMP; + af->v_Vertical = *++pointer; + af->v_Horizontal = *++pointer; + af->command_flags |= ANIM_CMD_JUMP; break; case TR_ANIMCOMMAND_EMPTYHANDS: @@ -1204,7 +1204,7 @@ void GenerateAnimCommandsTransform(skeletal_model_p model, int16_t *base_anim_co switch(*++pointer & 0x3FFF) { case TR_EFFECT_CHANGEDIRECTION: - af->frames[frame].command |= ANIM_CMD_CHANGE_DIRECTION; + af->command_flags |= ANIM_CMD_CHANGE_DIRECTION; //Con_Printf("ROTATE: anim = %d, frame = %d of %d", anim, frame, af->frames_count); //Sys_DebugLog("anim_transform.txt", "dir[anim = %d, frame = %d, frames = %d]", anim, frame, af->frames_count); break; @@ -1705,15 +1705,15 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct model->animations->state_change = NULL; model->animations->state_change_count = 0; model->animations->original_frame_rate = 1; + model->animations->command_flags = 0x0000; + vec3_set_zero(model->animations->move); + model->animations->v_Horizontal = 0.0; + model->animations->v_Vertical = 0.0; bone_frame->bone_tag_count = model->mesh_count; bone_frame->bone_tags = (bone_tag_p)malloc(bone_frame->bone_tag_count * sizeof(bone_tag_t)); - vec3_set_zero(bone_frame->pos); - vec3_set_zero(bone_frame->move); - bone_frame->v_Horizontal = 0.0; - bone_frame->v_Vertical = 0.0; - bone_frame->command = 0x00; + for(uint16_t k = 0; k < bone_frame->bone_tag_count; k++) { tree_tag = model->mesh_tree + k; @@ -1761,11 +1761,15 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim->id = i; anim->original_frame_rate = tr_animation->frame_rate; + anim->command_flags = 0x0000; anim->speed_x = tr_animation->speed; anim->accel_x = tr_animation->accel; anim->speed_y = tr_animation->accel_lateral; anim->accel_y = tr_animation->speed_lateral; + vec3_set_zero(anim->move); + anim->v_Horizontal = 0.0f; + anim->v_Vertical = 0.0f; anim->anim_command = tr_animation->anim_command; anim->num_anim_commands = tr_animation->num_anim_commands; @@ -1832,7 +1836,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct bone_frame->bone_tag_count = model->mesh_count; bone_frame->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t)); vec3_set_zero(bone_frame->pos); - vec3_set_zero(bone_frame->move); TR_GetBFrameBB_Pos(tr, frame_offset, bone_frame); if(frame_offset >= tr->frame_data_size) diff --git a/src/script.cpp b/src/script.cpp index 0e6c0bc7a..3ad05f307 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -2204,15 +2204,14 @@ int lua_SetStateChangeRange(lua_State * lua) int lua_GetAnimCommandTransform(lua_State * lua) { - if(lua_gettop(lua) < 3) + if(lua_gettop(lua) < 2) { - Con_Warning("getAnimCommandTransform: expecting arguments (model_id, anim_num, frame_num)"); + Con_Warning("getAnimCommandTransform: expecting arguments (model_id, anim_num)"); return 0; } int id = lua_tointeger(lua, 1); int anim = lua_tointeger(lua, 2); - int frame = lua_tointeger(lua, 3); skeletal_model_p model = World_GetModelByID(id); if(model == NULL) { @@ -2226,21 +2225,10 @@ int lua_GetAnimCommandTransform(lua_State * lua) return 0; } - if(frame < 0) // it is convenient to use -1 as a last frame number - { - frame = (int)model->animations[anim].frames_count + frame; - } - - if((frame < 0) || (frame + 1 > model->animations[anim].frames_count)) - { - Con_Warning("wrong anim frame number = %d", frame); - return 0; - } - - lua_pushinteger(lua, model->animations[anim].frames[frame].command); - lua_pushnumber(lua, model->animations[anim].frames[frame].move[0]); - lua_pushnumber(lua, model->animations[anim].frames[frame].move[1]); - lua_pushnumber(lua, model->animations[anim].frames[frame].move[2]); + lua_pushinteger(lua, model->animations[anim].anim_command); + lua_pushnumber(lua, model->animations[anim].move[0]); + lua_pushnumber(lua, model->animations[anim].move[1]); + lua_pushnumber(lua, model->animations[anim].move[2]); return 4; } @@ -2250,15 +2238,14 @@ int lua_SetAnimCommandTransform(lua_State * lua) { int top = lua_gettop(lua); - if(top < 4) + if(top < 3) { - Con_Warning("setAnimCommandTransform: expecting arguments (model_id, anim_num, frame_num, flag, (dx, dy, dz))"); + Con_Warning("setAnimCommandTransform: expecting arguments (model_id, anim_num, flag, (dx, dy, dz))"); return 0; } int id = lua_tointeger(lua, 1); int anim = lua_tointeger(lua, 2); - int frame = lua_tointeger(lua, 3); skeletal_model_p model = World_GetModelByID(id); if(model == NULL) { @@ -2272,23 +2259,12 @@ int lua_SetAnimCommandTransform(lua_State * lua) return 0; } - if(frame < 0) // it is convenient to use -1 as a last frame number - { - frame = (int)model->animations[anim].frames_count + frame; - } - - if((frame < 0) || (frame + 1 > model->animations[anim].frames_count)) - { - Con_Warning("wrong frame number = %d", frame); - return 0; - } - - model->animations[anim].frames[frame].command = 0x00ff & lua_tointeger(lua, 4); + model->animations[anim].anim_command = 0x00ff & lua_tointeger(lua, 4); if(top >= 7) { - model->animations[anim].frames[frame].move[0] = lua_tonumber(lua, 5); - model->animations[anim].frames[frame].move[1] = lua_tonumber(lua, 6); - model->animations[anim].frames[frame].move[2] = lua_tonumber(lua, 7); + model->animations[anim].move[0] = lua_tonumber(lua, 5); + model->animations[anim].move[1] = lua_tonumber(lua, 6); + model->animations[anim].move[2] = lua_tonumber(lua, 7); } return 0; @@ -3100,7 +3076,7 @@ int lua_SetEntityAnim(lua_State * lua) if(top < 4) { - Con_Warning("setEntityAnim: expecting arguments (entity_id, anim_type_id, anim_num, frame_number, (next_anim_num, next_frame_num))"); + Con_Warning("setEntityAnim: expecting arguments (entity_id, anim_type_id, anim_num, frame_number)"); return 0; } @@ -3118,11 +3094,6 @@ int lua_SetEntityAnim(lua_State * lua) if(ss_anim) { SSBoneFrame_SetAnimation(ent->bf, anim_type_id, lua_tointeger(lua, 3), lua_tointeger(lua, 4)); - if(top >= 6) - { - ss_anim->next_animation = lua_tointeger(lua, 5); - ss_anim->next_frame = lua_tointeger(lua, 6); - } } return 0; diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 88d2d94e3..35ddc7fd0 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -122,8 +122,6 @@ void SkeletalModel_InterpolateFrames(skeletal_model_p model) bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t)); bf->bone_tag_count = model->mesh_count; vec3_set_zero(bf->pos); - vec3_set_zero(bf->move); - bf->command = 0x00; vec3_copy(bf->centre, anim->frames[0].centre); vec3_copy(bf->pos, anim->frames[0].pos); vec3_copy(bf->bb_max, anim->frames[0].bb_max); @@ -140,10 +138,8 @@ void SkeletalModel_InterpolateFrames(skeletal_model_p model) for(uint16_t lerp_index = 1; lerp_index <= anim->original_frame_rate; lerp_index++) { vec3_set_zero(bf->pos); - vec3_set_zero(bf->move); - bf->command = 0x00; lerp = ((float)lerp_index) / (float)anim->original_frame_rate; - t = 1.0 - lerp; + t = 1.0f - lerp; bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t)); bf->bone_tag_count = model->mesh_count; @@ -292,9 +288,6 @@ void BoneFrame_Copy(bone_frame_p dst, bone_frame_p src) vec3_copy(dst->bb_max, src->bb_max); vec3_copy(dst->bb_min, src->bb_min); - dst->command = src->command; - vec3_copy(dst->move, src->move); - for(uint16_t i = 0; i < dst->bone_tag_count; i++) { vec4_copy(dst->bone_tags[i].qrotate, src->bone_tags[i].qrotate); @@ -370,8 +363,6 @@ void SSBoneFrame_InitSSAnim(struct ss_animation_s *ss_anim, uint32_t anim_type_i ss_anim->lerp = 0.0; ss_anim->current_animation = 0; ss_anim->current_frame = 0; - ss_anim->next_animation = 0; - ss_anim->next_frame = 0; ss_anim->period = 1.0f / 30.0f; ss_anim->next = NULL; @@ -401,34 +392,30 @@ void SSBoneFrame_Clear(ss_bone_frame_p bf) void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) { - float cmd_local_move[3], t; + float t; ss_bone_tag_p btag = bf->bone_tags; bone_tag_p src_btag, next_btag; skeletal_model_p model = bf->animations.model; bone_frame_p curr_bf, next_bf; - next_bf = model->animations[bf->animations.next_animation].frames + bf->animations.next_frame; curr_bf = model->animations[bf->animations.current_animation].frames + bf->animations.current_frame; - - t = 1.0f - bf->animations.lerp; - if(curr_bf->command & ANIM_CMD_MOVE) + next_bf = curr_bf; + if(bf->animations.current_frame + 1 < model->animations[bf->animations.current_animation].frames_count) { - vec3_mul_scalar(cmd_local_move, curr_bf->move, bf->animations.lerp); + next_bf++; } else { - vec3_set_zero(cmd_local_move); + bf->animations.lerp = 0.0f; } + + t = 1.0f - bf->animations.lerp; vec3_interpolate_macro(bf->bb_max, curr_bf->bb_max, next_bf->bb_max, bf->animations.lerp, t); - vec3_add(bf->bb_max, bf->bb_max, cmd_local_move); vec3_interpolate_macro(bf->bb_min, curr_bf->bb_min, next_bf->bb_min, bf->animations.lerp, t); - vec3_add(bf->bb_min, bf->bb_min, cmd_local_move); vec3_interpolate_macro(bf->centre, curr_bf->centre, next_bf->centre, bf->animations.lerp, t); - vec3_add(bf->centre, bf->centre, cmd_local_move); - vec3_interpolate_macro(bf->pos, curr_bf->pos, next_bf->pos, bf->animations.lerp, t); - vec3_add(bf->pos, bf->pos, cmd_local_move); + next_btag = next_bf->bone_tags; src_btag = curr_bf->bone_tags; for(uint16_t k = 0; k < curr_bf->bone_tag_count; k++, btag++, src_btag++, next_btag++) @@ -449,7 +436,15 @@ void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) if(btag->alt_anim && btag->alt_anim->model && btag->alt_anim->enabled && (btag->alt_anim->model->mesh_tree[k].replace_anim != 0)) { bone_frame_p ov_curr_bf = btag->alt_anim->model->animations[btag->alt_anim->current_animation].frames + btag->alt_anim->current_frame; - bone_frame_p ov_next_bf = btag->alt_anim->model->animations[btag->alt_anim->next_animation].frames + btag->alt_anim->next_frame; + bone_frame_p ov_next_bf = ov_curr_bf; + if(btag->alt_anim->current_frame + 1 < btag->alt_anim->model->animations[btag->alt_anim->current_animation].frames_count) + { + ov_next_bf++; + } + else + { + btag->alt_anim->lerp = 0.0f; + } ov_src_btag = ov_curr_bf->bone_tags + k; ov_next_btag = ov_next_bf->bone_tags + k; ov_lerp = btag->alt_anim->lerp; @@ -647,8 +642,6 @@ void SSBoneFrame_SetAnimation(struct ss_bone_frame_s *bf, int anim_type, int ani ss_anim->current_animation = animation; ss_anim->current_frame = frame; - ss_anim->next_animation = animation; - ss_anim->next_frame = frame; ss_anim->frame_time = (float)frame * ss_anim->period; //long int t = (ss_anim->frame_time) / ss_anim->period; @@ -815,27 +808,29 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) /* * Next frame and next anim calculation function. */ -void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc, int16_t *frame, int16_t *anim, uint16_t anim_flags) +void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc, int16_t *frame, int16_t *anim, int16_t *was_last_anim) { animation_frame_p curr_anim = ss_anim->model->animations + ss_anim->current_animation; *frame = (ss_anim->frame_time + time) / ss_anim->period; *frame = (*frame >= 0.0) ? (*frame) : (0.0); // paranoid checking *anim = ss_anim->current_animation; - + *was_last_anim = 0; + /* * Flag has a highest priority */ - if(anim_flags == ANIM_LOOP_LAST_FRAME) + if(ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME) { - if(*frame >= curr_anim->frames_count - 1) + if(*frame + 2 >= curr_anim->frames_count) { + //*was_last_anim = 1; *frame = curr_anim->frames_count - 1; *anim = ss_anim->current_animation; // paranoid dublicate } return; } - else if(anim_flags == ANIM_FRAME_LOCK) + else if(ss_anim->anim_frame_flags == ANIM_FRAME_LOCK) { *frame = 0; *anim = ss_anim->current_animation; @@ -862,10 +857,11 @@ void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ /* * Check next anim if frame >= frames_count */ - if(*frame >= curr_anim->frames_count) + if(*frame >= curr_anim->frames_count - 1) { if(curr_anim->next_anim) { + *was_last_anim = 1; *frame = curr_anim->next_frame; *anim = curr_anim->next_anim->id; return; diff --git a/src/skeletal_model.h b/src/skeletal_model.h index d2f8be35d..477c1f3be 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -73,9 +73,7 @@ typedef struct ss_animation_s int16_t current_state; int16_t next_state; int16_t current_animation; // - int16_t next_animation; // int16_t current_frame; // - int16_t next_frame; // uint16_t anim_frame_flags; // base animation control flags uint16_t anim_ext_flags; // additional animation control flags @@ -130,15 +128,12 @@ typedef struct bone_tag_s typedef struct bone_frame_s { uint16_t bone_tag_count; // number of bones - uint16_t command; // & 0x01 - move need, &0x02 - 180 rotate need + uint16_t unused; struct bone_tag_s *bone_tags; // bones data float pos[3]; // position (base offset) float bb_min[3]; // bounding box min coordinates float bb_max[3]; // bounding box max coordinates float centre[3]; // bounding box centre - float move[3]; // move command data - float v_Vertical; // jump command data - float v_Horizontal; // jump command data }bone_frame_t, *bone_frame_p ; /* @@ -180,11 +175,15 @@ typedef struct state_change_s typedef struct animation_frame_s { uint32_t id; - uint8_t original_frame_rate; + uint16_t original_frame_rate; + uint16_t command_flags; // & 0x01 - move need, &0x02 - 180 rotate need float speed_x; // Forward-backward speed float accel_x; // Forward-backward accel float speed_y; // Left-right speed float accel_y; // Left-right accel + float move[3]; // move command data + float v_Vertical; // jump command data + float v_Horizontal; // jump command data uint32_t anim_command; uint32_t num_anim_commands; uint16_t state_id; @@ -249,7 +248,7 @@ void SSBoneFrame_DisableOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_t struct state_change_s *Anim_FindStateChangeByAnim(struct animation_frame_s *anim, int state_change_anim); struct state_change_s *Anim_FindStateChangeByID(struct animation_frame_s *anim, uint32_t id); int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id); -void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc, int16_t *frame, int16_t *anim, uint16_t anim_flags); +void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc, int16_t *frame, int16_t *anim, int16_t *was_last_anim); #ifdef __cplusplus } diff --git a/src/world.cpp b/src/world.cpp index 07131f315..1fdc48218 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -2209,7 +2209,7 @@ void World_GenRoom(struct room_s *room, class VT_Level *tr) */ room->alternate_room = NULL; room->base_room = NULL; - // condition vas commented because heavy glitches in TR3+ + // condition was commented because heavy glitches in TR3+ if((tr_room->alternate_room >= 0) && ((uint32_t)tr_room->alternate_room < tr->rooms_count) /*&& (room->id < tr_room->alternate_room)*/) { room->alternate_room = global_world.rooms + tr_room->alternate_room; From f3dd72cfcc87dc1e5e28e4d2ac8323fafe65c209 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Thu, 4 Aug 2016 23:10:43 +0400 Subject: [PATCH 02/24] Anim_GetNextFrame was replaced by Anim_SetNextFrame function (and all internal logick too); still not playable; anim command system should be rewritten (+anim move interpolation); --- src/engine.cpp | 3 +- src/entity.cpp | 49 ++++-------------- src/gui.cpp | 34 +------------ src/resource.cpp | 6 ++- src/skeletal_model.c | 118 ++++++++++++++++++++++++++----------------- src/skeletal_model.h | 12 +++-- 6 files changed, 96 insertions(+), 126 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index b3d0253ae..4f48a1701 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -865,7 +865,8 @@ void ShowDebugInfo() entity_p ent = World_GetPlayer(); if(ent && ent->character) { - GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_st = %03d, next_st = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_state, ent->bf->animations.next_state); + animation_frame_p anim = ent->bf->animations.model->animations + ent->bf->animations.current_animation; + GLText_OutTextXY(30.0f, y += dy, "curr_st = %03d, next_st = %03d", ent->bf->animations.current_state, ent->bf->animations.next_state); GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_frame = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_frame); GLText_OutTextXY(30.0f, y += dy, "posX = %f, posY = %f, posZ = %f", ent->transform[12], ent->transform[13], ent->transform[14]); } diff --git a/src/entity.cpp b/src/entity.cpp index 2f9b2e915..02ed07fce 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -1022,10 +1022,7 @@ void Entity_Frame(entity_p entity, float time) { if(entity && !(entity->type_flags & ENTITY_TYPE_DYNAMIC) && (entity->state_flags & ENTITY_STATE_ACTIVE) && (entity->state_flags & ENTITY_STATE_ENABLED)) { - long int t; - float dt; animation_frame_p af; - state_change_p stc; ss_animation_p ss_anim = &entity->bf->animations; Entity_GhostUpdate(entity); @@ -1045,50 +1042,23 @@ void Entity_Frame(entity_p entity, float time) else if(ss_anim->model && !(ss_anim->anim_frame_flags & ANIM_FRAME_LOCK) && ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->frames_count > 1))) { - int16_t new_frame, new_anim, was_last_anim; - uint16_t frame_switch_state = 0x00; - ss_anim->lerp = 0.0; - stc = Anim_FindStateChangeByID(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); - Anim_GetNextFrame(ss_anim, time, stc, &new_frame, &new_anim, &was_last_anim); - if(ss_anim->current_animation != new_anim) + state_change_p stc = Anim_FindStateChangeByID(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); + uint16_t frame_switch_state = Anim_SetNextFrame(ss_anim, time, stc); + if(frame_switch_state > 0) { - frame_switch_state = 0x02; - Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); - if(was_last_anim) - { - Entity_DoAnimTransformCommand(entity); - } - - Entity_SetAnimation(entity, ss_anim->type, new_anim, new_frame); - stc = Anim_FindStateChangeByID(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); - } - else if(ss_anim->current_frame != new_frame) - { - frame_switch_state = 0x01; - Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); - if(was_last_anim) - { - Entity_DoAnimTransformCommand(entity); - } + entity->no_fix_all = 0x00; + //Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); + //Entity_DoAnimTransformCommand(entity); } - af = ss_anim->model->animations + ss_anim->current_animation; - ss_anim->frame_time += time; - - t = (ss_anim->frame_time) / ss_anim->period; - dt = ss_anim->frame_time - (float)t * ss_anim->period; - ss_anim->frame_time = (float)new_frame * ss_anim->period + dt; - ss_anim->lerp = dt / ss_anim->period; - //Anim_GetNextFrame(ss_anim, ss_anim->period, stc, &ss_anim->next_frame, &ss_anim->next_animation, &was_last_anim); - // Update acceleration. // With variable framerate, we don't know when we'll reach final // frame for sure, so we use native frame number check to increase acceleration. - - if((ss_anim->type == ANIM_TYPE_BASE) && (entity->character) && (ss_anim->current_frame != new_frame)) + af = ss_anim->model->animations + ss_anim->current_animation; + if((ss_anim->type == ANIM_TYPE_BASE) && (entity->character) && (frame_switch_state > 0)) { // NB!!! For Lara, we update ONLY X-axis speed/accel. - if((af->accel_x == 0) || (new_frame < ss_anim->current_frame)) + if((af->accel_x == 0) || (frame_switch_state > 1)) { entity->anim_linear_speed = af->speed_x; } @@ -1098,7 +1068,6 @@ void Entity_Frame(entity_p entity, float time) } } - ss_anim->current_frame = new_frame; if(ss_anim->onEndFrame != NULL) { ss_anim->onEndFrame(entity, ss_anim, frame_switch_state); diff --git a/src/gui.cpp b/src/gui.cpp index 7128f9c77..098b3d1b2 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -271,38 +271,8 @@ void Gui_Render() */ void Item_Frame(struct ss_bone_frame_s *bf, float time) { - int16_t frame, anim, was_last_anim; - long int t; - float dt; - state_change_p stc; - - bf->animations.lerp = 0.0; - stc = Anim_FindStateChangeByID(bf->animations.model->animations + bf->animations.current_animation, bf->animations.next_state); - Anim_GetNextFrame(&bf->animations, time, stc, &frame, &anim, &was_last_anim); - if(anim != bf->animations.current_animation) - { - /*frame %= bf->model->animations[anim].frames_count; - frame = (frame >= 0)?(frame):(bf->model->animations[anim].frames_count - 1 + frame); - - bf->last_state = bf->model->animations[anim].state_id; - bf->next_state = bf->model->animations[anim].state_id; - bf->current_animation = anim; - bf->current_frame = frame; - bf->next_animation = anim; - bf->next_frame = frame;*/ - stc = Anim_FindStateChangeByID(bf->animations.model->animations + bf->animations.current_animation, bf->animations.next_state); - } - else if(bf->animations.current_frame != frame) - { - bf->animations.current_frame = frame; - } - - bf->animations.frame_time += time; - - t = (bf->animations.frame_time) / bf->animations.period; - dt = bf->animations.frame_time - (float)t * bf->animations.period; - bf->animations.frame_time = (float)frame * bf->animations.period + dt; - bf->animations.lerp = dt / bf->animations.period; + state_change_p stc = Anim_FindStateChangeByID(bf->animations.model->animations + bf->animations.current_animation, bf->animations.next_state); + int frame_switch_state = Anim_SetNextFrame(&bf->animations, time, stc); //Anim_GetNextFrame(&bf->animations, bf->animations.period, stc, &bf->animations.next_frame, &bf->animations.next_animation, &was_last_anim); SSBoneFrame_Update(bf, time); } diff --git a/src/resource.cpp b/src/resource.cpp index 9ba951fb5..9c1fb524c 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1200,7 +1200,7 @@ void GenerateAnimCommandsTransform(skeletal_model_p model, int16_t *base_anim_co case TR_ANIMCOMMAND_PLAYEFFECT: { - int frame = *++pointer; + af->condition_frame = *++pointer; switch(*++pointer & 0x3FFF) { case TR_EFFECT_CHANGEDIRECTION: @@ -1706,6 +1706,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct model->animations->state_change_count = 0; model->animations->original_frame_rate = 1; model->animations->command_flags = 0x0000; + model->animations->condition_frame = 0xFFFF; vec3_set_zero(model->animations->move); model->animations->v_Horizontal = 0.0; model->animations->v_Vertical = 0.0; @@ -1762,6 +1763,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim->id = i; anim->original_frame_rate = tr_animation->frame_rate; anim->command_flags = 0x0000; + anim->condition_frame = 0xFFFF; anim->speed_x = tr_animation->speed; anim->accel_x = tr_animation->accel; @@ -1959,7 +1961,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim->state_change_count = 0; anim->state_change = NULL; - tr_animation = &tr->animations[tr_moveable->animation_index+i]; + tr_animation = &tr->animations[tr_moveable->animation_index + i]; int16_t j = tr_animation->next_animation - tr_moveable->animation_index; j &= 0x7fff; if((j >= 0) && (j < model->animation_count)) diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 35ddc7fd0..d1b36a1f9 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -397,18 +397,22 @@ void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) bone_tag_p src_btag, next_btag; skeletal_model_p model = bf->animations.model; bone_frame_p curr_bf, next_bf; - - curr_bf = model->animations[bf->animations.current_animation].frames + bf->animations.current_frame; - next_bf = curr_bf; - if(bf->animations.current_frame + 1 < model->animations[bf->animations.current_animation].frames_count) + animation_frame_p curr_anim = model->animations + bf->animations.current_animation; + + curr_bf = curr_anim->frames + bf->animations.current_frame; + if(bf->animations.current_frame + 1 < curr_anim->frames_count) + { + next_bf = curr_bf + 1; + } + else if(curr_anim->next_anim) { - next_bf++; + next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; } else { + next_bf = curr_bf; bf->animations.lerp = 0.0f; } - t = 1.0f - bf->animations.lerp; vec3_interpolate_macro(bf->bb_max, curr_bf->bb_max, next_bf->bb_max, bf->animations.lerp, t); @@ -421,11 +425,11 @@ void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) for(uint16_t k = 0; k < curr_bf->bone_tag_count; k++, btag++, src_btag++, next_btag++) { vec3_interpolate_macro(btag->offset, src_btag->offset, next_btag->offset, bf->animations.lerp, t); - vec3_copy(btag->transform+12, btag->offset); + vec3_copy(btag->transform + 12, btag->offset); btag->transform[15] = 1.0f; if(k == 0) { - vec3_add(btag->transform+12, btag->transform+12, bf->pos); + vec3_add(btag->transform + 12, btag->transform + 12, bf->pos); vec4_slerp(btag->qrotate, src_btag->qrotate, next_btag->qrotate, bf->animations.lerp); } else @@ -435,19 +439,25 @@ void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) float ov_lerp = bf->animations.lerp; if(btag->alt_anim && btag->alt_anim->model && btag->alt_anim->enabled && (btag->alt_anim->model->mesh_tree[k].replace_anim != 0)) { - bone_frame_p ov_curr_bf = btag->alt_anim->model->animations[btag->alt_anim->current_animation].frames + btag->alt_anim->current_frame; - bone_frame_p ov_next_bf = ov_curr_bf; - if(btag->alt_anim->current_frame + 1 < btag->alt_anim->model->animations[btag->alt_anim->current_animation].frames_count) + curr_anim = btag->alt_anim->model->animations + btag->alt_anim->current_animation; + bone_frame_p ov_curr_bf = curr_anim->frames + btag->alt_anim->current_frame; + bone_frame_p ov_next_bf; + ov_lerp = btag->alt_anim->lerp; + if(btag->alt_anim->current_frame + 1 < curr_anim->frames_count) { - ov_next_bf++; + ov_next_bf = ov_curr_bf + 1; + } + else if(curr_anim->next_anim) + { + ov_next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; } else { - btag->alt_anim->lerp = 0.0f; + ov_next_bf = ov_curr_bf; + ov_lerp = 0.0f; } ov_src_btag = ov_curr_bf->bone_tags + k; ov_next_btag = ov_next_bf->bone_tags + k; - ov_lerp = btag->alt_anim->lerp; } vec4_slerp(btag->qrotate, ov_src_btag->qrotate, ov_next_btag->qrotate, ov_lerp); } @@ -808,33 +818,34 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) /* * Next frame and next anim calculation function. */ -void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc, int16_t *frame, int16_t *anim, int16_t *was_last_anim) +int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc) { + float dt; + int32_t new_frame; animation_frame_p curr_anim = ss_anim->model->animations + ss_anim->current_animation; - - *frame = (ss_anim->frame_time + time) / ss_anim->period; - *frame = (*frame >= 0.0) ? (*frame) : (0.0); // paranoid checking - *anim = ss_anim->current_animation; - *was_last_anim = 0; + + 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; /* * Flag has a highest priority */ - if(ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME) + if((new_frame + 1 >= curr_anim->frames_count) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) { - if(*frame + 2 >= curr_anim->frames_count) - { - //*was_last_anim = 1; - *frame = curr_anim->frames_count - 1; - *anim = ss_anim->current_animation; // paranoid dublicate - } - return; + ss_anim->current_frame = curr_anim->frames_count - 1; + ss_anim->lerp = 0.0f; + ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period; + return 0x00; } else if(ss_anim->anim_frame_flags == ANIM_FRAME_LOCK) { - *frame = 0; - *anim = ss_anim->current_animation; - return; + ss_anim->current_frame = 0; + ss_anim->lerp = 0.0f; + ss_anim->frame_time = 0.0f; + return 0x00; } /* @@ -845,11 +856,16 @@ void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ anim_dispatch_p disp = stc->anim_dispatch; for(uint16_t i = 0; i < stc->anim_dispatch_count; i++, disp++) { - if((disp->frame_high >= disp->frame_low) && (((*frame >= disp->frame_low) && (*frame <= disp->frame_high)) || ((ss_anim->current_frame < disp->frame_low) && (*frame > disp->frame_high)))) + if((disp->frame_high >= disp->frame_low) && ((new_frame >= disp->frame_low) && (new_frame <= disp->frame_high) || + (disp->frame_high < disp->frame_low) && ((new_frame < disp->frame_low) && (new_frame > disp->frame_high)))) { - *anim = disp->next_anim; - *frame = disp->next_frame; - return; + ss_anim->lerp = 0.0f; + ss_anim->current_animation = disp->next_anim; + ss_anim->current_frame = disp->next_frame; + ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; + ss_anim->current_state = ss_anim->model->animations[ss_anim->current_animation].state_id; + ss_anim->next_state = ss_anim->current_state; + return 0x02; } } } @@ -857,17 +873,27 @@ void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ /* * Check next anim if frame >= frames_count */ - if(*frame >= curr_anim->frames_count - 1) + if(curr_anim->next_anim && (new_frame + 1 >= curr_anim->frames_count)) { - if(curr_anim->next_anim) - { - *was_last_anim = 1; - *frame = curr_anim->next_frame; - *anim = curr_anim->next_anim->id; - return; - } - - *frame %= curr_anim->frames_count; - *anim = ss_anim->current_animation; // paranoid dublicate + ss_anim->current_frame = curr_anim->next_frame; + ss_anim->current_animation = curr_anim->next_anim->id; + ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; + ss_anim->current_state = ss_anim->model->animations[ss_anim->current_animation].state_id; + ss_anim->next_state = ss_anim->current_state; + return ((curr_anim->next_anim->id == curr_anim->id) ? (0x01) : (0x02)); + } + + if(new_frame + 1 >= curr_anim->frames_count) + { + ss_anim->current_frame = 0; + ss_anim->frame_time = dt; + return 0x01; + } + + if(ss_anim->current_frame == new_frame) + { + return 0x00; } + ss_anim->current_frame = new_frame; + return 0x01; } diff --git a/src/skeletal_model.h b/src/skeletal_model.h index 477c1f3be..d4d4deaf8 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -177,6 +177,9 @@ typedef struct animation_frame_s uint32_t id; uint16_t original_frame_rate; uint16_t command_flags; // & 0x01 - move need, &0x02 - 180 rotate need + uint16_t condition_frame; + uint16_t state_id; + float speed_x; // Forward-backward speed float accel_x; // Forward-backward accel float speed_y; // Left-right speed @@ -186,15 +189,14 @@ typedef struct animation_frame_s float v_Horizontal; // jump command data uint32_t anim_command; uint32_t num_anim_commands; - uint16_t state_id; + uint16_t frames_count; // Number of frames - struct bone_frame_s *frames; // Frame data - uint16_t state_change_count; // Number of animation statechanges + struct bone_frame_s *frames; // Frame data struct state_change_s *state_change; // Animation statechanges data struct animation_frame_s *next_anim; // Next default animation - int next_frame; // Next default frame + int32_t next_frame; // Next default frame }animation_frame_t, *animation_frame_p; /* @@ -248,7 +250,7 @@ void SSBoneFrame_DisableOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_t struct state_change_s *Anim_FindStateChangeByAnim(struct animation_frame_s *anim, int state_change_anim); struct state_change_s *Anim_FindStateChangeByID(struct animation_frame_s *anim, uint32_t id); int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id); -void Anim_GetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc, int16_t *frame, int16_t *anim, int16_t *was_last_anim); +int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc); #ifdef __cplusplus } From 1c1e6cfbc7767a69705fb34208e5fc440eb20ee0 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sat, 6 Aug 2016 00:19:33 +0400 Subject: [PATCH 03/24] restored anim command functions; (change direction still works incorrect in some cases, but no more hack flags overriding by scripts); climbing system become pretty buggy... --- src/anim_state_control.cpp | 6 ++--- src/entity.cpp | 54 ++++++++++++++++++++------------------ src/resource.cpp | 10 +++---- src/skeletal_model.c | 37 +++++++------------------- 4 files changed, 45 insertions(+), 62 deletions(-) diff --git a/src/anim_state_control.cpp b/src/anim_state_control.cpp index e978145ec..a1ec3ed45 100644 --- a/src/anim_state_control.cpp +++ b/src/anim_state_control.cpp @@ -55,9 +55,9 @@ void ent_stop_traverse(entity_p ent, ss_animation_p ss_anim, int state) { float *v = ent->character->traversed_object->transform + 12; int i = v[0] / TR_METERING_SECTORSIZE; - v[0] = i * TR_METERING_SECTORSIZE + 512.0; + v[0] = i * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE / 2; i = v[1] / TR_METERING_SECTORSIZE; - v[1] = i * TR_METERING_SECTORSIZE + 512.0; + v[1] = i * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE / 2; SSBoneFrame_Update(ent->bf, 0.0f); Entity_UpdateRigidBody(ent->character->traversed_object, 1); ent->character->traversed_object = NULL; @@ -98,7 +98,7 @@ void ent_set_on_floor_after_climb(entity_p ent, ss_animation_p ss_anim, int stat Entity_SetAnimation(ent, ANIM_TYPE_BASE, af->next_anim->id, af->next_frame); Mat4_vec3_mul(p, ent->transform, ent->bf->bone_tags[0].full_transform + 12); vec3_sub(move, move, p); - vec3_add(ent->transform+12, ent->transform+12, move); + vec3_add(ent->transform+12, ent->transform + 12, move); ent->transform[12 + 2] = ent->character->climb.point[2]; SSBoneFrame_Update(ent->bf, 0.0f); Entity_UpdateRigidBody(ent, 1); diff --git a/src/entity.cpp b/src/entity.cpp index 02ed07fce..834458f83 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -656,7 +656,7 @@ void Entity_CheckCollisionCallbacks(entity_p ent) void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int changing) { - if((World_GetAnimCommands() == NULL) || (ss_anim->model == NULL)) + if((World_GetAnimCommands() == NULL) || (ss_anim->model == NULL) || (changing == 0x00)) { return; // If no anim commands } @@ -688,19 +688,14 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int case TR_ANIMCOMMAND_KILL: // This command executes ONLY at the end of animation. - if(ss_anim->current_frame == af->frames_count - 1) + if((changing >= 0x02) && (entity->character)) { - if(entity->character) - { - entity->character->resp.kill = 1; - } + entity->character->resp.kill = 1; } - break; case TR_ANIMCOMMAND_PLAYSOUND: int16_t sound_index; - if(ss_anim->current_frame == *++pointer) { sound_index = *++pointer & 0x3FFF; @@ -739,14 +734,15 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int // however, and currently only these are supported. if(ss_anim->current_frame == *++pointer) { + entity_p player = World_GetPlayer(); switch(*++pointer & 0x3FFF) { case TR_EFFECT_SHAKESCREEN: - if(World_GetPlayer()) + if(player) { - float *pos = World_GetPlayer()->transform + 12; + float *pos = player->transform + 12; float dist = vec3_dist(pos, entity->transform + 12); - dist = (dist > TR_CAM_MAX_SHAKE_DISTANCE)?(0):((TR_CAM_MAX_SHAKE_DISTANCE - dist) / 1024.0); + dist = (dist > TR_CAM_MAX_SHAKE_DISTANCE) ? (0) : ((TR_CAM_MAX_SHAKE_DISTANCE - dist) / 1024.0f); //if(dist > 0) // Cam_Shake(&engine_camera, (dist * TR_CAM_DEFAULT_SHAKE_POWER), 0.5); } @@ -940,19 +936,19 @@ void Entity_SetAnimation(entity_p entity, int anim_type, int animation, int fram } -void Entity_DoAnimTransformCommand(entity_p entity) +void Entity_DoAnimTransformCommand(entity_p entity, int16_t prev_anim, int16_t prev_frame, int changing) { if(entity->bf->animations.model != NULL) { animation_frame_p curr_af = entity->bf->animations.model->animations + entity->bf->animations.current_animation; + animation_frame_p prev_af = entity->bf->animations.model->animations + prev_anim; - if(curr_af->anim_command & ANIM_CMD_JUMP) + if((changing >= 2) && (curr_af->command_flags & ANIM_CMD_JUMP)) { Character_SetToJump(entity, -curr_af->v_Vertical, curr_af->v_Horizontal); } - /*if(curr_af->anim_command & ANIM_CMD_CHANGE_DIRECTION) + if((changing >= 1) && (curr_af->condition_frame == entity->bf->animations.current_frame) && (curr_af->command_flags & ANIM_CMD_CHANGE_DIRECTION)) { - //Con_Printf("ROTATED: anim = %d, frame = %d of %d", entity->bf->animations.current_animation, entity->bf->animations.current_frame, entity->bf->animations.model->animations[entity->bf->animations.current_animation].frames_count); entity->angles[0] += 180.0f; if(entity->move_type == MOVE_UNDERWATER) { @@ -966,13 +962,19 @@ void Entity_DoAnimTransformCommand(entity_p entity) { entity->dir_flag = ENT_MOVE_BACKWARD; } - Entity_SetAnimation(entity, ANIM_TYPE_BASE, curr_af->next_anim->id, curr_af->next_frame); + + /*if(curr_af->condition_frame > 0) + { + Entity_SetAnimation(entity, ANIM_TYPE_BASE, curr_af->next_anim->id, curr_af->next_frame); + }*/ Entity_UpdateTransform(entity); - }*/ - if(curr_af->anim_command & ANIM_CMD_MOVE) + Entity_UpdateRigidBody(entity, 1); + } + if((changing >= 2) && (prev_af->command_flags & ANIM_CMD_MOVE)) { float tr[3]; - Mat4_vec3_rot_macro(tr, entity->transform, curr_af->move); + entity->no_fix_all = 0x01; + Mat4_vec3_rot_macro(tr, entity->transform, prev_af->move); vec3_add(entity->transform + 12, entity->transform + 12, tr); } } @@ -1015,9 +1017,6 @@ void Entity_MoveToSink(entity_p entity, uint32_t sink_index) } -/** - * In original engine (+ some information from anim_commands) the anim_commands implement in beginning of frame - */ void Entity_Frame(entity_p entity, float time) { if(entity && !(entity->type_flags & ENTITY_TYPE_DYNAMIC) && (entity->state_flags & ENTITY_STATE_ACTIVE) && (entity->state_flags & ENTITY_STATE_ENABLED)) @@ -1043,12 +1042,17 @@ void Entity_Frame(entity_p entity, float time) ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->frames_count > 1))) { state_change_p stc = Anim_FindStateChangeByID(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); + int16_t old_anim = ss_anim->current_animation; + int16_t old_frame = ss_anim->current_frame; uint16_t frame_switch_state = Anim_SetNextFrame(ss_anim, time, stc); if(frame_switch_state > 0) { - entity->no_fix_all = 0x00; - //Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); - //Entity_DoAnimTransformCommand(entity); + if(frame_switch_state >= 2) + { + entity->no_fix_all = 0x00; + } + Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); + Entity_DoAnimTransformCommand(entity, old_anim, old_frame, frame_switch_state); } // Update acceleration. diff --git a/src/resource.cpp b/src/resource.cpp index 9c1fb524c..ff86df78f 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1700,7 +1700,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct bone_frame = model->animations->frames; model->animations->id = 0; - model->animations->next_anim = NULL; + model->animations->next_anim = model->animations->next_anim; model->animations->next_frame = 0; model->animations->state_change = NULL; model->animations->state_change_count = 0; @@ -1960,7 +1960,8 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct { anim->state_change_count = 0; anim->state_change = NULL; - + anim->next_anim = anim; + anim->next_frame = 0; tr_animation = &tr->animations[tr_moveable->animation_index + i]; int16_t j = tr_animation->next_animation - tr_moveable->animation_index; j &= 0x7fff; @@ -1977,11 +1978,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct Sys_DebugLog(LOG_FILENAME, "ANIM[%d], next_anim = %d, next_frame = %d", i, anim->next_anim->id, anim->next_frame); #endif } - else - { - anim->next_anim = NULL; - anim->next_frame = 0; - } anim->state_change_count = 0; anim->state_change = NULL; diff --git a/src/skeletal_model.c b/src/skeletal_model.c index d1b36a1f9..0726dc0e2 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -404,17 +404,12 @@ void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) { next_bf = curr_bf + 1; } - else if(curr_anim->next_anim) - { - next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; - } else { - next_bf = curr_bf; - bf->animations.lerp = 0.0f; + next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; } + t = 1.0f - bf->animations.lerp; - vec3_interpolate_macro(bf->bb_max, curr_bf->bb_max, next_bf->bb_max, bf->animations.lerp, t); vec3_interpolate_macro(bf->bb_min, curr_bf->bb_min, next_bf->bb_min, bf->animations.lerp, t); vec3_interpolate_macro(bf->centre, curr_bf->centre, next_bf->centre, bf->animations.lerp, t); @@ -447,14 +442,9 @@ void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) { ov_next_bf = ov_curr_bf + 1; } - else if(curr_anim->next_anim) - { - ov_next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; - } else { - ov_next_bf = ov_curr_bf; - ov_lerp = 0.0f; + ov_next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; } ov_src_btag = ov_curr_bf->bone_tags + k; ov_next_btag = ov_next_bf->bone_tags + k; @@ -856,8 +846,7 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ anim_dispatch_p disp = stc->anim_dispatch; for(uint16_t i = 0; i < stc->anim_dispatch_count; i++, disp++) { - if((disp->frame_high >= disp->frame_low) && ((new_frame >= disp->frame_low) && (new_frame <= disp->frame_high) || - (disp->frame_high < disp->frame_low) && ((new_frame < disp->frame_low) && (new_frame > disp->frame_high)))) + if((disp->frame_high >= disp->frame_low) && ((new_frame >= disp->frame_low) && (new_frame <= disp->frame_high))) { ss_anim->lerp = 0.0f; ss_anim->current_animation = disp->next_anim; @@ -865,7 +854,7 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; ss_anim->current_state = ss_anim->model->animations[ss_anim->current_animation].state_id; ss_anim->next_state = ss_anim->current_state; - return 0x02; + return 0x03; } } } @@ -873,27 +862,21 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ /* * Check next anim if frame >= frames_count */ - if(curr_anim->next_anim && (new_frame + 1 >= curr_anim->frames_count)) + if(new_frame + 1 >= curr_anim->frames_count) { ss_anim->current_frame = curr_anim->next_frame; ss_anim->current_animation = curr_anim->next_anim->id; ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; ss_anim->current_state = ss_anim->model->animations[ss_anim->current_animation].state_id; ss_anim->next_state = ss_anim->current_state; - return ((curr_anim->next_anim->id == curr_anim->id) ? (0x01) : (0x02)); + return 0x02;//((curr_anim->next_anim->id == curr_anim->id) ? (0x01) : (0x02)); } - if(new_frame + 1 >= curr_anim->frames_count) + if(ss_anim->current_frame != new_frame) { - ss_anim->current_frame = 0; - ss_anim->frame_time = dt; + ss_anim->current_frame = new_frame; return 0x01; } - if(ss_anim->current_frame == new_frame) - { - return 0x00; - } - ss_anim->current_frame = new_frame; - return 0x01; + return 0x00; } From aebd7875d4efb1cf1b06532344f8f9fb45d674ad Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sat, 6 Aug 2016 11:40:27 +0400 Subject: [PATCH 04/24] fixed jump frame condition; deleted set_on_floor_after_climb: used native move commands; fixed frame change checking (added 0x03 flag); --- autoexec.lua | 4 +-- src/anim_state_control.cpp | 50 +++++++++----------------------------- src/entity.cpp | 2 +- src/skeletal_model.c | 12 ++++----- 4 files changed, 21 insertions(+), 47 deletions(-) diff --git a/autoexec.lua b/autoexec.lua index d60e54bb0..487518fdd 100644 --- a/autoexec.lua +++ b/autoexec.lua @@ -20,5 +20,5 @@ noclip(0); --loadMap("data/LEVEL1.PHD"); --loadMap("tests/altroom1/LEVEL1.PHD"); --loadMap("tests/heavy1/LEVEL1.PHD"); ---setgamef(1, 99); -dofile("save/pad"); \ No newline at end of file +setgamef(4, 1); +--dofile("save/pad"); \ No newline at end of file diff --git a/src/anim_state_control.cpp b/src/anim_state_control.cpp index a1ec3ed45..6849b46ae 100644 --- a/src/anim_state_control.cpp +++ b/src/anim_state_control.cpp @@ -51,7 +51,7 @@ void ent_stop_traverse(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { float *v = ent->character->traversed_object->transform + 12; int i = v[0] / TR_METERING_SECTORSIZE; @@ -67,7 +67,7 @@ void ent_stop_traverse(entity_p ent, ss_animation_p ss_anim, int state) void ent_set_on_floor(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { ent->move_type = MOVE_ON_FLOOR; ent->transform[12 + 2] = ent->character->height_info.floor_hit.point[2]; @@ -87,30 +87,9 @@ void ent_set_turn_fast(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_set_on_floor_after_climb(entity_p ent, ss_animation_p ss_anim, int state) -{ - animation_frame_p af = ss_anim->model->animations + ss_anim->current_animation; - if(ss_anim->current_frame >= af->frames_count - 1) - { - float p[3], move[3]; - - Mat4_vec3_mul(move, ent->transform, ent->bf->bone_tags[0].full_transform + 12); - Entity_SetAnimation(ent, ANIM_TYPE_BASE, af->next_anim->id, af->next_frame); - Mat4_vec3_mul(p, ent->transform, ent->bf->bone_tags[0].full_transform + 12); - vec3_sub(move, move, p); - vec3_add(ent->transform+12, ent->transform + 12, move); - ent->transform[12 + 2] = ent->character->climb.point[2]; - SSBoneFrame_Update(ent->bf, 0.0f); - Entity_UpdateRigidBody(ent, 1); - Entity_GhostUpdate(ent); - ent->move_type = MOVE_ON_FLOOR; - ss_anim->onEndFrame = NULL; - } -} - void ent_set_underwater(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { ent->move_type = MOVE_UNDERWATER; ss_anim->onEndFrame = NULL; @@ -119,7 +98,7 @@ void ent_set_underwater(entity_p ent, ss_animation_p ss_anim, int state) void ent_set_free_falling(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { ent->move_type = MOVE_FREE_FALLING; ss_anim->onEndFrame = NULL; @@ -128,7 +107,7 @@ void ent_set_free_falling(entity_p ent, ss_animation_p ss_anim, int state) void ent_set_cmd_slide(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { ent->character->resp.slide = 0x01; ss_anim->onEndFrame = NULL; @@ -137,7 +116,7 @@ void ent_set_cmd_slide(entity_p ent, ss_animation_p ss_anim, int state) void ent_correct_diving_angle(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { ent->angles[1] = -45.0; Entity_UpdateTransform(ent); @@ -147,7 +126,7 @@ void ent_correct_diving_angle(entity_p ent, ss_animation_p ss_anim, int state) void ent_to_on_water(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { ent->transform[12 + 2] = ent->character->height_info.transition_level; Entity_GhostUpdate(ent); @@ -158,11 +137,10 @@ void ent_to_on_water(entity_p ent, ss_animation_p ss_anim, int state) void ent_climb_out_of_water(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { float *v = ent->character->climb.point; - - vec3_add_mul(ent->transform+12, v, ent->transform+4, 48.0); // temporary stick + vec3_add_mul(ent->transform + 12, v, ent->transform + 4, 48.0); // temporary stick ent->transform[12 + 2] = v[2]; SSBoneFrame_Update(ent->bf, 0.0f); Entity_UpdateRigidBody(ent, 1); @@ -173,7 +151,7 @@ void ent_climb_out_of_water(entity_p ent, ss_animation_p ss_anim, int state) void ent_to_edge_climb(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { float *v = ent->character->climb.point; ent->transform[12 + 0] = v[0] - ent->transform[4 + 0] * ent->bf->bb_max[1]; @@ -188,7 +166,7 @@ void ent_to_edge_climb(entity_p ent, ss_animation_p ss_anim, int state) void ent_to_monkey_swing(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { ent->move_type = MOVE_MONKEYSWING; ent->transform[12 + 2] = ent->character->height_info.ceiling_hit.point[2] - ent->bf->bb_max[2]; @@ -199,7 +177,7 @@ void ent_to_monkey_swing(entity_p ent, ss_animation_p ss_anim, int state) void ent_crawl_to_climb(entity_p ent, ss_animation_p ss_anim, int state) { - if(state == 0x02) + if(state >= 0x02) { character_command_p cmd = &ent->character->cmd; @@ -443,7 +421,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) vec3_copy(climb->point, climb->edge_point); Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_LARA_CLIMB_2CLICK, 0); ent->no_fix_all = 0x01; - ss_anim->onEndFrame = ent_set_on_floor_after_climb; break; } else if(pos[2] + 896.0 >= climb->edge_point[2]) @@ -453,7 +430,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) vec3_copy(climb->point, climb->edge_point); Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_LARA_CLIMB_3CLICK, 0); ent->no_fix_all = 0x01; - ss_anim->onEndFrame = ent_set_on_floor_after_climb; break; } } // end IF MOVE_LITTLE_CLIMBING @@ -1801,7 +1777,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) case TR_STATE_LARA_CLIMB_TO_CRAWL: cmd->rot[0] = 0; ent->no_fix_all = 0x01; - ss_anim->onEndFrame = ent_set_on_floor_after_climb; break; case TR_STATE_LARA_HANG: @@ -2232,7 +2207,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) case TR_STATE_LARA_ONWATER_EXIT: cmd->rot[0] = 0; ent->no_fix_all = 0x01; - ss_anim->onEndFrame = ent_set_on_floor_after_climb; break; case TR_STATE_LARA_JUMP_FORWARD: diff --git a/src/entity.cpp b/src/entity.cpp index 834458f83..c8a0b5993 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -943,7 +943,7 @@ void Entity_DoAnimTransformCommand(entity_p entity, int16_t prev_anim, int16_t p animation_frame_p curr_af = entity->bf->animations.model->animations + entity->bf->animations.current_animation; animation_frame_p prev_af = entity->bf->animations.model->animations + prev_anim; - if((changing >= 2) && (curr_af->command_flags & ANIM_CMD_JUMP)) + if((entity->bf->animations.current_frame == 1) && (prev_frame == 0) && (curr_af->command_flags & ANIM_CMD_JUMP)) { Character_SetToJump(entity, -curr_af->v_Vertical, curr_af->v_Horizontal); } diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 0726dc0e2..2c61f6da5 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -864,12 +864,12 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ */ if(new_frame + 1 >= curr_anim->frames_count) { - ss_anim->current_frame = curr_anim->next_frame; - ss_anim->current_animation = curr_anim->next_anim->id; - ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; - ss_anim->current_state = ss_anim->model->animations[ss_anim->current_animation].state_id; - ss_anim->next_state = ss_anim->current_state; - return 0x02;//((curr_anim->next_anim->id == curr_anim->id) ? (0x01) : (0x02)); + ss_anim->current_frame = curr_anim->next_frame; + ss_anim->current_animation = curr_anim->next_anim->id; + ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; + ss_anim->current_state = ss_anim->model->animations[ss_anim->current_animation].state_id; + ss_anim->next_state = ss_anim->current_state; + return 0x02; } if(ss_anim->current_frame != new_frame) From 92ce0f46ba5e4c4aabdc198fe376f14ed39ddcb3 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sat, 6 Aug 2016 16:22:49 +0400 Subject: [PATCH 05/24] restored fields next_frame and next_anim in ss_animation_s strucrure; --- src/character_controller.cpp | 130 +++++++++++++++++------------------ src/entity.cpp | 14 ++-- src/skeletal_model.c | 54 ++++++++------- src/skeletal_model.h | 9 ++- 4 files changed, 109 insertions(+), 98 deletions(-) diff --git a/src/character_controller.cpp b/src/character_controller.cpp index 26ee86aaa..a756db0b4 100644 --- a/src/character_controller.cpp +++ b/src/character_controller.cpp @@ -2429,20 +2429,20 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - //ss_anim->next_frame = (ss_anim->current_frame + 1) % t; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = (ss_anim->current_frame + 1) % t; + ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 0; + ss_anim->next_frame = 0; + ss_anim->next_animation = 0; } else { ss_anim->current_frame = 0; ss_anim->current_animation = 0; - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 0; + ss_anim->next_frame = 0; + ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE; } @@ -2451,14 +2451,14 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * case WEAPON_STATE_IDLE: ss_anim->current_frame = 0; ss_anim->current_animation = 0; - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 0; + ss_anim->next_frame = 0; + ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 2; - //ss_anim->next_animation = 2; - //ss_anim->current_frame = ss_anim->next_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; + ss_anim->next_animation = 2; + ss_anim->current_frame = ss_anim->next_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; } @@ -2482,13 +2482,13 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = t - 1 - ss_anim->current_frame; if(ss_anim->current_frame > 0) { - //ss_anim->next_frame = ss_anim->current_frame - 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame - 1; + ss_anim->next_animation = ss_anim->current_animation; } else { - //ss_anim->next_frame = ss_anim->current_frame = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame = 0; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_IDLE; } break; @@ -2503,7 +2503,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 2; - //ss_anim->next_animation = 2; + ss_anim->next_animation = 2; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; break; @@ -2525,20 +2525,20 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - //ss_anim->next_frame = ss_anim->current_frame + 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame + 1; + ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 3; + ss_anim->next_frame = 0; + ss_anim->next_animation = 3; } else if(!silent && ent->character->cmd.action) { ss_anim->current_frame = 0; - //ss_anim->next_frame = 1; + ss_anim->next_frame = 1; ss_anim->current_animation = 3; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_FIRE; } else @@ -2565,28 +2565,28 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - //ss_anim->next_frame = ss_anim->current_frame + 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame + 1; + ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - //ss_anim->next_frame = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = 0; + ss_anim->next_animation = ss_anim->current_animation; } else { ss_anim->frame_time = dt; ss_anim->current_frame = 0; - //ss_anim->next_frame = 1; + ss_anim->next_frame = 1; } } else { ss_anim->frame_time = 0.0; ss_anim->current_animation = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; - //ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); + ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } break; @@ -2601,13 +2601,13 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = t - 1 - ss_anim->current_frame; if(ss_anim->current_frame > 0) { - //ss_anim->next_frame = ss_anim->current_frame - 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame - 1; + ss_anim->next_animation = ss_anim->current_animation; } else { - //ss_anim->next_frame = ss_anim->current_frame = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame = 0; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_HIDE; ent->character->weapon_current_state = WEAPON_STATE_HIDE; Character_SetWeaponModel(ent, ent->character->current_weapon, WEAPON_STATE_HIDE); @@ -2657,9 +2657,9 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ent->character->cmd.ready_weapon) // ready weapon { ss_anim->current_animation = 1; - //ss_anim->next_animation = 1; + ss_anim->next_animation = 1; ss_anim->current_frame = 0; - //ss_anim->next_frame = 0; + ss_anim->next_frame = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_HIDE_TO_READY; ent->character->weapon_current_state = WEAPON_STATE_IDLE; @@ -2675,20 +2675,20 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - //ss_anim->next_frame = (ss_anim->current_frame + 1) % t; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = (ss_anim->current_frame + 1) % t; + ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 0; + ss_anim->next_frame = 0; + ss_anim->next_animation = 0; } else { ss_anim->current_frame = 0; ss_anim->current_animation = 0; - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 0; + ss_anim->next_frame = 0; + ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE; } @@ -2697,13 +2697,13 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * case WEAPON_STATE_IDLE: ss_anim->current_frame = 0; ss_anim->current_animation = 0; - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 0; + ss_anim->next_frame = 0; + ss_anim->next_animation = 0; ss_anim->frame_time = 0.0; if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 3; - //ss_anim->next_animation = 3; + ss_anim->next_animation = 3; //ss_anim->current_frame = ss_anim->next_frame = 0; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; @@ -2728,13 +2728,13 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = t - 1 - ss_anim->current_frame; if(ss_anim->current_frame > 0) { - //ss_anim->next_frame = ss_anim->current_frame - 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame - 1; + ss_anim->next_animation = ss_anim->current_animation; } else { - //ss_anim->next_frame = ss_anim->current_frame = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame = 0; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_IDLE; } break; @@ -2749,7 +2749,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ent->character->cmd.ready_weapon) { ss_anim->current_animation = 3; - //ss_anim->next_animation = 3; + ss_anim->next_animation = 3; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; break; @@ -2771,20 +2771,20 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - //ss_anim->next_frame = ss_anim->current_frame + 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame + 1; + ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - //ss_anim->next_frame = 0; - //ss_anim->next_animation = 2; + ss_anim->next_frame = 0; + ss_anim->next_animation = 2; } else if(ent->character->cmd.action) { ss_anim->current_frame = 0; - //ss_anim->next_frame = 1; + ss_anim->next_frame = 1; ss_anim->current_animation = 2; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_FIRE; } else @@ -2811,28 +2811,28 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * if(ss_anim->current_frame < t - 1) { - //ss_anim->next_frame = ss_anim->current_frame + 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame + 1; + ss_anim->next_animation = ss_anim->current_animation; } else if(ss_anim->current_frame < t) { - //ss_anim->next_frame = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = 0; + ss_anim->next_animation = ss_anim->current_animation; } else { ss_anim->frame_time = dt; ss_anim->current_frame = 0; - //ss_anim->next_frame = 1; + ss_anim->next_frame = 1; } } else { ss_anim->frame_time = 0.0; ss_anim->current_animation = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; - //ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); + ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } break; @@ -2845,13 +2845,13 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->lerp = dt / ss_anim->period; if(ss_anim->current_frame < t - 1) { - //ss_anim->next_frame = ss_anim->current_frame + 1; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame + 1; + ss_anim->next_animation = ss_anim->current_animation; } else { - //ss_anim->next_frame = ss_anim->current_frame = 0; - //ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = ss_anim->current_frame = 0; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->current_state = WEAPON_STATE_HIDE; ent->character->weapon_current_state = WEAPON_STATE_HIDE; Character_SetWeaponModel(ent, ent->character->current_weapon, WEAPON_STATE_HIDE); diff --git a/src/entity.cpp b/src/entity.cpp index c8a0b5993..1191784cb 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -936,18 +936,18 @@ void Entity_SetAnimation(entity_p entity, int anim_type, int animation, int fram } -void Entity_DoAnimTransformCommand(entity_p entity, int16_t prev_anim, int16_t prev_frame, int changing) +void Entity_DoAnimTransformCommand(entity_p entity, struct ss_animation_s *ss_anim, int16_t prev_anim, int16_t prev_frame, int changing) { - if(entity->bf->animations.model != NULL) + if(ss_anim->model != NULL) { - animation_frame_p curr_af = entity->bf->animations.model->animations + entity->bf->animations.current_animation; - animation_frame_p prev_af = entity->bf->animations.model->animations + prev_anim; + animation_frame_p curr_af = ss_anim->model->animations + ss_anim->current_animation; + animation_frame_p prev_af = ss_anim->model->animations + prev_anim; - if((entity->bf->animations.current_frame == 1) && (prev_frame == 0) && (curr_af->command_flags & ANIM_CMD_JUMP)) + if((ss_anim->current_frame == 1) && (prev_frame == 0) && (curr_af->command_flags & ANIM_CMD_JUMP)) { Character_SetToJump(entity, -curr_af->v_Vertical, curr_af->v_Horizontal); } - if((changing >= 1) && (curr_af->condition_frame == entity->bf->animations.current_frame) && (curr_af->command_flags & ANIM_CMD_CHANGE_DIRECTION)) + if((changing >= 1) && (curr_af->condition_frame == ss_anim->current_frame) && (curr_af->command_flags & ANIM_CMD_CHANGE_DIRECTION)) { entity->angles[0] += 180.0f; if(entity->move_type == MOVE_UNDERWATER) @@ -1052,7 +1052,7 @@ void Entity_Frame(entity_p entity, float time) entity->no_fix_all = 0x00; } Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); - Entity_DoAnimTransformCommand(entity, old_anim, old_frame, frame_switch_state); + Entity_DoAnimTransformCommand(entity, ss_anim, old_anim, old_frame, frame_switch_state); } // Update acceleration. diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 2c61f6da5..72e3d1f2e 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -363,6 +363,8 @@ void SSBoneFrame_InitSSAnim(struct ss_animation_s *ss_anim, uint32_t anim_type_i ss_anim->lerp = 0.0; ss_anim->current_animation = 0; ss_anim->current_frame = 0; + ss_anim->next_animation = 0; + ss_anim->next_frame = 0; ss_anim->period = 1.0f / 30.0f; ss_anim->next = NULL; @@ -392,24 +394,15 @@ void SSBoneFrame_Clear(ss_bone_frame_p bf) void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) { - float t; + float t = 1.0f - bf->animations.lerp; ss_bone_tag_p btag = bf->bone_tags; bone_tag_p src_btag, next_btag; skeletal_model_p model = bf->animations.model; - bone_frame_p curr_bf, next_bf; animation_frame_p curr_anim = model->animations + bf->animations.current_animation; + animation_frame_p next_anim = model->animations + bf->animations.next_animation; + bone_frame_p curr_bf = curr_anim->frames + bf->animations.current_frame; + bone_frame_p next_bf = next_anim->frames + bf->animations.next_frame; - curr_bf = curr_anim->frames + bf->animations.current_frame; - if(bf->animations.current_frame + 1 < curr_anim->frames_count) - { - next_bf = curr_bf + 1; - } - else - { - next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; - } - - t = 1.0f - bf->animations.lerp; vec3_interpolate_macro(bf->bb_max, curr_bf->bb_max, next_bf->bb_max, bf->animations.lerp, t); vec3_interpolate_macro(bf->bb_min, curr_bf->bb_min, next_bf->bb_min, bf->animations.lerp, t); vec3_interpolate_macro(bf->centre, curr_bf->centre, next_bf->centre, bf->animations.lerp, t); @@ -435,17 +428,10 @@ void SSBoneFrame_Update(struct ss_bone_frame_s *bf, float time) if(btag->alt_anim && btag->alt_anim->model && btag->alt_anim->enabled && (btag->alt_anim->model->mesh_tree[k].replace_anim != 0)) { curr_anim = btag->alt_anim->model->animations + btag->alt_anim->current_animation; + next_anim = btag->alt_anim->model->animations + btag->alt_anim->next_animation; bone_frame_p ov_curr_bf = curr_anim->frames + btag->alt_anim->current_frame; - bone_frame_p ov_next_bf; + bone_frame_p ov_next_bf = next_anim->frames + btag->alt_anim->next_frame; ov_lerp = btag->alt_anim->lerp; - if(btag->alt_anim->current_frame + 1 < curr_anim->frames_count) - { - ov_next_bf = ov_curr_bf + 1; - } - else - { - ov_next_bf = curr_anim->next_anim->frames + curr_anim->next_frame; - } ov_src_btag = ov_curr_bf->bone_tags + k; ov_next_btag = ov_next_bf->bone_tags + k; } @@ -808,6 +794,22 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) /* * Next frame and next anim calculation function. */ +void inline Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame) +{ + animation_frame_p curr_anim = ss_anim->model->animations + ss_anim->current_animation; + if(new_frame + 1 < curr_anim->frames_count) + { + ss_anim->next_frame = new_frame + 1; + ss_anim->next_animation = ss_anim->current_animation; + } + else + { + ss_anim->next_frame = curr_anim->next_frame; + ss_anim->next_animation = curr_anim->next_anim->id; + } +} + + int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc) { float dt; @@ -826,6 +828,8 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ if((new_frame + 1 >= curr_anim->frames_count) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) { ss_anim->current_frame = curr_anim->frames_count - 1; + ss_anim->next_frame = ss_anim->current_frame; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->lerp = 0.0f; ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period; return 0x00; @@ -833,6 +837,8 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ else if(ss_anim->anim_frame_flags == ANIM_FRAME_LOCK) { ss_anim->current_frame = 0; + ss_anim->next_frame = ss_anim->current_frame; + ss_anim->next_animation = ss_anim->current_animation; ss_anim->lerp = 0.0f; ss_anim->frame_time = 0.0f; return 0x00; @@ -851,6 +857,7 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ ss_anim->lerp = 0.0f; ss_anim->current_animation = disp->next_anim; ss_anim->current_frame = disp->next_frame; + Anim_SetNextAnimFrame(ss_anim, disp->next_frame); ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; ss_anim->current_state = ss_anim->model->animations[ss_anim->current_animation].state_id; ss_anim->next_state = ss_anim->current_state; @@ -858,7 +865,8 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ } } } - + Anim_SetNextAnimFrame(ss_anim, new_frame); + /* * Check next anim if frame >= frames_count */ diff --git a/src/skeletal_model.h b/src/skeletal_model.h index d4d4deaf8..0a0a8e7dd 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -70,11 +70,14 @@ typedef struct ss_animation_s { uint16_t type : 15; uint16_t enabled : 1; + uint16_t unused; int16_t current_state; int16_t next_state; - int16_t current_animation; // - int16_t current_frame; // - + int16_t current_animation; + int16_t current_frame; + int16_t next_animation; + int16_t next_frame; + uint16_t anim_frame_flags; // base animation control flags uint16_t anim_ext_flags; // additional animation control flags From c9060dc1ab1721beca52dc8af17496879bdd14ab Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sat, 6 Aug 2016 18:34:02 +0400 Subject: [PATCH 06/24] warning fixes; --- src/core/vmath.c | 2 +- src/game.cpp | 2 +- src/render/render.cpp | 4 ++-- src/resource.cpp | 16 ++++++++-------- src/script.cpp | 7 ++++++- src/skeletal_model.c | 8 +++----- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/core/vmath.c b/src/core/vmath.c index 3bfe24f62..c97079840 100644 --- a/src/core/vmath.c +++ b/src/core/vmath.c @@ -99,7 +99,7 @@ void Spline_BuildLine(spline_p spline) float Spline_Get(spline_p spline, float t) { - uint32_t i = t; + int32_t i = t; if((i < 0) || (i + 1 > spline->base_points_count)) { diff --git a/src/game.cpp b/src/game.cpp index 4f67dc68d..6acf24e93 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -283,7 +283,7 @@ void Save_Entity(FILE **f, entity_p ent) for(ss_anim = &ent->bf->animations; ss_anim; ss_anim = ss_anim->next) { - fprintf(*f, "\nsetEntityAnim(%d, %d, %d, %d, %d, %d);", ent->id, ss_anim->type, ss_anim->current_animation, ss_anim->current_frame); + fprintf(*f, "\nsetEntityAnim(%d, %d, %d, %d, %d, %d);", ent->id, ss_anim->type, ss_anim->current_animation, ss_anim->current_frame, ss_anim->next_animation, ss_anim->next_frame); fprintf(*f, "\nsetEntityAnimState(%d, %d, %d, %d);", ent->id, ss_anim->type, ss_anim->next_state, ss_anim->current_state); fprintf(*f, "\nentitySSAnimSetTarget(%d, %d, %d, %.2f, %.2f, %.2f, %.6f, %.6f, %.6f);", ent->id, ss_anim->type, ss_anim->targeting_bone, ss_anim->target[0], ss_anim->target[1], ss_anim->target[2], diff --git a/src/render/render.cpp b/src/render/render.cpp index 28ecfb398..463c8b115 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -260,7 +260,7 @@ void CRender::GenWorldList(struct camera_s *cam) last_frus->parents_count = 1; // created by camera this->ProcessRoom(p, last_frus); // next start reccursion algorithm } - else if(fabs((vec3_plane_dist(p->norm, cam->gl_transform + 12)) <= eps) && + else if((fabs(vec3_plane_dist(p->norm, cam->gl_transform + 12)) <= eps) && (cam_pos[0] <= dest_room->bb_max[0] + eps) && (cam_pos[0] >= dest_room->bb_min[0] - eps) && (cam_pos[1] <= dest_room->bb_max[1] + eps) && (cam_pos[1] >= dest_room->bb_min[1] - eps) && (cam_pos[2] <= dest_room->bb_max[2] + eps) && (cam_pos[2] >= dest_room->bb_min[2] - eps)) @@ -297,7 +297,7 @@ void CRender::GenWorldList(struct camera_s *cam) last_frus->parents_count = 1; // created by camera this->ProcessRoom(p, last_frus); // next start reccursion algorithm } - else if(fabs((vec3_plane_dist(p->norm, cam->gl_transform + 12)) <= eps) && + else if((fabs(vec3_plane_dist(p->norm, cam->gl_transform + 12)) <= eps) && (cam_pos[0] <= dest_room->bb_max[0] + eps) && (cam_pos[0] >= dest_room->bb_min[0] - eps) && (cam_pos[1] <= dest_room->bb_max[1] + eps) && (cam_pos[1] >= dest_room->bb_min[1] - eps) && (cam_pos[2] <= dest_room->bb_max[2] + eps) && (cam_pos[2] >= dest_room->bb_min[2] - eps)) diff --git a/src/resource.cpp b/src/resource.cpp index ff86df78f..5ae296009 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -838,8 +838,8 @@ int Res_Sector_TranslateFloorData(struct room_s *rooms, uint32_t rooms_count, st } else if(raw_x_slant < 0) { - sector->floor_corners[0][2] -= (abs((float)raw_x_slant) * TR_METERING_STEP); - sector->floor_corners[1][2] -= (abs((float)raw_x_slant) * TR_METERING_STEP); + sector->floor_corners[0][2] -= (fabs((float)raw_x_slant) * TR_METERING_STEP); + sector->floor_corners[1][2] -= (fabs((float)raw_x_slant) * TR_METERING_STEP); } if(raw_y_slant > 0) @@ -849,8 +849,8 @@ int Res_Sector_TranslateFloorData(struct room_s *rooms, uint32_t rooms_count, st } else if(raw_y_slant < 0) { - sector->floor_corners[1][2] -= (abs((float)raw_y_slant) * TR_METERING_STEP); - sector->floor_corners[2][2] -= (abs((float)raw_y_slant) * TR_METERING_STEP); + sector->floor_corners[1][2] -= (fabs((float)raw_y_slant) * TR_METERING_STEP); + sector->floor_corners[2][2] -= (fabs((float)raw_y_slant) * TR_METERING_STEP); } entry++; @@ -874,8 +874,8 @@ int Res_Sector_TranslateFloorData(struct room_s *rooms, uint32_t rooms_count, st } else if(raw_x_slant < 0) { - sector->ceiling_corners[1][2] += (abs((float)raw_x_slant) * TR_METERING_STEP); - sector->ceiling_corners[0][2] += (abs((float)raw_x_slant) * TR_METERING_STEP); + sector->ceiling_corners[1][2] += (fabs((float)raw_x_slant) * TR_METERING_STEP); + sector->ceiling_corners[0][2] += (fabs((float)raw_x_slant) * TR_METERING_STEP); } if(raw_y_slant > 0) @@ -885,8 +885,8 @@ int Res_Sector_TranslateFloorData(struct room_s *rooms, uint32_t rooms_count, st } else if(raw_y_slant < 0) { - sector->ceiling_corners[0][2] += (abs((float)raw_y_slant) * TR_METERING_STEP); - sector->ceiling_corners[3][2] += (abs((float)raw_y_slant) * TR_METERING_STEP); + sector->ceiling_corners[0][2] += (fabs((float)raw_y_slant) * TR_METERING_STEP); + sector->ceiling_corners[3][2] += (fabs((float)raw_y_slant) * TR_METERING_STEP); } entry++; diff --git a/src/script.cpp b/src/script.cpp index 5e7f335bc..113ab3a14 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -3076,7 +3076,7 @@ int lua_SetEntityAnim(lua_State * lua) if(top < 4) { - Con_Warning("setEntityAnim: expecting arguments (entity_id, anim_type_id, anim_num, frame_number)"); + Con_Warning("setEntityAnim: expecting arguments (entity_id, anim_type_id, anim_num, frame_number, (next_anim, next_frame))"); return 0; } @@ -3094,6 +3094,11 @@ int lua_SetEntityAnim(lua_State * lua) if(ss_anim) { SSBoneFrame_SetAnimation(ent->bf, anim_type_id, lua_tointeger(lua, 3), lua_tointeger(lua, 4)); + if(top >= 6) + { + ss_anim->next_animation = lua_tointeger(lua, 5); + ss_anim->next_frame = lua_tointeger(lua, 6); + } } return 0; diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 72e3d1f2e..c3bc44009 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -621,7 +621,7 @@ void SSBoneFrame_SetAnimation(struct ss_bone_frame_s *bf, int anim_type, int ani ss_anim->lerp = 0.0; frame %= anim->frames_count; frame = (frame >= 0) ? (frame) : (anim->frames_count - 1 + frame); - ss_anim->period = 1.0 / 30.0; + ss_anim->period = 1.0f / 30.0f; ss_anim->current_state = anim->state_id; ss_anim->next_state = anim->state_id; @@ -630,9 +630,7 @@ void SSBoneFrame_SetAnimation(struct ss_bone_frame_s *bf, int anim_type, int ani ss_anim->current_frame = frame; ss_anim->frame_time = (float)frame * ss_anim->period; - //long int t = (ss_anim->frame_time) / ss_anim->period; - //float dt = ss_anim->frame_time - (float)t * ss_anim->period; - ss_anim->frame_time = (float)frame * ss_anim->period;// + dt; + ss_anim->frame_time = (float)frame * ss_anim->period; } } @@ -794,7 +792,7 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) /* * Next frame and next anim calculation function. */ -void inline Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame) +inline void Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame) { animation_frame_p curr_anim = ss_anim->model->animations + ss_anim->current_animation; if(new_frame + 1 < curr_anim->frames_count) From 522f8d19ebf88b6f4002fb97e43cbbd9266c338c Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sat, 6 Aug 2016 18:41:42 +0400 Subject: [PATCH 07/24] fix build (linker error); --- src/skeletal_model.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/skeletal_model.c b/src/skeletal_model.c index c3bc44009..bad71afba 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -11,6 +11,7 @@ void SSBoneFrame_InitSSAnim(struct ss_animation_s *ss_anim, uint32_t anim_type_id); +void Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame); void SkeletalModel_Clear(skeletal_model_p model) { @@ -792,7 +793,7 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) /* * Next frame and next anim calculation function. */ -inline void Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame) +void Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame) { animation_frame_p curr_anim = ss_anim->model->animations + ss_anim->current_animation; if(new_frame + 1 < curr_anim->frames_count) From 58a3c7acdaf2c3adfc2bb47afa199e5e76ff5fc8 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sun, 7 Aug 2016 22:16:52 +0400 Subject: [PATCH 08/24] changed Anim_SetNextFrame logick: lead_frame == next_frame; --- src/engine.cpp | 2 +- src/entity.cpp | 21 +++++++-------- src/skeletal_model.c | 63 ++++++++++++++++++-------------------------- 3 files changed, 36 insertions(+), 50 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index e4afdf6b4..b1e189b79 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -908,7 +908,7 @@ void ShowDebugInfo() { animation_frame_p anim = ent->bf->animations.model->animations + ent->bf->animations.current_animation; GLText_OutTextXY(30.0f, y += dy, "curr_st = %03d, next_st = %03d", ent->bf->animations.current_state, ent->bf->animations.next_state); - GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_frame = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_frame); + GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_frame = %03d, next_anim = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_frame, anim->next_anim->id); GLText_OutTextXY(30.0f, y += dy, "posX = %f, posY = %f, posZ = %f", ent->transform[12], ent->transform[13], ent->transform[14]); } } diff --git a/src/entity.cpp b/src/entity.cpp index 1191784cb..f2d0f5fb7 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -940,14 +940,14 @@ void Entity_DoAnimTransformCommand(entity_p entity, struct ss_animation_s *ss_an { if(ss_anim->model != NULL) { + animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; animation_frame_p curr_af = ss_anim->model->animations + ss_anim->current_animation; - animation_frame_p prev_af = ss_anim->model->animations + prev_anim; - if((ss_anim->current_frame == 1) && (prev_frame == 0) && (curr_af->command_flags & ANIM_CMD_JUMP)) + if((ss_anim->current_frame == 0) && (next_af->command_flags & ANIM_CMD_JUMP)) { - Character_SetToJump(entity, -curr_af->v_Vertical, curr_af->v_Horizontal); + Character_SetToJump(entity, -next_af->v_Vertical, next_af->v_Horizontal); } - if((changing >= 1) && (curr_af->condition_frame == ss_anim->current_frame) && (curr_af->command_flags & ANIM_CMD_CHANGE_DIRECTION)) + if((changing >= 1) && (next_af->condition_frame == ss_anim->next_frame) && (next_af->command_flags & ANIM_CMD_CHANGE_DIRECTION)) { entity->angles[0] += 180.0f; if(entity->move_type == MOVE_UNDERWATER) @@ -963,18 +963,17 @@ void Entity_DoAnimTransformCommand(entity_p entity, struct ss_animation_s *ss_an entity->dir_flag = ENT_MOVE_BACKWARD; } - /*if(curr_af->condition_frame > 0) - { - Entity_SetAnimation(entity, ANIM_TYPE_BASE, curr_af->next_anim->id, curr_af->next_frame); - }*/ + //ss_anim->current_animation = ss_anim->next_animation; + //ss_anim->current_frame = ss_anim->next_frame; + Anim_SetNextFrame(ss_anim, ss_anim->period, NULL); Entity_UpdateTransform(entity); Entity_UpdateRigidBody(entity, 1); } - if((changing >= 2) && (prev_af->command_flags & ANIM_CMD_MOVE)) + if((changing >= 2) && (curr_af->command_flags & ANIM_CMD_MOVE)) { float tr[3]; entity->no_fix_all = 0x01; - Mat4_vec3_rot_macro(tr, entity->transform, prev_af->move); + Mat4_vec3_rot_macro(tr, entity->transform, curr_af->move); vec3_add(entity->transform + 12, entity->transform + 12, tr); } } @@ -1047,7 +1046,7 @@ void Entity_Frame(entity_p entity, float time) uint16_t frame_switch_state = Anim_SetNextFrame(ss_anim, time, stc); if(frame_switch_state > 0) { - if(frame_switch_state >= 2) + if(frame_switch_state >= 0x02) { entity->no_fix_all = 0x00; } diff --git a/src/skeletal_model.c b/src/skeletal_model.c index bad71afba..9baefb681 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -11,7 +11,6 @@ void SSBoneFrame_InitSSAnim(struct ss_animation_s *ss_anim, uint32_t anim_type_id); -void Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame); void SkeletalModel_Clear(skeletal_model_p model) { @@ -627,11 +626,12 @@ void SSBoneFrame_SetAnimation(struct ss_bone_frame_s *bf, int anim_type, int ani ss_anim->current_state = anim->state_id; ss_anim->next_state = anim->state_id; + ss_anim->next_animation = animation; + ss_anim->next_frame = frame; ss_anim->current_animation = animation; ss_anim->current_frame = frame; ss_anim->frame_time = (float)frame * ss_anim->period; - ss_anim->frame_time = (float)frame * ss_anim->period; } } @@ -793,27 +793,11 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) /* * Next frame and next anim calculation function. */ -void Anim_SetNextAnimFrame(struct ss_animation_s *ss_anim, int32_t new_frame) -{ - animation_frame_p curr_anim = ss_anim->model->animations + ss_anim->current_animation; - if(new_frame + 1 < curr_anim->frames_count) - { - ss_anim->next_frame = new_frame + 1; - ss_anim->next_animation = ss_anim->current_animation; - } - else - { - ss_anim->next_frame = curr_anim->next_frame; - ss_anim->next_animation = curr_anim->next_anim->id; - } -} - - int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc) { float dt; int32_t new_frame; - animation_frame_p curr_anim = ss_anim->model->animations + ss_anim->current_animation; + animation_frame_p next_anim = ss_anim->model->animations + ss_anim->next_animation; ss_anim->frame_time = (ss_anim->frame_time >= 0.0f) ? (ss_anim->frame_time) : (0.0f); ss_anim->frame_time += time; @@ -824,20 +808,20 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ /* * Flag has a highest priority */ - if((new_frame + 1 >= curr_anim->frames_count) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) + if((new_frame + 1 >= next_anim->frames_count) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) { - ss_anim->current_frame = curr_anim->frames_count - 1; - ss_anim->next_frame = ss_anim->current_frame; - ss_anim->next_animation = ss_anim->current_animation; + ss_anim->next_frame = next_anim->frames_count - 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->current_frame * ss_anim->period; + 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->next_frame = ss_anim->current_frame; - ss_anim->next_animation = ss_anim->current_animation; + 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; @@ -853,35 +837,38 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_ { if((disp->frame_high >= disp->frame_low) && ((new_frame >= disp->frame_low) && (new_frame <= disp->frame_high))) { - ss_anim->lerp = 0.0f; - ss_anim->current_animation = disp->next_anim; - ss_anim->current_frame = disp->next_frame; - Anim_SetNextAnimFrame(ss_anim, disp->next_frame); - ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; + 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->current_animation].state_id; ss_anim->next_state = ss_anim->current_state; return 0x03; } } } - Anim_SetNextAnimFrame(ss_anim, new_frame); /* * Check next anim if frame >= frames_count */ - if(new_frame + 1 >= curr_anim->frames_count) + if(new_frame + 1 > next_anim->frames_count) { - ss_anim->current_frame = curr_anim->next_frame; - ss_anim->current_animation = curr_anim->next_anim->id; - ss_anim->frame_time = (float)ss_anim->current_frame * ss_anim->period + dt; + 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->current_animation].state_id; ss_anim->next_state = ss_anim->current_state; return 0x02; } - if(ss_anim->current_frame != new_frame) + if(ss_anim->next_frame != new_frame) { - ss_anim->current_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; return 0x01; } From 8fa3ba789876776da4f86fc7dc73852fab921f7b Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Mon, 8 Aug 2016 20:19:39 +0400 Subject: [PATCH 09/24] Entity_DoAnimTransformCommand moved to Entity_DoAnimCommands function; removed unnecessary fields from animation_frame_s; --- scripts/autoexec.lua | 8 - src/entity.cpp | 452 +++++++++++++++++++++---------------------- src/gui.cpp | 3 +- src/resource.cpp | 80 -------- src/script.cpp | 71 ------- src/skeletal_model.c | 3 +- src/skeletal_model.h | 7 +- 7 files changed, 224 insertions(+), 400 deletions(-) diff --git a/scripts/autoexec.lua b/scripts/autoexec.lua index 8fbb29a6c..5cb4b8f51 100644 --- a/scripts/autoexec.lua +++ b/scripts/autoexec.lua @@ -238,14 +238,6 @@ setModelCollisionMap(0, 12, 6); setModelCollisionMap(0, 13, 10); -- braces 3 setModelCollisionMap(0, 14, 13); ---setAnimCommandTransform(0, 147, 0, 0x00); -- roll animation smooth fix ---setAnimCommandTransform(0, 146, -2, 0x03); - ---if(getLevelVersion() >= TR_II) then --- setAnimCommandTransform(0, 205, 1, 0x00); --- setAnimCommandTransform(0, 203, -2, 0x03); ---end - -- Generate UV rotation texture animations for waterfalls in TR4+ versions if (getLevelVersion() == TR_IV) then diff --git a/src/entity.cpp b/src/entity.cpp index f2d0f5fb7..0cfcda747 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -656,209 +656,245 @@ void Entity_CheckCollisionCallbacks(entity_p ent) void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int changing) { - if((World_GetAnimCommands() == NULL) || (ss_anim->model == NULL) || (changing == 0x00)) + if(World_GetAnimCommands() && ss_anim->model && (changing >= 0x01)) { - return; // If no anim commands - } - - animation_frame_p af = ss_anim->model->animations + ss_anim->current_animation; - if(af->num_anim_commands <= 255) - { - uint32_t count = af->num_anim_commands; - int16_t *pointer = World_GetAnimCommands() + af->anim_command; - int8_t random_value = 0; - - for(uint32_t i = 0; i < count; i++, pointer++) + animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; + if(next_af->num_anim_commands <= 255) { - switch(*pointer) - { - case TR_ANIMCOMMAND_SETPOSITION: - // This command executes ONLY at the end of animation. - pointer += 3; // Parse through 3 operands. - break; - - case TR_ANIMCOMMAND_JUMPDISTANCE: - // This command executes ONLY at the end of animation. - pointer += 2; // Parse through 2 operands. - break; + float params[3]; + uint32_t count = next_af->num_anim_commands; + int16_t *pointer = World_GetAnimCommands() + next_af->anim_command; + int8_t random_value = 0; - case TR_ANIMCOMMAND_EMPTYHANDS: - ///@FIXME: Behaviour is yet to be discovered. - break; - - case TR_ANIMCOMMAND_KILL: - // This command executes ONLY at the end of animation. - if((changing >= 0x02) && (entity->character)) - { - entity->character->resp.kill = 1; - } - break; - - case TR_ANIMCOMMAND_PLAYSOUND: - int16_t sound_index; - if(ss_anim->current_frame == *++pointer) - { - sound_index = *++pointer & 0x3FFF; + for(uint32_t i = 0; i < count; i++, pointer++) + { + switch(*pointer) + { + case TR_ANIMCOMMAND_SETPOSITION: + if(changing >= 2)// This command executes ONLY at the end of animation. + { + float tr[3]; + entity->no_fix_all = 0x01; + params[0] = (float)(*++pointer); // x = x; + params[2] =-(float)(*++pointer); // z =-y + params[1] = (float)(*++pointer); // y = z + Mat4_vec3_rot_macro(tr, entity->transform, params); + vec3_add(entity->transform + 12, entity->transform + 12, tr); + Anim_SetNextFrame(ss_anim, ss_anim->period); + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + } + break; - // Quick workaround for TR3 quicksand. - if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || - (Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_SHALLOW) ) + case TR_ANIMCOMMAND_JUMPDISTANCE: + if(ss_anim->current_frame == 0) // This command executes ONLY at the end of animation. { - sound_index = 18; + params[0] = *++pointer; + params[1] = *++pointer; + Character_SetToJump(entity, -params[0], params[1]); } + break; + + case TR_ANIMCOMMAND_EMPTYHANDS: + ///@FIXME: Behaviour is yet to be discovered. + break; - if(*pointer & TR_ANIMCOMMAND_CONDITION_WATER) + case TR_ANIMCOMMAND_KILL: + // This command executes ONLY at the end of animation. + if((changing >= 0x02) && (entity->character)) { - if(Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_WATER_SHALLOW) - Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); + entity->character->resp.kill = 1; } - else if(*pointer & TR_ANIMCOMMAND_CONDITION_LAND) + break; + + case TR_ANIMCOMMAND_PLAYSOUND: + int16_t sound_index; + if(ss_anim->next_frame == *++pointer) { - if(Entity_GetSubstanceState(entity) != ENTITY_SUBSTANCE_WATER_SHALLOW) + sound_index = *++pointer & 0x3FFF; + + // Quick workaround for TR3 quicksand. + if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || + (Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_SHALLOW) ) + { + sound_index = 18; + } + + if(*pointer & TR_ANIMCOMMAND_CONDITION_WATER) + { + if(Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_WATER_SHALLOW) + Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + else if(*pointer & TR_ANIMCOMMAND_CONDITION_LAND) + { + if(Entity_GetSubstanceState(entity) != ENTITY_SUBSTANCE_WATER_SHALLOW) + Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + else + { Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); + } } else { - Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); + pointer++; } - } - else - { - pointer++; - } - break; + break; - case TR_ANIMCOMMAND_PLAYEFFECT: - // Effects (flipeffects) are various non-typical actions which vary - // across different TR game engine versions. There are common ones, - // however, and currently only these are supported. - if(ss_anim->current_frame == *++pointer) - { - entity_p player = World_GetPlayer(); - switch(*++pointer & 0x3FFF) + case TR_ANIMCOMMAND_PLAYEFFECT: + // Effects (flipeffects) are various non-typical actions which vary + // across different TR game engine versions. There are common ones, + // however, and currently only these are supported. + if(ss_anim->next_frame == *++pointer) { - case TR_EFFECT_SHAKESCREEN: - if(player) - { - float *pos = player->transform + 12; - float dist = vec3_dist(pos, entity->transform + 12); - dist = (dist > TR_CAM_MAX_SHAKE_DISTANCE) ? (0) : ((TR_CAM_MAX_SHAKE_DISTANCE - dist) / 1024.0f); - //if(dist > 0) - // Cam_Shake(&engine_camera, (dist * TR_CAM_DEFAULT_SHAKE_POWER), 0.5); - } - break; - - case TR_EFFECT_CHANGEDIRECTION: - break; - - case TR_EFFECT_HIDEOBJECT: - entity->state_flags &= ~ENTITY_STATE_VISIBLE; - break; - - case TR_EFFECT_SHOWOBJECT: - entity->state_flags |= ENTITY_STATE_VISIBLE; - break; - - case TR_EFFECT_PLAYSTEPSOUND: - // Please note that we bypass land/water mask, as TR3-5 tends to ignore - // this flag and play step sound in any case on land, ignoring it - // completely in water rooms. - if(!Entity_GetSubstanceState(entity)) - { - // TR3-5 footstep map. - // We define it here as a magic numbers array, because TR3-5 versions - // fortunately have no differences in footstep sounds order. - // Also note that some footstep types mutually share same sound IDs - // across different TR versions. - switch(entity->current_sector->material) + entity_p player = World_GetPlayer(); + switch(*++pointer & 0x3FFF) + { + case TR_EFFECT_SHAKESCREEN: + if(player) + { + float *pos = player->transform + 12; + float dist = vec3_dist(pos, entity->transform + 12); + dist = (dist > TR_CAM_MAX_SHAKE_DISTANCE) ? (0) : ((TR_CAM_MAX_SHAKE_DISTANCE - dist) / 1024.0f); + //if(dist > 0) + // Cam_Shake(&engine_camera, (dist * TR_CAM_DEFAULT_SHAKE_POWER), 0.5); + } + break; + + case TR_EFFECT_CHANGEDIRECTION: + if(changing >= 1) + { + entity->angles[0] += 180.0f; + if(entity->move_type == MOVE_UNDERWATER) + { + entity->angles[1] = -entity->angles[1]; // for underwater case + } + if(entity->dir_flag == ENT_MOVE_BACKWARD) + { + entity->dir_flag = ENT_MOVE_FORWARD; + } + else if(entity->dir_flag == ENT_MOVE_FORWARD) + { + entity->dir_flag = ENT_MOVE_BACKWARD; + } + + //ss_anim->current_animation = ss_anim->next_animation; + //ss_anim->current_frame = ss_anim->next_frame; + Anim_SetNextFrame(ss_anim, ss_anim->period); + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + } + break; + + case TR_EFFECT_HIDEOBJECT: + entity->state_flags &= ~ENTITY_STATE_VISIBLE; + break; + + case TR_EFFECT_SHOWOBJECT: + entity->state_flags |= ENTITY_STATE_VISIBLE; + break; + + case TR_EFFECT_PLAYSTEPSOUND: + // Please note that we bypass land/water mask, as TR3-5 tends to ignore + // this flag and play step sound in any case on land, ignoring it + // completely in water rooms. + if(!Entity_GetSubstanceState(entity)) { - case SECTOR_MATERIAL_MUD: - Audio_Send(288, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_SNOW: // TR3 & TR5 only - if(World_GetVersion() != TR_IV) - { - Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - break; - - case SECTOR_MATERIAL_SAND: // Same as grass - Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_GRAVEL: - Audio_Send(290, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_ICE: // TR3 & TR5 only - if(World_GetVersion() != TR_IV) - { - Audio_Send(289, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - break; - - case SECTOR_MATERIAL_WATER: // BYPASS! - // Audio_Send(17, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_STONE: // DEFAULT SOUND, BYPASS! - // Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_WOOD: - Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_METAL: - Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_MARBLE: // TR4 only - if(World_GetVersion() == TR_IV) - { - Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - break; - - case SECTOR_MATERIAL_GRASS: // Same as sand - Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_CONCRETE: // DEFAULT SOUND, BYPASS! - Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_OLDWOOD: // Same as wood - Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_OLDMETAL: // Same as metal - Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; + // TR3-5 footstep map. + // We define it here as a magic numbers array, because TR3-5 versions + // fortunately have no differences in footstep sounds order. + // Also note that some footstep types mutually share same sound IDs + // across different TR versions. + switch(entity->current_sector->material) + { + case SECTOR_MATERIAL_MUD: + Audio_Send(288, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_SNOW: // TR3 & TR5 only + if(World_GetVersion() != TR_IV) + { + Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + case SECTOR_MATERIAL_SAND: // Same as grass + Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_GRAVEL: + Audio_Send(290, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_ICE: // TR3 & TR5 only + if(World_GetVersion() != TR_IV) + { + Audio_Send(289, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + case SECTOR_MATERIAL_WATER: // BYPASS! + // Audio_Send(17, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_STONE: // DEFAULT SOUND, BYPASS! + // Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_WOOD: + Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_METAL: + Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_MARBLE: // TR4 only + if(World_GetVersion() == TR_IV) + { + Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + case SECTOR_MATERIAL_GRASS: // Same as sand + Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_CONCRETE: // DEFAULT SOUND, BYPASS! + Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_OLDWOOD: // Same as wood + Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_OLDMETAL: // Same as metal + Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + } } - } - break; - - case TR_EFFECT_BUBBLE: - ///@FIXME: Spawn bubble particle here, when particle system is developed. - random_value = rand() % 100; - if(random_value > 60) - { - Audio_Send(TR_AUDIO_SOUND_BUBBLE, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - break; - - default: - ///@FIXME: TODO ALL OTHER EFFECTS! - break; + break; + + case TR_EFFECT_BUBBLE: + ///@FIXME: Spawn bubble particle here, when particle system is developed. + random_value = rand() % 100; + if(random_value > 60) + { + Audio_Send(TR_AUDIO_SOUND_BUBBLE, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + default: + ///@FIXME: TODO ALL OTHER EFFECTS! + break; + } } - } - else - { - pointer++; - } - break; + else + { + pointer++; + } + break; + } } } } @@ -936,50 +972,6 @@ void Entity_SetAnimation(entity_p entity, int anim_type, int animation, int fram } -void Entity_DoAnimTransformCommand(entity_p entity, struct ss_animation_s *ss_anim, int16_t prev_anim, int16_t prev_frame, int changing) -{ - if(ss_anim->model != NULL) - { - animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; - animation_frame_p curr_af = ss_anim->model->animations + ss_anim->current_animation; - - if((ss_anim->current_frame == 0) && (next_af->command_flags & ANIM_CMD_JUMP)) - { - Character_SetToJump(entity, -next_af->v_Vertical, next_af->v_Horizontal); - } - if((changing >= 1) && (next_af->condition_frame == ss_anim->next_frame) && (next_af->command_flags & ANIM_CMD_CHANGE_DIRECTION)) - { - entity->angles[0] += 180.0f; - if(entity->move_type == MOVE_UNDERWATER) - { - entity->angles[1] = -entity->angles[1]; // for underwater case - } - if(entity->dir_flag == ENT_MOVE_BACKWARD) - { - entity->dir_flag = ENT_MOVE_FORWARD; - } - else if(entity->dir_flag == ENT_MOVE_FORWARD) - { - entity->dir_flag = ENT_MOVE_BACKWARD; - } - - //ss_anim->current_animation = ss_anim->next_animation; - //ss_anim->current_frame = ss_anim->next_frame; - Anim_SetNextFrame(ss_anim, ss_anim->period, NULL); - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); - } - if((changing >= 2) && (curr_af->command_flags & ANIM_CMD_MOVE)) - { - float tr[3]; - entity->no_fix_all = 0x01; - Mat4_vec3_rot_macro(tr, entity->transform, curr_af->move); - vec3_add(entity->transform + 12, entity->transform + 12, tr); - } - } -} - - void Entity_MoveToSink(entity_p entity, uint32_t sink_index) { static_camera_sink_p sink = World_GetstaticCameraSink(sink_index); @@ -1040,10 +1032,7 @@ void Entity_Frame(entity_p entity, float time) else if(ss_anim->model && !(ss_anim->anim_frame_flags & ANIM_FRAME_LOCK) && ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->frames_count > 1))) { - state_change_p stc = Anim_FindStateChangeByID(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); - int16_t old_anim = ss_anim->current_animation; - int16_t old_frame = ss_anim->current_frame; - uint16_t frame_switch_state = Anim_SetNextFrame(ss_anim, time, stc); + uint16_t frame_switch_state = Anim_SetNextFrame(ss_anim, time); if(frame_switch_state > 0) { if(frame_switch_state >= 0x02) @@ -1051,7 +1040,6 @@ void Entity_Frame(entity_p entity, float time) entity->no_fix_all = 0x00; } Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); - Entity_DoAnimTransformCommand(entity, ss_anim, old_anim, old_frame, frame_switch_state); } // Update acceleration. diff --git a/src/gui.cpp b/src/gui.cpp index c8627af4b..ac8b927be 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -271,8 +271,7 @@ void Gui_Render() */ void Item_Frame(struct ss_bone_frame_s *bf, float time) { - state_change_p stc = Anim_FindStateChangeByID(bf->animations.model->animations + bf->animations.current_animation, bf->animations.next_state); - int frame_switch_state = Anim_SetNextFrame(&bf->animations, time, stc); + int frame_switch_state = Anim_SetNextFrame(&bf->animations, time); //Anim_GetNextFrame(&bf->animations, bf->animations.period, stc, &bf->animations.next_frame, &bf->animations.next_animation, &was_last_anim); SSBoneFrame_Update(bf, time); } diff --git a/src/resource.cpp b/src/resource.cpp index 5ae296009..352f15ba1 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1149,73 +1149,6 @@ int Res_Sector_TranslateFloorData(struct room_s *rooms, uint32_t rooms_count, st return ret; } - -void GenerateAnimCommandsTransform(skeletal_model_p model, int16_t *base_anim_commands_array) -{ - if(!base_anim_commands_array) - { - return; - } - - //Sys_DebugLog("anim_transform.txt", "MODEL[%d]", model->id); - for(uint16_t anim = 0; anim < model->animation_count; anim++) - { - if(model->animations[anim].num_anim_commands > 255) - { - continue; // If no anim commands or current anim has more than 255 (according to TRosettaStone). - } - - animation_frame_p af = model->animations + anim; - int16_t *pointer = base_anim_commands_array + af->anim_command; - - for(uint32_t i = 0; i < af->num_anim_commands; i++, pointer++) - { - switch(*pointer) - { - case TR_ANIMCOMMAND_SETPOSITION: - // This command executes ONLY at the end of animation. - af->move[0] = (float)(*++pointer); // x = x; - af->move[2] =-(float)(*++pointer); // z =-y - af->move[1] = (float)(*++pointer); // y = z - af->command_flags |= ANIM_CMD_MOVE; - //Sys_DebugLog("anim_transform.txt", "move[anim = %d, frame = %d, frames = %d]", anim, af->frames_count-1, af->frames_count); - break; - - case TR_ANIMCOMMAND_JUMPDISTANCE: - af->v_Vertical = *++pointer; - af->v_Horizontal = *++pointer; - af->command_flags |= ANIM_CMD_JUMP; - break; - - case TR_ANIMCOMMAND_EMPTYHANDS: - break; - - case TR_ANIMCOMMAND_KILL: - break; - - case TR_ANIMCOMMAND_PLAYSOUND: - ++pointer; - ++pointer; - break; - - case TR_ANIMCOMMAND_PLAYEFFECT: - { - af->condition_frame = *++pointer; - switch(*++pointer & 0x3FFF) - { - case TR_EFFECT_CHANGEDIRECTION: - af->command_flags |= ANIM_CMD_CHANGE_DIRECTION; - //Con_Printf("ROTATE: anim = %d, frame = %d of %d", anim, frame, af->frames_count); - //Sys_DebugLog("anim_transform.txt", "dir[anim = %d, frame = %d, frames = %d]", anim, frame, af->frames_count); - break; - } - } - break; - } - } - } -} - /** Assign animated texture to a polygon. * While in original TRs we had TexInfo abstraction layer to refer texture, * in OpenTomb we need to re-think animated texture concept to work on a @@ -1705,11 +1638,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct model->animations->state_change = NULL; model->animations->state_change_count = 0; model->animations->original_frame_rate = 1; - model->animations->command_flags = 0x0000; - model->animations->condition_frame = 0xFFFF; - vec3_set_zero(model->animations->move); - model->animations->v_Horizontal = 0.0; - model->animations->v_Vertical = 0.0; bone_frame->bone_tag_count = model->mesh_count; bone_frame->bone_tags = (bone_tag_p)malloc(bone_frame->bone_tag_count * sizeof(bone_tag_t)); @@ -1762,17 +1690,11 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim->id = i; anim->original_frame_rate = tr_animation->frame_rate; - anim->command_flags = 0x0000; - anim->condition_frame = 0xFFFF; anim->speed_x = tr_animation->speed; anim->accel_x = tr_animation->accel; anim->speed_y = tr_animation->accel_lateral; anim->accel_y = tr_animation->speed_lateral; - vec3_set_zero(anim->move); - anim->v_Horizontal = 0.0f; - anim->v_Vertical = 0.0f; - anim->anim_command = tr_animation->anim_command; anim->num_anim_commands = tr_animation->num_anim_commands; anim->state_id = tr_animation->state_id; @@ -2030,8 +1952,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct } } } - - GenerateAnimCommandsTransform(model, base_anim_commands_array); } diff --git a/src/script.cpp b/src/script.cpp index 113ab3a14..a38a0a4cf 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -2202,75 +2202,6 @@ int lua_SetStateChangeRange(lua_State * lua) } -int lua_GetAnimCommandTransform(lua_State * lua) -{ - if(lua_gettop(lua) < 2) - { - Con_Warning("getAnimCommandTransform: expecting arguments (model_id, anim_num)"); - return 0; - } - - int id = lua_tointeger(lua, 1); - int anim = lua_tointeger(lua, 2); - skeletal_model_p model = World_GetModelByID(id); - if(model == NULL) - { - Con_Warning("no skeletal model with id = %d", id); - return 0; - } - - if((anim < 0) || (anim + 1 > model->animation_count)) - { - Con_Warning("wrong anim number = %d", anim); - return 0; - } - - lua_pushinteger(lua, model->animations[anim].anim_command); - lua_pushnumber(lua, model->animations[anim].move[0]); - lua_pushnumber(lua, model->animations[anim].move[1]); - lua_pushnumber(lua, model->animations[anim].move[2]); - - return 4; -} - - -int lua_SetAnimCommandTransform(lua_State * lua) -{ - int top = lua_gettop(lua); - - if(top < 3) - { - Con_Warning("setAnimCommandTransform: expecting arguments (model_id, anim_num, flag, (dx, dy, dz))"); - return 0; - } - - int id = lua_tointeger(lua, 1); - int anim = lua_tointeger(lua, 2); - skeletal_model_p model = World_GetModelByID(id); - if(model == NULL) - { - Con_Warning("no skeletal model with id = %d", id); - return 0; - } - - if((anim < 0) || (anim + 1 > model->animation_count)) - { - Con_Warning("wrong anim number = %d", anim); - return 0; - } - - model->animations[anim].anim_command = 0x00ff & lua_tointeger(lua, 4); - if(top >= 7) - { - model->animations[anim].move[0] = lua_tonumber(lua, 5); - model->animations[anim].move[1] = lua_tonumber(lua, 6); - model->animations[anim].move[2] = lua_tonumber(lua, 7); - } - - return 0; -} - - int lua_SpawnEntity(lua_State * lua) { if(lua_gettop(lua) < 5) @@ -5500,8 +5431,6 @@ void Script_LuaRegisterFuncs(lua_State *lua) lua_register(lua, "getFlipState", lua_GetFlipState); lua_register(lua, "setModelCollisionMap", lua_SetModelCollisionMap); - lua_register(lua, "getAnimCommandTransform", lua_GetAnimCommandTransform); - lua_register(lua, "setAnimCommandTransform", lua_SetAnimCommandTransform); lua_register(lua, "setStateChangeRange", lua_SetStateChangeRange); lua_register(lua, "addItem", lua_AddItem); diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 9baefb681..1e00718a0 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -793,11 +793,12 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) /* * Next frame and next anim calculation function. */ -int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc) +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(ss_anim->model->animations + ss_anim->current_animation, 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; diff --git a/src/skeletal_model.h b/src/skeletal_model.h index 0a0a8e7dd..04d2a9792 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -179,17 +179,12 @@ typedef struct animation_frame_s { uint32_t id; uint16_t original_frame_rate; - uint16_t command_flags; // & 0x01 - move need, &0x02 - 180 rotate need - uint16_t condition_frame; uint16_t state_id; float speed_x; // Forward-backward speed float accel_x; // Forward-backward accel float speed_y; // Left-right speed float accel_y; // Left-right accel - float move[3]; // move command data - float v_Vertical; // jump command data - float v_Horizontal; // jump command data uint32_t anim_command; uint32_t num_anim_commands; @@ -253,7 +248,7 @@ void SSBoneFrame_DisableOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_t struct state_change_s *Anim_FindStateChangeByAnim(struct animation_frame_s *anim, int state_change_anim); struct state_change_s *Anim_FindStateChangeByID(struct animation_frame_s *anim, uint32_t id); int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id); -int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time, struct state_change_s *stc); +int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time); #ifdef __cplusplus } From 7f39835a363997038bf60900bea863dc01ba90ec Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Tue, 9 Aug 2016 21:09:04 +0400 Subject: [PATCH 10/24] fixed animation initialization; fixed state change in Anim_SetNextFrame; --- src/entity.cpp | 18 +++++++++++------- src/resource.cpp | 2 +- src/script.cpp | 2 +- src/skeletal_model.c | 16 +++------------- src/skeletal_model.h | 2 +- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index 0cfcda747..aef7d57e2 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -959,15 +959,19 @@ void Entity_SetAnimation(entity_p entity, int anim_type, int animation, int fram { if(entity) { - animation = (animation < 0) ? (0) : (animation); - entity->no_fix_all = 0x00; - - if(anim_type == ANIM_TYPE_BASE) + ss_animation_p ss_anim = SSBoneFrame_GetOverrideAnim(entity->bf, anim_type); + if(ss_anim) { - entity->anim_linear_speed = entity->bf->animations.model->animations[animation].speed_x; + animation = (animation < 0) ? (0) : (animation); + entity->no_fix_all = 0x00; + + if(anim_type == ANIM_TYPE_BASE) + { + entity->anim_linear_speed = entity->bf->animations.model->animations[animation].speed_x; + } + SSBoneFrame_SetAnimation(ss_anim, animation, frame); + SSBoneFrame_Update(entity->bf, 0.0f); } - SSBoneFrame_SetAnimation(entity->bf, anim_type, animation, frame); - SSBoneFrame_Update(entity->bf, 0.0f); } } diff --git a/src/resource.cpp b/src/resource.cpp index 352f15ba1..7e88a57c7 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1633,7 +1633,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct bone_frame = model->animations->frames; model->animations->id = 0; - model->animations->next_anim = model->animations->next_anim; + model->animations->next_anim = model->animations; model->animations->next_frame = 0; model->animations->state_change = NULL; model->animations->state_change_count = 0; diff --git a/src/script.cpp b/src/script.cpp index a38a0a4cf..9b6e4599e 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -3024,7 +3024,7 @@ int lua_SetEntityAnim(lua_State * lua) ss_animation_p ss_anim = SSBoneFrame_GetOverrideAnim(ent->bf, anim_type_id); if(ss_anim) { - SSBoneFrame_SetAnimation(ent->bf, anim_type_id, lua_tointeger(lua, 3), lua_tointeger(lua, 4)); + SSBoneFrame_SetAnimation(ss_anim, lua_tointeger(lua, 3), lua_tointeger(lua, 4)); if(top >= 6) { ss_anim->next_animation = lua_tointeger(lua, 5); diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 1e00718a0..908f2ad5a 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -603,18 +603,8 @@ void SSBoneFrame_SetTargetingLimit(struct ss_animation_s *ss_anim, const float l } -void SSBoneFrame_SetAnimation(struct ss_bone_frame_s *bf, int anim_type, int animation, int frame) +void SSBoneFrame_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame) { - ss_animation_p ss_anim = NULL; - for(ss_animation_p ss_anim_it = &bf->animations; ss_anim_it; ss_anim_it = ss_anim_it->next) - { - if(ss_anim_it->type == anim_type) - { - ss_anim = ss_anim_it; - break; - } - } - if(ss_anim && ss_anim->model && (animation < ss_anim->model->animation_count)) { animation_frame_p anim = &ss_anim->model->animations[animation]; @@ -843,7 +833,7 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) 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->current_animation].state_id; + ss_anim->current_state = ss_anim->model->animations[ss_anim->next_animation].state_id; ss_anim->next_state = ss_anim->current_state; return 0x03; } @@ -860,7 +850,7 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) 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->current_animation].state_id; + ss_anim->current_state = ss_anim->model->animations[ss_anim->next_animation].state_id; ss_anim->next_state = ss_anim->current_state; return 0x02; } diff --git a/src/skeletal_model.h b/src/skeletal_model.h index 04d2a9792..97ed21e82 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -238,7 +238,7 @@ void SSBoneFrame_TargetBoneToSlerp(struct ss_bone_frame_s *bf, struct ss_animati void SSBoneFrame_SetTrget(struct ss_animation_s *ss_anim, uint16_t targeted_bone, const float target_pos[3], const float bone_dir[3]); void SSBoneFrame_SetTargetingAxisMod(struct ss_animation_s *ss_anim, const float mod[3]); void SSBoneFrame_SetTargetingLimit(struct ss_animation_s *ss_anim, const float limit[4]); -void SSBoneFrame_SetAnimation(struct ss_bone_frame_s *bf, int anim_type, int animation, int frame); +void SSBoneFrame_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame); struct ss_animation_s *SSBoneFrame_AddOverrideAnim(struct ss_bone_frame_s *bf, struct skeletal_model_s *sm, uint16_t anim_type_id); struct ss_animation_s *SSBoneFrame_GetOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_type); void SSBoneFrame_EnableOverrideAnimByType(struct ss_bone_frame_s *bf, uint16_t anim_type); From ca5a0786dd6afb1a5a1c422dc7cb9c93da1d4dca Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Wed, 10 Aug 2016 19:57:07 +0400 Subject: [PATCH 11/24] fixed jump animation command condition; --- src/entity.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index aef7d57e2..5d14a5c16 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -671,7 +671,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int switch(*pointer) { case TR_ANIMCOMMAND_SETPOSITION: - if(changing >= 2)// This command executes ONLY at the end of animation. + if(changing >= 0x2) // This command executes ONLY at the end of animation. { float tr[3]; entity->no_fix_all = 0x01; @@ -687,7 +687,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int break; case TR_ANIMCOMMAND_JUMPDISTANCE: - if(ss_anim->current_frame == 0) // This command executes ONLY at the end of animation. + if(changing >= 2) // This command executes ONLY at the end of animation. { params[0] = *++pointer; params[1] = *++pointer; @@ -1016,7 +1016,6 @@ void Entity_Frame(entity_p entity, float time) { if(entity && !(entity->type_flags & ENTITY_TYPE_DYNAMIC) && (entity->state_flags & ENTITY_STATE_ACTIVE) && (entity->state_flags & ENTITY_STATE_ENABLED)) { - animation_frame_p af; ss_animation_p ss_anim = &entity->bf->animations; Entity_GhostUpdate(entity); @@ -1025,9 +1024,10 @@ void Entity_Frame(entity_p entity, float time) { if(ss_anim->enabled) { + int frame_switch_state = 0x00; if(ss_anim->model && ss_anim->onFrame) { - int frame_switch_state = ss_anim->onFrame(entity, ss_anim, time); + frame_switch_state = ss_anim->onFrame(entity, ss_anim, time); if(ss_anim->onEndFrame != NULL) { ss_anim->onEndFrame(entity, ss_anim, frame_switch_state); @@ -1036,8 +1036,8 @@ void Entity_Frame(entity_p entity, float time) else if(ss_anim->model && !(ss_anim->anim_frame_flags & ANIM_FRAME_LOCK) && ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->frames_count > 1))) { - uint16_t frame_switch_state = Anim_SetNextFrame(ss_anim, time); - if(frame_switch_state > 0) + frame_switch_state = Anim_SetNextFrame(ss_anim, time); + if(frame_switch_state > 0x01) { if(frame_switch_state >= 0x02) { @@ -1049,11 +1049,11 @@ void Entity_Frame(entity_p entity, float time) // Update acceleration. // With variable framerate, we don't know when we'll reach final // frame for sure, so we use native frame number check to increase acceleration. - af = ss_anim->model->animations + ss_anim->current_animation; if((ss_anim->type == ANIM_TYPE_BASE) && (entity->character) && (frame_switch_state > 0)) { - // NB!!! For Lara, we update ONLY X-axis speed/accel. - if((af->accel_x == 0) || (frame_switch_state > 1)) + animation_frame_p af = ss_anim->model->animations + ss_anim->next_animation; + // NB!!! For Lara, we update ONLY X-axis speed / accel. + if((af->accel_x == 0) || (frame_switch_state >= 0x02)) { entity->anim_linear_speed = af->speed_x; } From f7ffc74b7613524d62835dc7f7d010764c570018 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Fri, 12 Aug 2016 21:48:58 +0400 Subject: [PATCH 12/24] added command fields with additional frame interpolation info; fixed DoAnimCommand condition; --- src/anim_state_control.cpp | 4 ++-- src/entity.cpp | 28 ++++++++++++++-------------- src/skeletal_model.h | 4 ++++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/anim_state_control.cpp b/src/anim_state_control.cpp index 6849b46ae..e9d99911f 100644 --- a/src/anim_state_control.cpp +++ b/src/anim_state_control.cpp @@ -118,7 +118,7 @@ void ent_correct_diving_angle(entity_p ent, ss_animation_p ss_anim, int state) { if(state >= 0x02) { - ent->angles[1] = -45.0; + ent->angles[1] = -45.0f; Entity_UpdateTransform(ent); ss_anim->onEndFrame = NULL; } @@ -140,7 +140,7 @@ void ent_climb_out_of_water(entity_p ent, ss_animation_p ss_anim, int state) if(state >= 0x02) { float *v = ent->character->climb.point; - vec3_add_mul(ent->transform + 12, v, ent->transform + 4, 48.0); // temporary stick + vec3_add_mul(ent->transform + 12, v, ent->transform + 4, 48.0f); // temporary stick ent->transform[12 + 2] = v[2]; SSBoneFrame_Update(ent->bf, 0.0f); Entity_UpdateRigidBody(ent, 1); diff --git a/src/entity.cpp b/src/entity.cpp index 5d14a5c16..0ccd10bd7 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -661,7 +661,6 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; if(next_af->num_anim_commands <= 255) { - float params[3]; uint32_t count = next_af->num_anim_commands; int16_t *pointer = World_GetAnimCommands() + next_af->anim_command; int8_t random_value = 0; @@ -675,10 +674,11 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int { float tr[3]; entity->no_fix_all = 0x01; - params[0] = (float)(*++pointer); // x = x; - params[2] =-(float)(*++pointer); // z =-y - params[1] = (float)(*++pointer); // y = z - Mat4_vec3_rot_macro(tr, entity->transform, params); + entity->bf->move_cmd = 0x01; + entity->bf->move_data[0] = (float)(*++pointer); // x = x; + entity->bf->move_data[2] =-(float)(*++pointer); // z =-y + entity->bf->move_data[1] = (float)(*++pointer); // y = z + Mat4_vec3_rot_macro(tr, entity->transform, entity->bf->move_data); vec3_add(entity->transform + 12, entity->transform + 12, tr); Anim_SetNextFrame(ss_anim, ss_anim->period); Entity_UpdateTransform(entity); @@ -687,11 +687,11 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int break; case TR_ANIMCOMMAND_JUMPDISTANCE: - if(changing >= 2) // This command executes ONLY at the end of animation. + if(changing >= 0x02) // This command executes ONLY at the end of animation. { - params[0] = *++pointer; - params[1] = *++pointer; - Character_SetToJump(entity, -params[0], params[1]); + float vz = *++pointer; + float vh = *++pointer; + Character_SetToJump(entity, -vz, vh); } break; @@ -708,10 +708,9 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int break; case TR_ANIMCOMMAND_PLAYSOUND: - int16_t sound_index; if(ss_anim->next_frame == *++pointer) { - sound_index = *++pointer & 0x3FFF; + int16_t sound_index = (*++pointer) & 0x3FFF; // Quick workaround for TR3 quicksand. if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || @@ -762,8 +761,9 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int break; case TR_EFFECT_CHANGEDIRECTION: - if(changing >= 1) + if(changing >= 0x01) { + entity->bf->change_dir_cmd = 0x01; entity->angles[0] += 180.0f; if(entity->move_type == MOVE_UNDERWATER) { @@ -1037,7 +1037,7 @@ void Entity_Frame(entity_p entity, float time) ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->frames_count > 1))) { frame_switch_state = Anim_SetNextFrame(ss_anim, time); - if(frame_switch_state > 0x01) + if(frame_switch_state >= 0x01) { if(frame_switch_state >= 0x02) { @@ -1055,7 +1055,7 @@ void Entity_Frame(entity_p entity, float time) // NB!!! For Lara, we update ONLY X-axis speed / accel. if((af->accel_x == 0) || (frame_switch_state >= 0x02)) { - entity->anim_linear_speed = af->speed_x; + entity->anim_linear_speed = af->speed_x; } else { diff --git a/src/skeletal_model.h b/src/skeletal_model.h index 97ed21e82..d792f722c 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -106,6 +106,10 @@ typedef struct ss_animation_s typedef struct ss_bone_frame_s { uint16_t bone_tag_count; // number of bones + uint16_t change_dir_cmd : 1; + uint16_t move_cmd : 1; + float move_data[3]; + struct ss_bone_tag_s *bone_tags; // array of bones float pos[3]; // position (base offset) float bb_min[3]; // bounding box min coordinates From 92b8d2d2479e0637b380e76bf29ccd6ffdb184ee Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sun, 14 Aug 2016 20:35:25 +0400 Subject: [PATCH 13/24] frame change type now are stored in ss_animation_s structure; --- src/anim_state_control.cpp | 52 +++++++++++++++++++------------------- src/entity.cpp | 21 +++++++-------- src/entity.h | 2 +- src/skeletal_model.c | 12 +++++++++ src/skeletal_model.h | 5 ++-- 5 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/anim_state_control.cpp b/src/anim_state_control.cpp index e9d99911f..62ba28e01 100644 --- a/src/anim_state_control.cpp +++ b/src/anim_state_control.cpp @@ -49,9 +49,9 @@ #define OSCILLATE_HANG_USE 0 -void ent_stop_traverse(entity_p ent, ss_animation_p ss_anim, int state) +void ent_stop_traverse(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { float *v = ent->character->traversed_object->transform + 12; int i = v[0] / TR_METERING_SECTORSIZE; @@ -65,9 +65,9 @@ void ent_stop_traverse(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_set_on_floor(entity_p ent, ss_animation_p ss_anim, int state) +void ent_set_on_floor(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { ent->move_type = MOVE_ON_FLOOR; ent->transform[12 + 2] = ent->character->height_info.floor_hit.point[2]; @@ -78,45 +78,45 @@ void ent_set_on_floor(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_set_turn_fast(entity_p ent, ss_animation_p ss_anim, int state) +void ent_set_turn_fast(entity_p ent, ss_animation_p ss_anim) { - if(state == 0x02) + if(ss_anim->changing_next == 0x02) { ent->bf->animations.next_state = TR_STATE_LARA_TURN_FAST; ss_anim->onEndFrame = NULL; } } -void ent_set_underwater(entity_p ent, ss_animation_p ss_anim, int state) +void ent_set_underwater(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { ent->move_type = MOVE_UNDERWATER; ss_anim->onEndFrame = NULL; } } -void ent_set_free_falling(entity_p ent, ss_animation_p ss_anim, int state) +void ent_set_free_falling(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { ent->move_type = MOVE_FREE_FALLING; ss_anim->onEndFrame = NULL; } } -void ent_set_cmd_slide(entity_p ent, ss_animation_p ss_anim, int state) +void ent_set_cmd_slide(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { ent->character->resp.slide = 0x01; ss_anim->onEndFrame = NULL; } } -void ent_correct_diving_angle(entity_p ent, ss_animation_p ss_anim, int state) +void ent_correct_diving_angle(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { ent->angles[1] = -45.0f; Entity_UpdateTransform(ent); @@ -124,9 +124,9 @@ void ent_correct_diving_angle(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_to_on_water(entity_p ent, ss_animation_p ss_anim, int state) +void ent_to_on_water(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { ent->transform[12 + 2] = ent->character->height_info.transition_level; Entity_GhostUpdate(ent); @@ -135,9 +135,9 @@ void ent_to_on_water(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_climb_out_of_water(entity_p ent, ss_animation_p ss_anim, int state) +void ent_climb_out_of_water(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { float *v = ent->character->climb.point; vec3_add_mul(ent->transform + 12, v, ent->transform + 4, 48.0f); // temporary stick @@ -149,9 +149,9 @@ void ent_climb_out_of_water(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_to_edge_climb(entity_p ent, ss_animation_p ss_anim, int state) +void ent_to_edge_climb(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { float *v = ent->character->climb.point; ent->transform[12 + 0] = v[0] - ent->transform[4 + 0] * ent->bf->bb_max[1]; @@ -164,9 +164,9 @@ void ent_to_edge_climb(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_to_monkey_swing(entity_p ent, ss_animation_p ss_anim, int state) +void ent_to_monkey_swing(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { ent->move_type = MOVE_MONKEYSWING; ent->transform[12 + 2] = ent->character->height_info.ceiling_hit.point[2] - ent->bf->bb_max[2]; @@ -175,9 +175,9 @@ void ent_to_monkey_swing(entity_p ent, ss_animation_p ss_anim, int state) } } -void ent_crawl_to_climb(entity_p ent, ss_animation_p ss_anim, int state) +void ent_crawl_to_climb(entity_p ent, ss_animation_p ss_anim) { - if(state >= 0x02) + if(ss_anim->changing_next >= 0x02) { character_command_p cmd = &ent->character->cmd; @@ -193,7 +193,7 @@ void ent_crawl_to_climb(entity_p ent, ss_animation_p ss_anim, int state) } ent->no_fix_all = 0x01; - ent_to_edge_climb(ent, ss_anim, state); + ent_to_edge_climb(ent, ss_anim); ss_anim->onEndFrame = NULL; } } @@ -2516,7 +2516,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) if(low_vertical_space) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_LARA_ONWATER_TO_LAND_LOW, 0); - ent_climb_out_of_water(ent, ss_anim, 0x02); + ent_climb_out_of_water(ent, ss_anim); } else { diff --git a/src/entity.cpp b/src/entity.cpp index 0ccd10bd7..bf9137306 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -654,11 +654,13 @@ void Entity_CheckCollisionCallbacks(entity_p ent) } -void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int changing) +void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) { - if(World_GetAnimCommands() && ss_anim->model && (changing >= 0x01)) + if(World_GetAnimCommands() && ss_anim->model) { animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; + entity->bf->move_cmd = 0x00; + entity->bf->change_dir_cmd = 0x00; if(next_af->num_anim_commands <= 255) { uint32_t count = next_af->num_anim_commands; @@ -670,7 +672,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int switch(*pointer) { case TR_ANIMCOMMAND_SETPOSITION: - if(changing >= 0x2) // This command executes ONLY at the end of animation. + if(ss_anim->changing_next >= 0x02) // This command executes ONLY at the end of animation. { float tr[3]; entity->no_fix_all = 0x01; @@ -687,7 +689,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int break; case TR_ANIMCOMMAND_JUMPDISTANCE: - if(changing >= 0x02) // This command executes ONLY at the end of animation. + if(ss_anim->changing_next >= 0x02) // This command executes ONLY at the end of animation. { float vz = *++pointer; float vh = *++pointer; @@ -701,7 +703,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int case TR_ANIMCOMMAND_KILL: // This command executes ONLY at the end of animation. - if((changing >= 0x02) && (entity->character)) + if((ss_anim->changing_next >= 0x02) && (entity->character)) { entity->character->resp.kill = 1; } @@ -711,7 +713,6 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int if(ss_anim->next_frame == *++pointer) { int16_t sound_index = (*++pointer) & 0x3FFF; - // Quick workaround for TR3 quicksand. if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || (Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_SHALLOW) ) @@ -761,7 +762,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int break; case TR_EFFECT_CHANGEDIRECTION: - if(changing >= 0x01) + if(ss_anim->changing_next >= 0x01) { entity->bf->change_dir_cmd = 0x01; entity->angles[0] += 180.0f; @@ -1030,7 +1031,7 @@ void Entity_Frame(entity_p entity, float time) frame_switch_state = ss_anim->onFrame(entity, ss_anim, time); if(ss_anim->onEndFrame != NULL) { - ss_anim->onEndFrame(entity, ss_anim, frame_switch_state); + ss_anim->onEndFrame(entity, ss_anim); } } else if(ss_anim->model && !(ss_anim->anim_frame_flags & ANIM_FRAME_LOCK) && @@ -1043,7 +1044,7 @@ void Entity_Frame(entity_p entity, float time) { entity->no_fix_all = 0x00; } - Entity_DoAnimCommands(entity, ss_anim, frame_switch_state); + Entity_DoAnimCommands(entity, ss_anim); } // Update acceleration. @@ -1065,7 +1066,7 @@ void Entity_Frame(entity_p entity, float time) if(ss_anim->onEndFrame != NULL) { - ss_anim->onEndFrame(entity, ss_anim, frame_switch_state); + ss_anim->onEndFrame(entity, ss_anim); } } } diff --git a/src/entity.h b/src/entity.h index f434c53b9..c31531703 100644 --- a/src/entity.h +++ b/src/entity.h @@ -124,7 +124,7 @@ int Entity_CheckNextPenetration(struct entity_s *ent, float move[3]); void Entity_FixPenetrations(struct entity_s *ent, float move[3]); void Entity_CheckCollisionCallbacks(entity_p ent); -void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim, int changing); +void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim); void Entity_ProcessSector(entity_p ent); void Entity_SetAnimation(entity_p entity, int anim_type, int animation, int frame); void Entity_MoveToSink(entity_p entity, uint32_t sink_index); diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 908f2ad5a..68af772f8 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -613,6 +613,9 @@ void SSBoneFrame_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame = (frame >= 0) ? (frame) : (anim->frames_count - 1 + frame); ss_anim->period = 1.0f / 30.0f; + ss_anim->changing_curr = 0x03; + ss_anim->changing_next = 0x03; + ss_anim->current_state = anim->state_id; ss_anim->next_state = anim->state_id; @@ -796,6 +799,9 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) 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 */ @@ -835,6 +841,8 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) 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; } } @@ -852,6 +860,8 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) 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; } @@ -860,6 +870,8 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) 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; } diff --git a/src/skeletal_model.h b/src/skeletal_model.h index d792f722c..72df5881c 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -70,7 +70,8 @@ typedef struct ss_animation_s { uint16_t type : 15; uint16_t enabled : 1; - uint16_t unused; + uint16_t changing_next : 8; + uint16_t changing_curr : 8; int16_t current_state; int16_t next_state; int16_t current_animation; @@ -94,7 +95,7 @@ typedef struct ss_animation_s float lerp; int (*onFrame)(struct entity_s *ent, struct ss_animation_s *ss_anim, float time); - void (*onEndFrame)(struct entity_s *ent, struct ss_animation_s *ss_anim, int state); + void (*onEndFrame)(struct entity_s *ent, struct ss_animation_s *ss_anim); struct skeletal_model_s *model; // pointer to the base model struct ss_animation_s *next; struct ss_animation_s *prev; From 7a07992fc0cb9ba06d7ffd6c47f48971be2a1232 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Thu, 18 Aug 2016 22:20:14 +0400 Subject: [PATCH 14/24] restored ent_set_on_floor_after_climb function; fixed anim command pointer increment; fixed onEndFrame logick and move command; --- autoexec.lua | 4 ++-- src/anim_state_control.cpp | 30 +++++++++++++++++++++++++++++- src/character_controller.cpp | 36 ++++++++++++++++++++++++++++++------ src/engine.cpp | 11 ++++++----- src/entity.cpp | 22 ++++++++++++++++++---- 5 files changed, 85 insertions(+), 18 deletions(-) diff --git a/autoexec.lua b/autoexec.lua index 487518fdd..eaeeb68c3 100644 --- a/autoexec.lua +++ b/autoexec.lua @@ -20,5 +20,5 @@ noclip(0); --loadMap("data/LEVEL1.PHD"); --loadMap("tests/altroom1/LEVEL1.PHD"); --loadMap("tests/heavy1/LEVEL1.PHD"); -setgamef(4, 1); ---dofile("save/pad"); \ No newline at end of file +--setgamef(4, 1); +dofile("save/qsave.lua"); \ No newline at end of file diff --git a/src/anim_state_control.cpp b/src/anim_state_control.cpp index 62ba28e01..1dee697c3 100644 --- a/src/anim_state_control.cpp +++ b/src/anim_state_control.cpp @@ -78,6 +78,27 @@ void ent_set_on_floor(entity_p ent, ss_animation_p ss_anim) } } +void ent_set_on_floor_after_climb(entity_p ent, ss_animation_p ss_anim) +{ + animation_frame_p af = ss_anim->model->animations + ss_anim->current_animation; + if(ss_anim->changing_next >= 0x02) + { + float p[3], move[3]; + + Mat4_vec3_mul(move, ent->transform, ent->bf->bone_tags[0].full_transform + 12); + Entity_SetAnimation(ent, ANIM_TYPE_BASE, af->next_anim->id, af->next_frame); + Mat4_vec3_mul(p, ent->transform, ent->bf->bone_tags[0].full_transform + 12); + vec3_sub(move, move, p); + vec3_add(ent->transform + 12, ent->transform + 12, move); + ent->transform[12 + 2] = ent->character->climb.point[2]; + SSBoneFrame_Update(ent->bf, 0.0f); + Entity_UpdateRigidBody(ent, 1); + Entity_GhostUpdate(ent); + ent->move_type = MOVE_ON_FLOOR; + ss_anim->onEndFrame = NULL; + } +} + void ent_set_turn_fast(entity_p ent, ss_animation_p ss_anim) { if(ss_anim->changing_next == 0x02) @@ -145,13 +166,14 @@ void ent_climb_out_of_water(entity_p ent, ss_animation_p ss_anim) SSBoneFrame_Update(ent->bf, 0.0f); Entity_UpdateRigidBody(ent, 1); Entity_GhostUpdate(ent); + ent->no_fix_all = 0x01; ss_anim->onEndFrame = NULL; } } void ent_to_edge_climb(entity_p ent, ss_animation_p ss_anim) { - if(ss_anim->changing_next >= 0x02) + if(ss_anim->changing_next >= 0x01) { float *v = ent->character->climb.point; ent->transform[12 + 0] = v[0] - ent->transform[4 + 0] * ent->bf->bb_max[1]; @@ -420,6 +442,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) pos[2] = climb->edge_point[2] - 512.0; vec3_copy(climb->point, climb->edge_point); Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_LARA_CLIMB_2CLICK, 0); + ss_anim->onEndFrame = ent_set_on_floor_after_climb; ent->no_fix_all = 0x01; break; } @@ -429,6 +452,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) pos[2] = climb->edge_point[2] - 768.0; vec3_copy(climb->point, climb->edge_point); Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_LARA_CLIMB_3CLICK, 0); + ss_anim->onEndFrame = ent_set_on_floor_after_climb; ent->no_fix_all = 0x01; break; } @@ -1777,6 +1801,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) case TR_STATE_LARA_CLIMB_TO_CRAWL: cmd->rot[0] = 0; ent->no_fix_all = 0x01; + ss_anim->onEndFrame = ent_set_on_floor_after_climb;; break; case TR_STATE_LARA_HANG: @@ -1867,11 +1892,13 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) { vec3_copy(climb->point, climb->edge_point); ss_anim->next_state = TR_STATE_LARA_CLIMB_TO_CRAWL; // crawlspace climb + ss_anim->onEndFrame = ent_to_edge_climb; } else if(climb->edge_hit && (climb->next_z_space >= ent->character->Height - LARA_HANG_VERTICAL_EPSILON)) { vec3_copy(climb->point, climb->edge_point); ss_anim->next_state = (cmd->shift)?(TR_STATE_LARA_HANDSTAND):(TR_STATE_LARA_GRABBING); // climb up + ss_anim->onEndFrame = ent_to_edge_climb; } else { @@ -2207,6 +2234,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) case TR_STATE_LARA_ONWATER_EXIT: cmd->rot[0] = 0; ent->no_fix_all = 0x01; + ss_anim->onEndFrame = ent_set_on_floor_after_climb; break; case TR_STATE_LARA_JUMP_FORWARD: diff --git a/src/character_controller.cpp b/src/character_controller.cpp index 67b564912..470af87b9 100644 --- a/src/character_controller.cpp +++ b/src/character_controller.cpp @@ -1154,19 +1154,19 @@ int Character_MoveOnFloor(struct entity_s *ent) if(ent->dir_flag & ENT_MOVE_FORWARD) { - vec3_mul_scalar(ent->speed, ent->transform+4, t); + vec3_mul_scalar(ent->speed, ent->transform + 4, t); } else if(ent->dir_flag & ENT_MOVE_BACKWARD) { - vec3_mul_scalar(ent->speed, ent->transform+4,-t); + vec3_mul_scalar(ent->speed, ent->transform + 4,-t); } else if(ent->dir_flag & ENT_MOVE_LEFT) { - vec3_mul_scalar(ent->speed, ent->transform+0,-t); + vec3_mul_scalar(ent->speed, ent->transform + 0,-t); } else if(ent->dir_flag & ENT_MOVE_RIGHT) { - vec3_mul_scalar(ent->speed, ent->transform+0, t); + vec3_mul_scalar(ent->speed, ent->transform + 0, t); } else { @@ -2373,6 +2373,9 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * * 2: draw weapon (full); * 3: fire process; */ + int16_t old_anim = ss_anim->next_animation; + int16_t old_frame = ss_anim->next_frame; + if(ss_anim->model->animation_count == 4) { const float bone_dir[] = {0.0f, 1.0f, 0.0f}; @@ -2612,7 +2615,16 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * break; }; } - return 1; + + if(old_anim != ss_anim->next_animation) + { + return 0x03; + } + if(old_frame != ss_anim->next_frame) + { + return 0x01; + } + return 0x00; } @@ -2626,6 +2638,9 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * * 3: hide weapon; * 4: idle to fire (targeted); */ + int16_t old_anim = ss_anim->next_animation; + int16_t old_frame = ss_anim->next_frame; + if(ss_anim->model->animation_count > 4) { float dt; @@ -2857,5 +2872,14 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * break; }; } - return 1; + + if(old_anim != ss_anim->next_animation) + { + return 0x03; + } + if(old_frame != ss_anim->next_frame) + { + return 0x01; + } + return 0x00; } diff --git a/src/engine.cpp b/src/engine.cpp index b1e189b79..7e3bbd7d3 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -55,7 +55,7 @@ static ALCdevice *al_device = NULL; static ALCcontext *al_context = NULL; static volatile int engine_done = 0; -static int engine_set_sero_time = 0; +static int engine_set_zero_time = 0; float time_scale = 1.0f; engine_container_p last_cont = NULL; @@ -796,9 +796,9 @@ void Engine_MainLoop() oldtime = newtime; time *= time_scale; - if(engine_set_sero_time) + if(engine_set_zero_time) { - engine_set_sero_time = 0; + engine_set_zero_time = 0; time = 0.0f; } @@ -908,7 +908,8 @@ void ShowDebugInfo() { animation_frame_p anim = ent->bf->animations.model->animations + ent->bf->animations.current_animation; GLText_OutTextXY(30.0f, y += dy, "curr_st = %03d, next_st = %03d", ent->bf->animations.current_state, ent->bf->animations.next_state); - GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_frame = %03d, next_anim = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_frame, anim->next_anim->id); + GLText_OutTextXY(30.0f, y += dy, "curr_anim = %03d, curr_frame = %03d, next_anim = %03d, next_frame = %03d", ent->bf->animations.current_animation, ent->bf->animations.current_frame, ent->bf->animations.next_animation, ent->bf->animations.next_frame); + GLText_OutTextXY(30.0f, y += dy, "anim_next_anim = %03d, anim_next_frame = %03d", anim->next_anim->id, anim->next_frame); GLText_OutTextXY(30.0f, y += dy, "posX = %f, posY = %f, posZ = %f", ent->transform[12], ent->transform[13], ent->transform[14]); } } @@ -1162,7 +1163,7 @@ int Engine_LoadMap(const char *name) Gui_DrawLoadScreen(1000); Gui_NotifierStop(); - engine_set_sero_time = 1; + engine_set_zero_time = 1; return 1; } diff --git a/src/entity.cpp b/src/entity.cpp index bf9137306..5c3f5dd4b 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -672,7 +672,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) switch(*pointer) { case TR_ANIMCOMMAND_SETPOSITION: - if(ss_anim->changing_next >= 0x02) // This command executes ONLY at the end of animation. + if((ss_anim->changing_next >= 0x02) && (ss_anim->onEndFrame == NULL)) // This command executes ONLY at the end of animation. { float tr[3]; entity->no_fix_all = 0x01; @@ -686,6 +686,10 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) Entity_UpdateTransform(entity); Entity_UpdateRigidBody(entity, 1); } + else + { + pointer += 3; + } break; case TR_ANIMCOMMAND_JUMPDISTANCE: @@ -695,6 +699,10 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) float vh = *++pointer; Character_SetToJump(entity, -vz, vh); } + else + { + pointer += 2; + } break; case TR_ANIMCOMMAND_EMPTYHANDS: @@ -895,7 +903,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) pointer++; } break; - } + }; } } } @@ -1029,7 +1037,13 @@ void Entity_Frame(entity_p entity, float time) if(ss_anim->model && ss_anim->onFrame) { frame_switch_state = ss_anim->onFrame(entity, ss_anim, time); - if(ss_anim->onEndFrame != NULL) + + if(frame_switch_state >= 0x01) + { + Entity_DoAnimCommands(entity, ss_anim); + } + + if(ss_anim->onEndFrame) { ss_anim->onEndFrame(entity, ss_anim); } @@ -1064,7 +1078,7 @@ void Entity_Frame(entity_p entity, float time) } } - if(ss_anim->onEndFrame != NULL) + if(ss_anim->onEndFrame) { ss_anim->onEndFrame(entity, ss_anim); } From 0f04cc36cd6702d7fd08a4a466a0c8d8f74300c0 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Fri, 19 Aug 2016 19:58:36 +0400 Subject: [PATCH 15/24] fixed state change data getting in Anim_SetNextFrame(...); fixed jump command conditions; removed unused data from ss_bone_frame_s structure; --- src/entity.cpp | 16 ++++++---------- src/skeletal_model.c | 4 ++-- src/skeletal_model.h | 4 +--- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index 5c3f5dd4b..fad77912f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -659,8 +659,6 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) if(World_GetAnimCommands() && ss_anim->model) { animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; - entity->bf->move_cmd = 0x00; - entity->bf->change_dir_cmd = 0x00; if(next_af->num_anim_commands <= 255) { uint32_t count = next_af->num_anim_commands; @@ -674,13 +672,12 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) case TR_ANIMCOMMAND_SETPOSITION: if((ss_anim->changing_next >= 0x02) && (ss_anim->onEndFrame == NULL)) // This command executes ONLY at the end of animation. { - float tr[3]; + float tr[3], move[3]; entity->no_fix_all = 0x01; - entity->bf->move_cmd = 0x01; - entity->bf->move_data[0] = (float)(*++pointer); // x = x; - entity->bf->move_data[2] =-(float)(*++pointer); // z =-y - entity->bf->move_data[1] = (float)(*++pointer); // y = z - Mat4_vec3_rot_macro(tr, entity->transform, entity->bf->move_data); + move[0] = (float)(*++pointer); // x = x; + move[2] =-(float)(*++pointer); // z =-y + move[1] = (float)(*++pointer); // y = z + Mat4_vec3_rot_macro(tr, entity->transform, move); vec3_add(entity->transform + 12, entity->transform + 12, tr); Anim_SetNextFrame(ss_anim, ss_anim->period); Entity_UpdateTransform(entity); @@ -693,7 +690,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) break; case TR_ANIMCOMMAND_JUMPDISTANCE: - if(ss_anim->changing_next >= 0x02) // This command executes ONLY at the end of animation. + if(ss_anim->next_frame + 1 == next_af->frames_count) // This command executes ONLY at the end of animation. { float vz = *++pointer; float vh = *++pointer; @@ -772,7 +769,6 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) case TR_EFFECT_CHANGEDIRECTION: if(ss_anim->changing_next >= 0x01) { - entity->bf->change_dir_cmd = 0x01; entity->angles[0] += 180.0f; if(entity->move_type == MOVE_UNDERWATER) { diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 68af772f8..9168c3527 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -791,7 +791,7 @@ 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(ss_anim->model->animations + ss_anim->current_animation, ss_anim->next_state); + 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; @@ -827,7 +827,7 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) /* * State change check */ - if(stc != NULL) + if(stc) { anim_dispatch_p disp = stc->anim_dispatch; for(uint16_t i = 0; i < stc->anim_dispatch_count; i++, disp++) diff --git a/src/skeletal_model.h b/src/skeletal_model.h index 72df5881c..dfaf1f681 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -107,9 +107,7 @@ typedef struct ss_animation_s typedef struct ss_bone_frame_s { uint16_t bone_tag_count; // number of bones - uint16_t change_dir_cmd : 1; - uint16_t move_cmd : 1; - float move_data[3]; + uint16_t unused; struct ss_bone_tag_s *bone_tags; // array of bones float pos[3]; // position (base offset) From eb1b3700634c23400e52882970146fb01a757a58 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sat, 20 Aug 2016 12:41:40 +0400 Subject: [PATCH 16/24] fixed SET_POS anim command condition; --- src/entity.cpp | 9 ++++---- src/script.cpp | 2 +- src/skeletal_model.c | 53 ++++++++++++++++++++++---------------------- src/skeletal_model.h | 2 +- 4 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index fad77912f..a4af23e1f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -670,7 +670,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) switch(*pointer) { case TR_ANIMCOMMAND_SETPOSITION: - if((ss_anim->changing_next >= 0x02) && (ss_anim->onEndFrame == NULL)) // This command executes ONLY at the end of animation. + if(ss_anim->next_frame + 1 == next_af->frames_count) // This command executes ONLY at the end of animation. { float tr[3], move[3]; entity->no_fix_all = 0x01; @@ -679,7 +679,8 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) move[1] = (float)(*++pointer); // y = z Mat4_vec3_rot_macro(tr, entity->transform, move); vec3_add(entity->transform + 12, entity->transform + 12, tr); - Anim_SetNextFrame(ss_anim, ss_anim->period); + Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame + Anim_SetAnimation(ss_anim, ss_anim->next_animation, ss_anim->next_frame); Entity_UpdateTransform(entity); Entity_UpdateRigidBody(entity, 1); } @@ -783,8 +784,6 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) entity->dir_flag = ENT_MOVE_BACKWARD; } - //ss_anim->current_animation = ss_anim->next_animation; - //ss_anim->current_frame = ss_anim->next_frame; Anim_SetNextFrame(ss_anim, ss_anim->period); Entity_UpdateTransform(entity); Entity_UpdateRigidBody(entity, 1); @@ -974,7 +973,7 @@ void Entity_SetAnimation(entity_p entity, int anim_type, int animation, int fram { entity->anim_linear_speed = entity->bf->animations.model->animations[animation].speed_x; } - SSBoneFrame_SetAnimation(ss_anim, animation, frame); + Anim_SetAnimation(ss_anim, animation, frame); SSBoneFrame_Update(entity->bf, 0.0f); } } diff --git a/src/script.cpp b/src/script.cpp index 9b6e4599e..e7d1582f2 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -3024,7 +3024,7 @@ int lua_SetEntityAnim(lua_State * lua) ss_animation_p ss_anim = SSBoneFrame_GetOverrideAnim(ent->bf, anim_type_id); if(ss_anim) { - SSBoneFrame_SetAnimation(ss_anim, lua_tointeger(lua, 3), lua_tointeger(lua, 4)); + Anim_SetAnimation(ss_anim, lua_tointeger(lua, 3), lua_tointeger(lua, 4)); if(top >= 6) { ss_anim->next_animation = lua_tointeger(lua, 5); diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 9168c3527..14cb2f37a 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -165,7 +165,7 @@ void SkeletalModel_InterpolateFrames(skeletal_model_p model) bf->bone_tags[k].offset[0] = t * anim->frames[j-1].bone_tags[k].offset[0] + lerp * anim->frames[j].bone_tags[k].offset[0]; bf->bone_tags[k].offset[1] = t * anim->frames[j-1].bone_tags[k].offset[1] + lerp * anim->frames[j].bone_tags[k].offset[1]; bf->bone_tags[k].offset[2] = t * anim->frames[j-1].bone_tags[k].offset[2] + lerp * anim->frames[j].bone_tags[k].offset[2]; - + vec4_slerp(bf->bone_tags[k].qrotate, anim->frames[j-1].bone_tags[k].qrotate, anim->frames[j].bone_tags[k].qrotate, lerp); } bf++; @@ -603,32 +603,6 @@ void SSBoneFrame_SetTargetingLimit(struct ss_animation_s *ss_anim, const float l } -void SSBoneFrame_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame) -{ - if(ss_anim && ss_anim->model && (animation < ss_anim->model->animation_count)) - { - animation_frame_p anim = &ss_anim->model->animations[animation]; - ss_anim->lerp = 0.0; - frame %= anim->frames_count; - frame = (frame >= 0) ? (frame) : (anim->frames_count - 1 + frame); - ss_anim->period = 1.0f / 30.0f; - - ss_anim->changing_curr = 0x03; - ss_anim->changing_next = 0x03; - - ss_anim->current_state = anim->state_id; - ss_anim->next_state = anim->state_id; - - ss_anim->next_animation = animation; - ss_anim->next_frame = frame; - ss_anim->current_animation = animation; - ss_anim->current_frame = frame; - - ss_anim->frame_time = (float)frame * ss_anim->period; - } -} - - struct ss_animation_s *SSBoneFrame_AddOverrideAnim(struct ss_bone_frame_s *bf, struct skeletal_model_s *sm, uint16_t anim_type_id) { if(!sm || (sm->mesh_count == bf->bone_tag_count)) @@ -783,6 +757,31 @@ int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id) } +void Anim_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame) +{ + if(ss_anim && ss_anim->model && (animation < ss_anim->model->animation_count)) + { + animation_frame_p anim = &ss_anim->model->animations[animation]; + ss_anim->lerp = 0.0; + frame %= anim->frames_count; + frame = (frame >= 0) ? (frame) : (anim->frames_count - 1 + frame); + ss_anim->period = 1.0f / 30.0f; + + ss_anim->changing_curr = 0x03; + ss_anim->changing_next = 0x03; + + ss_anim->current_state = anim->state_id; + ss_anim->next_state = anim->state_id; + + ss_anim->next_animation = animation; + ss_anim->next_frame = frame; + ss_anim->current_animation = animation; + ss_anim->current_frame = frame; + + ss_anim->frame_time = (float)frame * ss_anim->period; + } +} + /* * Next frame and next anim calculation function. */ diff --git a/src/skeletal_model.h b/src/skeletal_model.h index dfaf1f681..84dcc0873 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -241,7 +241,6 @@ void SSBoneFrame_TargetBoneToSlerp(struct ss_bone_frame_s *bf, struct ss_animati void SSBoneFrame_SetTrget(struct ss_animation_s *ss_anim, uint16_t targeted_bone, const float target_pos[3], const float bone_dir[3]); void SSBoneFrame_SetTargetingAxisMod(struct ss_animation_s *ss_anim, const float mod[3]); void SSBoneFrame_SetTargetingLimit(struct ss_animation_s *ss_anim, const float limit[4]); -void SSBoneFrame_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame); struct ss_animation_s *SSBoneFrame_AddOverrideAnim(struct ss_bone_frame_s *bf, struct skeletal_model_s *sm, uint16_t anim_type_id); struct ss_animation_s *SSBoneFrame_GetOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_type); void SSBoneFrame_EnableOverrideAnimByType(struct ss_bone_frame_s *bf, uint16_t anim_type); @@ -251,6 +250,7 @@ void SSBoneFrame_DisableOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_t struct state_change_s *Anim_FindStateChangeByAnim(struct animation_frame_s *anim, int state_change_anim); struct state_change_s *Anim_FindStateChangeByID(struct animation_frame_s *anim, uint32_t id); int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id); +void Anim_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame); int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time); #ifdef __cplusplus From 542c4460b4d11b0edba09f5e98b5e686ccff2212 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sat, 20 Aug 2016 21:41:18 +0400 Subject: [PATCH 17/24] fixed frame loosing in move anim command case; TODO: make anim_command structure like trigger commands for animations; --- src/anim_state_control.cpp | 2 +- src/entity.cpp | 78 ++++++++++++++++++-------------------- src/resource.cpp | 29 ++++++++++++-- src/skeletal_model.c | 6 +-- src/skeletal_model.h | 12 +++++- 5 files changed, 77 insertions(+), 50 deletions(-) diff --git a/src/anim_state_control.cpp b/src/anim_state_control.cpp index 1dee697c3..091980dbf 100644 --- a/src/anim_state_control.cpp +++ b/src/anim_state_control.cpp @@ -81,7 +81,7 @@ void ent_set_on_floor(entity_p ent, ss_animation_p ss_anim) void ent_set_on_floor_after_climb(entity_p ent, ss_animation_p ss_anim) { animation_frame_p af = ss_anim->model->animations + ss_anim->current_animation; - if(ss_anim->changing_next >= 0x02) + if((ss_anim->changing_next >= 0x02) && (ss_anim->changing_next < 0x04)) { float p[3], move[3]; diff --git a/src/entity.cpp b/src/entity.cpp index a4af23e1f..ef4cab590 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -659,10 +659,12 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) if(World_GetAnimCommands() && ss_anim->model) { animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; + animation_frame_p current_af = ss_anim->model->animations + ss_anim->current_animation; if(next_af->num_anim_commands <= 255) { uint32_t count = next_af->num_anim_commands; int16_t *pointer = World_GetAnimCommands() + next_af->anim_command; + int16_t next_frame = ss_anim->next_frame; int8_t random_value = 0; for(uint32_t i = 0; i < count; i++, pointer++) @@ -670,28 +672,11 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) switch(*pointer) { case TR_ANIMCOMMAND_SETPOSITION: - if(ss_anim->next_frame + 1 == next_af->frames_count) // This command executes ONLY at the end of animation. - { - float tr[3], move[3]; - entity->no_fix_all = 0x01; - move[0] = (float)(*++pointer); // x = x; - move[2] =-(float)(*++pointer); // z =-y - move[1] = (float)(*++pointer); // y = z - Mat4_vec3_rot_macro(tr, entity->transform, move); - vec3_add(entity->transform + 12, entity->transform + 12, tr); - Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame - Anim_SetAnimation(ss_anim, ss_anim->next_animation, ss_anim->next_frame); - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); - } - else - { - pointer += 3; - } + pointer += 3; break; case TR_ANIMCOMMAND_JUMPDISTANCE: - if(ss_anim->next_frame + 1 == next_af->frames_count) // This command executes ONLY at the end of animation. + if(next_frame + 1 == next_af->frames_count) // This command executes ONLY at the end of animation. { float vz = *++pointer; float vh = *++pointer; @@ -716,7 +701,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) break; case TR_ANIMCOMMAND_PLAYSOUND: - if(ss_anim->next_frame == *++pointer) + if(next_frame == *++pointer) { int16_t sound_index = (*++pointer) & 0x3FFF; // Quick workaround for TR3 quicksand. @@ -751,7 +736,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) // Effects (flipeffects) are various non-typical actions which vary // across different TR game engine versions. There are common ones, // however, and currently only these are supported. - if(ss_anim->next_frame == *++pointer) + if(next_frame == *++pointer) { entity_p player = World_GetPlayer(); switch(*++pointer & 0x3FFF) @@ -768,26 +753,6 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) break; case TR_EFFECT_CHANGEDIRECTION: - if(ss_anim->changing_next >= 0x01) - { - entity->angles[0] += 180.0f; - if(entity->move_type == MOVE_UNDERWATER) - { - entity->angles[1] = -entity->angles[1]; // for underwater case - } - if(entity->dir_flag == ENT_MOVE_BACKWARD) - { - entity->dir_flag = ENT_MOVE_FORWARD; - } - else if(entity->dir_flag == ENT_MOVE_FORWARD) - { - entity->dir_flag = ENT_MOVE_BACKWARD; - } - - Anim_SetNextFrame(ss_anim, ss_anim->period); - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); - } break; case TR_EFFECT_HIDEOBJECT: @@ -901,6 +866,37 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) }; } } + + if(current_af->command_move && ss_anim->changing_next >= 0x02) + { + float tr[3]; + entity->no_fix_all = 0x01; + Mat4_vec3_rot_macro(tr, entity->transform, current_af->command_data); + vec3_add(entity->transform + 12, entity->transform + 12, tr); + Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + } + if(next_af->command_change_dir && (next_af->command_frame == ss_anim->next_frame) && (ss_anim->changing_next >= 0x01)) + { + entity->angles[0] += 180.0f; + if(entity->move_type == MOVE_UNDERWATER) + { + entity->angles[1] = -entity->angles[1]; // for underwater case + } + if(entity->dir_flag == ENT_MOVE_BACKWARD) + { + entity->dir_flag = ENT_MOVE_FORWARD; + } + else if(entity->dir_flag == ENT_MOVE_FORWARD) + { + entity->dir_flag = ENT_MOVE_BACKWARD; + } + + Anim_SetNextFrame(ss_anim, ss_anim->period); + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + } } } diff --git a/src/resource.cpp b/src/resource.cpp index 7e88a57c7..a16790c7f 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1638,7 +1638,10 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct model->animations->state_change = NULL; model->animations->state_change_count = 0; model->animations->original_frame_rate = 1; - + vec3_set_zero(model->animations->command_data); + model->animations->command_change_dir = 0x00; + model->animations->command_move = 0x00; + model->animations->command_frame = 0x00; bone_frame->bone_tag_count = model->mesh_count; bone_frame->bone_tags = (bone_tag_p)malloc(bone_frame->bone_tag_count * sizeof(bone_tag_t)); vec3_set_zero(bone_frame->pos); @@ -1698,6 +1701,10 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim->anim_command = tr_animation->anim_command; anim->num_anim_commands = tr_animation->num_anim_commands; anim->state_id = tr_animation->state_id; + vec3_set_zero(anim->command_data); + anim->command_change_dir = 0x00; + anim->command_move = 0x00; + anim->command_frame = 0x00; anim->frames_count = TR_GetNumFramesForAnimation(tr, tr_moveable->animation_index+i); @@ -1717,6 +1724,14 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct switch(*pointer) { case TR_ANIMCOMMAND_PLAYEFFECT: + *(pointer + 1) -= tr_animation->frame_start; + if(0x3FF & (*(pointer + 2)) == TR_EFFECT_CHANGEDIRECTION) + { + anim->command_change_dir = 0x01; + anim->command_frame = *(pointer + 1); + } + break; + case TR_ANIMCOMMAND_PLAYSOUND: // Recalculate absolute frame number to relative. ///@FIXED: was unpredictable behavior. @@ -1725,8 +1740,10 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct break; case TR_ANIMCOMMAND_SETPOSITION: - // Parse through 3 operands. - pointer += 3; + anim->command_move = 0x01; + anim->command_data[0] = (float)(*++pointer); // x = x; + anim->command_data[2] =-(float)(*++pointer); // z =-y + anim->command_data[1] = (float)(*++pointer); // y = z break; case TR_ANIMCOMMAND_JUMPDISTANCE: @@ -1740,7 +1757,11 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct } } } - + /*uint32_t command_move : 1; + uint32_t command_change_dir : 1; + uint32_t : 14; + uint32_t command_frame : 16; + float command_data[3];*/ if(anim->frames_count <= 0) { diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 14cb2f37a..757f1a6c8 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -767,9 +767,9 @@ void Anim_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame) frame = (frame >= 0) ? (frame) : (anim->frames_count - 1 + frame); ss_anim->period = 1.0f / 30.0f; - ss_anim->changing_curr = 0x03; - ss_anim->changing_next = 0x03; - + ss_anim->changing_curr = 0x04; + ss_anim->changing_next = 0x04; + ss_anim->current_state = anim->state_id; ss_anim->next_state = anim->state_id; diff --git a/src/skeletal_model.h b/src/skeletal_model.h index 84dcc0873..b0eec99fa 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -65,7 +65,12 @@ typedef struct ss_bone_tag_s uint32_t body_part; // flag: BODY, LEFT_LEG_1, RIGHT_HAND_2, HEAD... }ss_bone_tag_t, *ss_bone_tag_p; - +// changing info: +// 0x00 - no changes; +// 0x01 - next frame, same anim; +// 0x02 - next frame, next anim (anim ended, may be loop); +// 0x03 - new frame, new anim (by state change info); +// 0x04 - rough change by set animation; typedef struct ss_animation_s { uint16_t type : 15; @@ -184,6 +189,11 @@ typedef struct animation_frame_s uint16_t original_frame_rate; uint16_t state_id; + uint32_t command_move : 1; + uint32_t command_change_dir : 1; + uint32_t : 14; + uint32_t command_frame : 16; + float command_data[3]; float speed_x; // Forward-backward speed float accel_x; // Forward-backward accel float speed_y; // Left-right speed From f9ffb398e4284308eaa8063d2ddb2d5e2dd33052 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sun, 21 Aug 2016 16:13:31 +0400 Subject: [PATCH 18/24] added animation_command_s and animation_effect_s structures; bytecode anim commands parsing fully moved to level loading; --- src/entity.cpp | 149 +++++++++++++++++++------------------------ src/resource.cpp | 82 ++++++++++-------------- src/resource.h | 2 +- src/skeletal_model.c | 34 ++++++++++ src/skeletal_model.h | 29 +++++++-- src/world.cpp | 25 +------- src/world.h | 1 - 7 files changed, 159 insertions(+), 163 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index ef4cab590..15965021e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -656,54 +656,58 @@ void Entity_CheckCollisionCallbacks(entity_p ent) void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) { - if(World_GetAnimCommands() && ss_anim->model) + if(ss_anim->model) { animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; animation_frame_p current_af = ss_anim->model->animations + ss_anim->current_animation; - if(next_af->num_anim_commands <= 255) - { - uint32_t count = next_af->num_anim_commands; - int16_t *pointer = World_GetAnimCommands() + next_af->anim_command; - int16_t next_frame = ss_anim->next_frame; - int8_t random_value = 0; + int16_t next_frame = ss_anim->next_frame; - for(uint32_t i = 0; i < count; i++, pointer++) + for(animation_command_p command = current_af->commands; command; command = command->next) + { + switch(command->id) { - switch(*pointer) - { - case TR_ANIMCOMMAND_SETPOSITION: - pointer += 3; - break; + case TR_ANIMCOMMAND_SETPOSITION: + if(ss_anim->changing_next >= 0x02) // This command executes ONLY at the end of animation. + { + float tr[3]; + entity->no_fix_all = 0x01; + Mat4_vec3_rot_macro(tr, entity->transform, command->data); + vec3_add(entity->transform + 12, entity->transform + 12, tr); + Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + } + break; - case TR_ANIMCOMMAND_JUMPDISTANCE: - if(next_frame + 1 == next_af->frames_count) // This command executes ONLY at the end of animation. - { - float vz = *++pointer; - float vh = *++pointer; - Character_SetToJump(entity, -vz, vh); - } - else - { - pointer += 2; - } - break; + case TR_ANIMCOMMAND_JUMPDISTANCE: + if(entity->character && (ss_anim->changing_next >= 0x02)) // This command executes ONLY at the end of animation. + { + Character_SetToJump(entity, -command->data[0], command->data[1]); + } + break; - case TR_ANIMCOMMAND_EMPTYHANDS: - ///@FIXME: Behaviour is yet to be discovered. - break; + case TR_ANIMCOMMAND_EMPTYHANDS: + ///@FIXME: Behaviour is yet to be discovered. + break; - case TR_ANIMCOMMAND_KILL: - // This command executes ONLY at the end of animation. - if((ss_anim->changing_next >= 0x02) && (entity->character)) - { - entity->character->resp.kill = 1; - } - break; + case TR_ANIMCOMMAND_KILL: + if(entity->character) + { + entity->character->resp.kill = 0x01; + } + break; + }; + } + for(animation_effect_p effect = next_af->effects; effect; effect = effect->next) + { + if(next_frame == effect->frame) + { + switch(effect->id) + { case TR_ANIMCOMMAND_PLAYSOUND: - if(next_frame == *++pointer) { - int16_t sound_index = (*++pointer) & 0x3FFF; + int16_t sound_index = 0x3FFFF & effect->data; // Quick workaround for TR3 quicksand. if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || (Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_SHALLOW) ) @@ -711,12 +715,12 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) sound_index = 18; } - if(*pointer & TR_ANIMCOMMAND_CONDITION_WATER) + if(effect->data & TR_ANIMCOMMAND_CONDITION_WATER) { if(Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_WATER_SHALLOW) Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); } - else if(*pointer & TR_ANIMCOMMAND_CONDITION_LAND) + else if(effect->data & TR_ANIMCOMMAND_CONDITION_LAND) { if(Entity_GetSubstanceState(entity) != ENTITY_SUBSTANCE_WATER_SHALLOW) Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); @@ -726,20 +730,15 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); } } - else - { - pointer++; - } break; case TR_ANIMCOMMAND_PLAYEFFECT: // Effects (flipeffects) are various non-typical actions which vary // across different TR game engine versions. There are common ones, // however, and currently only these are supported. - if(next_frame == *++pointer) { entity_p player = World_GetPlayer(); - switch(*++pointer & 0x3FFF) + switch(effect->data & 0x3FFF) { case TR_EFFECT_SHAKESCREEN: if(player) @@ -753,6 +752,26 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) break; case TR_EFFECT_CHANGEDIRECTION: + if(ss_anim->changing_next >= 0x01) + { + entity->angles[0] += 180.0f; + if(entity->move_type == MOVE_UNDERWATER) + { + entity->angles[1] = -entity->angles[1]; // for underwater case + } + if(entity->dir_flag == ENT_MOVE_BACKWARD) + { + entity->dir_flag = ENT_MOVE_FORWARD; + } + else if(entity->dir_flag == ENT_MOVE_FORWARD) + { + entity->dir_flag = ENT_MOVE_BACKWARD; + } + + Anim_SetNextFrame(ss_anim, ss_anim->period); + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + } break; case TR_EFFECT_HIDEOBJECT: @@ -846,8 +865,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) case TR_EFFECT_BUBBLE: ///@FIXME: Spawn bubble particle here, when particle system is developed. - random_value = rand() % 100; - if(random_value > 60) + if(rand() % 100 > 60) { Audio_Send(TR_AUDIO_SOUND_BUBBLE, TR_AUDIO_EMITTER_ENTITY, entity->id); } @@ -858,44 +876,9 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) break; } } - else - { - pointer++; - } break; }; - } - } - - if(current_af->command_move && ss_anim->changing_next >= 0x02) - { - float tr[3]; - entity->no_fix_all = 0x01; - Mat4_vec3_rot_macro(tr, entity->transform, current_af->command_data); - vec3_add(entity->transform + 12, entity->transform + 12, tr); - Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); - } - if(next_af->command_change_dir && (next_af->command_frame == ss_anim->next_frame) && (ss_anim->changing_next >= 0x01)) - { - entity->angles[0] += 180.0f; - if(entity->move_type == MOVE_UNDERWATER) - { - entity->angles[1] = -entity->angles[1]; // for underwater case - } - if(entity->dir_flag == ENT_MOVE_BACKWARD) - { - entity->dir_flag = ENT_MOVE_FORWARD; - } - else if(entity->dir_flag == ENT_MOVE_FORWARD) - { - entity->dir_flag = ENT_MOVE_BACKWARD; - } - - Anim_SetNextFrame(ss_anim, ss_anim->period); - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); + }; } } } diff --git a/src/resource.cpp b/src/resource.cpp index a16790c7f..22675d71f 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1552,7 +1552,7 @@ void TR_GenRoomMesh(struct room_s *room, size_t room_index, struct anim_seq_s *a } -void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct base_mesh_s *base_mesh_array, int16_t *base_anim_commands_array, class VT_Level *tr) +void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct base_mesh_s *base_mesh_array, class VT_Level *tr) { tr_moveable_t *tr_moveable; tr_animation_t *tr_animation; @@ -1638,10 +1638,8 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct model->animations->state_change = NULL; model->animations->state_change_count = 0; model->animations->original_frame_rate = 1; - vec3_set_zero(model->animations->command_data); - model->animations->command_change_dir = 0x00; - model->animations->command_move = 0x00; - model->animations->command_frame = 0x00; + model->animations->commands = NULL; + model->animations->effects = NULL; bone_frame->bone_tag_count = model->mesh_count; bone_frame->bone_tags = (bone_tag_p)malloc(bone_frame->bone_tag_count * sizeof(bone_tag_t)); vec3_set_zero(bone_frame->pos); @@ -1682,7 +1680,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim = model->animations; for(uint16_t i = 0; i < model->animation_count; i++, anim++) { - tr_animation = &tr->animations[tr_moveable->animation_index+i]; + tr_animation = &tr->animations[tr_moveable->animation_index + i]; frame_offset = tr_animation->frame_offset / 2; uint16_t l_start = 0x09; if(tr->game_version == TR_I || tr->game_version == TR_I_DEMO || tr->game_version == TR_I_UB) @@ -1698,15 +1696,11 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim->accel_x = tr_animation->accel; anim->speed_y = tr_animation->accel_lateral; anim->accel_y = tr_animation->speed_lateral; - anim->anim_command = tr_animation->anim_command; - anim->num_anim_commands = tr_animation->num_anim_commands; + anim->commands = NULL; + anim->effects = NULL; anim->state_id = tr_animation->state_id; - vec3_set_zero(anim->command_data); - anim->command_change_dir = 0x00; - anim->command_move = 0x00; - anim->command_frame = 0x00; - anim->frames_count = TR_GetNumFramesForAnimation(tr, tr_moveable->animation_index+i); + anim->frames_count = TR_GetNumFramesForAnimation(tr, tr_moveable->animation_index + i); //Sys_DebugLog(LOG_FILENAME, "Anim[%d], %d", tr_moveable->animation_index, TR_GetNumFramesForAnimation(tr, tr_moveable->animation_index)); @@ -1714,54 +1708,48 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct // Max. amount of AnimCommands is 255, larger numbers are considered as 0. // See http://evpopov.com/dl/TR4format.html#Animations for details. - if( (anim->num_anim_commands > 0) && (anim->num_anim_commands <= 255) ) + if((tr_animation->num_anim_commands > 0) && (tr_animation->num_anim_commands <= 255)) { // Calculate current animation anim command block offset. - int16_t *pointer = base_anim_commands_array + anim->anim_command; - - for(uint32_t count = 0; count < anim->num_anim_commands; count++, pointer++) + int16_t *pointer = tr->anim_commands + tr_animation->anim_command; + animation_command_t command; + animation_effect_t effect; + for(uint32_t count = 0; count < tr_animation->num_anim_commands; count++, pointer++) { - switch(*pointer) + command.id = *pointer; + switch(command.id) { - case TR_ANIMCOMMAND_PLAYEFFECT: - *(pointer + 1) -= tr_animation->frame_start; - if(0x3FF & (*(pointer + 2)) == TR_EFFECT_CHANGEDIRECTION) - { - anim->command_change_dir = 0x01; - anim->command_frame = *(pointer + 1); - } - break; - - case TR_ANIMCOMMAND_PLAYSOUND: - // Recalculate absolute frame number to relative. - ///@FIXED: was unpredictable behavior. - *(pointer + 1) -= tr_animation->frame_start; - pointer += 2; - break; - case TR_ANIMCOMMAND_SETPOSITION: - anim->command_move = 0x01; - anim->command_data[0] = (float)(*++pointer); // x = x; - anim->command_data[2] =-(float)(*++pointer); // z =-y - anim->command_data[1] = (float)(*++pointer); // y = z + command.data[0] = (float)(*++pointer); // x = x; + command.data[2] =-(float)(*++pointer); // z =-y + command.data[1] = (float)(*++pointer); // y = z + Anim_AddCommand(anim, &command); break; case TR_ANIMCOMMAND_JUMPDISTANCE: - // Parse through 2 operands. - pointer += 2; + command.data[0] = (float)(*++pointer); // v_z + command.data[1] = (float)(*++pointer); // v_y + command.data[2] = 0.0f; + Anim_AddCommand(anim, &command); break; + case TR_ANIMCOMMAND_PLAYEFFECT: + case TR_ANIMCOMMAND_PLAYSOUND: + effect.id = command.id; + effect.frame = *(++pointer) - tr_animation->frame_start; + effect.data = *(++pointer); + Anim_AddEffect(anim, &effect); + break; + + case TR_ANIMCOMMAND_KILL: + case TR_ANIMCOMMAND_EMPTYHANDS: default: - // All other commands have no operands. + vec3_set_zero(command.data); + Anim_AddCommand(anim, &command); break; - } + }; } } - /*uint32_t command_move : 1; - uint32_t command_change_dir : 1; - uint32_t : 14; - uint32_t command_frame : 16; - float command_data[3];*/ if(anim->frames_count <= 0) { diff --git a/src/resource.h b/src/resource.h index d453b8d31..2277b49b4 100644 --- a/src/resource.h +++ b/src/resource.h @@ -37,6 +37,6 @@ void Res_RoomSectorsCalculate(struct room_s *rooms, uint32_t rooms_count, uint32 // Functions generating native OpenTomb structs from legacy TR structs. void TR_GenMesh(struct base_mesh_s *mesh, size_t mesh_index, struct anim_seq_s *anim_sequences, uint32_t anim_sequences_count, class bordered_texture_atlas *atlas, class VT_Level *tr); void TR_GenRoomMesh(struct room_s *room, size_t room_index, struct anim_seq_s *anim_sequences, uint32_t anim_sequences_count, class bordered_texture_atlas *atlas, class VT_Level *tr); -void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct base_mesh_s *base_mesh_array, int16_t *base_anim_commands_array, class VT_Level *tr); +void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct base_mesh_s *base_mesh_array, class VT_Level *tr); #endif diff --git a/src/skeletal_model.c b/src/skeletal_model.c index 757f1a6c8..c1582e5a5 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -63,6 +63,20 @@ void SkeletalModel_Clear(skeletal_model_p model) free(anim->frames); anim->frames = NULL; } + + while(anim->commands) + { + animation_command_p next_command = anim->commands->next; + free(anim->commands); + anim->commands = next_command; + } + + while(anim->effects) + { + animation_effect_p next_effect = anim->effects->next; + free(anim->effects); + anim->effects = next_effect; + } } model->animation_count= 0; free(model->animations); @@ -697,6 +711,26 @@ void SSBoneFrame_DisableOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_t /* ******************************************************************************* */ +void Anim_AddCommand(struct animation_frame_s *anim, const animation_command_p command) +{ + animation_command_p *ptr = &anim->commands; + for(; *ptr; ptr = &((*ptr)->next)); + *ptr = (animation_command_p)malloc(sizeof(animation_command_t)); + **ptr = *command; + (*ptr)->next = NULL; +} + + +void Anim_AddEffect(struct animation_frame_s *anim, const animation_effect_p effect) +{ + animation_effect_p *ptr = &anim->effects; + for(; *ptr; ptr = &((*ptr)->next)); + *ptr = (animation_effect_p)malloc(sizeof(animation_effect_t)); + **ptr = *effect; + (*ptr)->next = NULL; +} + + struct state_change_s *Anim_FindStateChangeByAnim(struct animation_frame_s *anim, int state_change_anim) { if(state_change_anim >= 0) diff --git a/src/skeletal_model.h b/src/skeletal_model.h index b0eec99fa..138efd2c9 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -180,6 +180,23 @@ typedef struct state_change_s struct anim_dispatch_s *anim_dispatch; }state_change_t, *state_change_p; +typedef struct animation_command_s +{ + uint16_t id; + uint16_t unused; + float data[3]; + struct animation_command_s *next; +}animation_command_t, *animation_command_p; + +typedef struct animation_effect_s +{ + uint16_t id; + uint16_t frame; + uint16_t data; + uint16_t unused; + struct animation_effect_s *next; +}animation_effect_t, *animation_effect_p; + /* * one animation frame structure */ @@ -189,17 +206,13 @@ typedef struct animation_frame_s uint16_t original_frame_rate; uint16_t state_id; - uint32_t command_move : 1; - uint32_t command_change_dir : 1; - uint32_t : 14; - uint32_t command_frame : 16; - float command_data[3]; + struct animation_command_s *commands; + struct animation_effect_s *effects; + float speed_x; // Forward-backward speed float accel_x; // Forward-backward accel float speed_y; // Left-right speed float accel_y; // Left-right accel - uint32_t anim_command; - uint32_t num_anim_commands; uint16_t frames_count; // Number of frames uint16_t state_change_count; // Number of animation statechanges @@ -257,6 +270,8 @@ void SSBoneFrame_EnableOverrideAnimByType(struct ss_bone_frame_s *bf, uint16_t a void SSBoneFrame_EnableOverrideAnim(struct ss_bone_frame_s *bf, struct ss_animation_s *ss_anim); void SSBoneFrame_DisableOverrideAnim(struct ss_bone_frame_s *bf, uint16_t anim_type); +void Anim_AddCommand(struct animation_frame_s *anim, const animation_command_p command); +void Anim_AddEffect(struct animation_frame_s *anim, const animation_effect_p effect); struct state_change_s *Anim_FindStateChangeByAnim(struct animation_frame_s *anim, int state_change_anim); struct state_change_s *Anim_FindStateChangeByID(struct animation_frame_s *anim, uint32_t id); int Anim_GetAnimDispatchCase(struct ss_bone_frame_s *bf, uint32_t id); diff --git a/src/world.cpp b/src/world.cpp index 85e54cfde..494ab89fe 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -86,9 +86,6 @@ extern "C" { struct flyby_camera_state_s *flyby_cameras; struct flyby_camera_sequence_s *flyby_camera_sequences; - uint32_t anim_commands_count; - int16_t *anim_commands; - /// private: struct lua_State *objects_flags_conf; struct lua_State *ent_ID_override; @@ -115,7 +112,6 @@ bool Res_CreateEntityFunc(lua_State *lua, const char* func_name, int entity_id); void World_GenTextures(class VT_Level *tr); -void World_GenAnimCommands(class VT_Level *tr); void World_GenAnimTextures(class VT_Level *tr); void World_GenMeshes(class VT_Level *tr); void World_GenSprites(class VT_Level *tr); @@ -170,8 +166,6 @@ void World_Prepare() global_world.skeletal_models = NULL; global_world.skeletal_models_count = 0; global_world.sky_box = NULL; - global_world.anim_commands = NULL; - global_world.anim_commands_count = 0; global_world.objects_flags_conf = NULL; global_world.ent_ID_override = NULL; @@ -194,9 +188,6 @@ void World_Open(class VT_Level *tr) World_GenTextures(tr); // Generate OGL textures Gui_DrawLoadScreen(300); - World_GenAnimCommands(tr); // Copy anim commands - Gui_DrawLoadScreen(310); - World_GenAnimTextures(tr); // Generate animated textures Gui_DrawLoadScreen(320); @@ -611,12 +602,6 @@ struct static_camera_sink_s *World_GetstaticCameraSink(uint32_t id) } -int16_t *World_GetAnimCommands() -{ - return global_world.anim_commands; -} - - void World_GetRoomInfo(struct room_s **rooms, uint32_t *rooms_count) { *rooms = global_world.rooms; @@ -1543,14 +1528,6 @@ void World_GenTextures(class VT_Level *tr) } -void World_GenAnimCommands(class VT_Level *tr) -{ - global_world.anim_commands_count = tr->anim_commands_count; - global_world.anim_commands = tr->anim_commands; - tr->anim_commands = NULL; - tr->anim_commands_count = 0; -} - /** Animated textures loading. * Natively, animated textures stored as a stream of bitu16s, which * is then parsed on the fly. What we do is parse this stream to the @@ -2255,7 +2232,7 @@ void World_GenSkeletalModels(class VT_Level *tr) tr_moveable = &tr->moveables[i]; smodel->id = tr_moveable->object_id; smodel->mesh_count = tr_moveable->num_meshes; - TR_GenSkeletalModel(smodel, i, global_world.meshes, global_world.anim_commands, tr); + TR_GenSkeletalModel(smodel, i, global_world.meshes, tr); SkeletalModel_FillTransparency(smodel); } } diff --git a/src/world.h b/src/world.h index b1d4fca23..c30f172d3 100644 --- a/src/world.h +++ b/src/world.h @@ -21,7 +21,6 @@ struct RedBlackNode_s *World_GetEntityTreeRoot(); struct flyby_camera_sequence_s *World_GetFlyBySequences(); struct base_item_s *World_GetBaseItemByID(uint32_t id); struct static_camera_sink_s *World_GetstaticCameraSink(uint32_t id); -int16_t *World_GetAnimCommands(); void World_GetRoomInfo(struct room_s **rooms, uint32_t *rooms_count); void World_GetAnimSeqInfo(struct anim_seq_s **seq, uint32_t *seq_count); From 1765696279829622ea819e843faa4f34a6555919 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Sun, 21 Aug 2016 19:41:44 +0400 Subject: [PATCH 19/24] fixed command data type; fixed loosed command on frame skipping; --- src/entity.cpp | 328 ++++++++++++++++++++++--------------------- src/resource.cpp | 16 +-- src/skeletal_model.h | 6 +- 3 files changed, 178 insertions(+), 172 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index 15965021e..c9a5f794d 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -662,6 +662,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) animation_frame_p current_af = ss_anim->model->animations + ss_anim->current_animation; int16_t next_frame = ss_anim->next_frame; + ///@DO COMMANDS for(animation_command_p command = current_af->commands; command; command = command->next) { switch(command->id) @@ -676,6 +677,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame Entity_UpdateTransform(entity); Entity_UpdateRigidBody(entity, 1); + Entity_DoAnimCommands(entity, ss_anim); } break; @@ -699,185 +701,189 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) }; } + ///@DO EFFECTS for(animation_effect_p effect = next_af->effects; effect; effect = effect->next) { - if(next_frame == effect->frame) + if(next_frame != effect->frame) { - switch(effect->id) - { - case TR_ANIMCOMMAND_PLAYSOUND: + continue; + } + + switch(effect->id) + { + case TR_ANIMCOMMAND_PLAYSOUND: + { + int16_t sound_index = 0x3FFFF & effect->data; + // Quick workaround for TR3 quicksand. + if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || + (Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_SHALLOW) ) + { + sound_index = 18; + } + + if(effect->data & TR_ANIMCOMMAND_CONDITION_WATER) + { + if(Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_WATER_SHALLOW) + Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + else if(effect->data & TR_ANIMCOMMAND_CONDITION_LAND) { - int16_t sound_index = 0x3FFFF & effect->data; - // Quick workaround for TR3 quicksand. - if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || - (Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_SHALLOW) ) - { - sound_index = 18; - } - - if(effect->data & TR_ANIMCOMMAND_CONDITION_WATER) - { - if(Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_WATER_SHALLOW) - Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - else if(effect->data & TR_ANIMCOMMAND_CONDITION_LAND) - { - if(Entity_GetSubstanceState(entity) != ENTITY_SUBSTANCE_WATER_SHALLOW) - Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - else - { + if(Entity_GetSubstanceState(entity) != ENTITY_SUBSTANCE_WATER_SHALLOW) Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); - } } - break; + else + { + Audio_Send(sound_index, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + } + break; - case TR_ANIMCOMMAND_PLAYEFFECT: - // Effects (flipeffects) are various non-typical actions which vary - // across different TR game engine versions. There are common ones, - // however, and currently only these are supported. + case TR_ANIMCOMMAND_PLAYEFFECT: + // Effects (flipeffects) are various non-typical actions which vary + // across different TR game engine versions. There are common ones, + // however, and currently only these are supported. + { + entity_p player = World_GetPlayer(); + switch(effect->data & 0x3FFF) { - entity_p player = World_GetPlayer(); - switch(effect->data & 0x3FFF) - { - case TR_EFFECT_SHAKESCREEN: - if(player) + case TR_EFFECT_SHAKESCREEN: + if(player) + { + float *pos = player->transform + 12; + float dist = vec3_dist(pos, entity->transform + 12); + dist = (dist > TR_CAM_MAX_SHAKE_DISTANCE) ? (0) : ((TR_CAM_MAX_SHAKE_DISTANCE - dist) / 1024.0f); + //if(dist > 0) + // Cam_Shake(&engine_camera, (dist * TR_CAM_DEFAULT_SHAKE_POWER), 0.5); + } + break; + + case TR_EFFECT_CHANGEDIRECTION: + if(ss_anim->changing_next >= 0x01) + { + entity->angles[0] += 180.0f; + if(entity->move_type == MOVE_UNDERWATER) { - float *pos = player->transform + 12; - float dist = vec3_dist(pos, entity->transform + 12); - dist = (dist > TR_CAM_MAX_SHAKE_DISTANCE) ? (0) : ((TR_CAM_MAX_SHAKE_DISTANCE - dist) / 1024.0f); - //if(dist > 0) - // Cam_Shake(&engine_camera, (dist * TR_CAM_DEFAULT_SHAKE_POWER), 0.5); + entity->angles[1] = -entity->angles[1]; // for underwater case } - break; - - case TR_EFFECT_CHANGEDIRECTION: - if(ss_anim->changing_next >= 0x01) + if(entity->dir_flag == ENT_MOVE_BACKWARD) { - entity->angles[0] += 180.0f; - if(entity->move_type == MOVE_UNDERWATER) - { - entity->angles[1] = -entity->angles[1]; // for underwater case - } - if(entity->dir_flag == ENT_MOVE_BACKWARD) - { - entity->dir_flag = ENT_MOVE_FORWARD; - } - else if(entity->dir_flag == ENT_MOVE_FORWARD) - { - entity->dir_flag = ENT_MOVE_BACKWARD; - } - - Anim_SetNextFrame(ss_anim, ss_anim->period); - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); + entity->dir_flag = ENT_MOVE_FORWARD; } - break; - - case TR_EFFECT_HIDEOBJECT: - entity->state_flags &= ~ENTITY_STATE_VISIBLE; - break; - - case TR_EFFECT_SHOWOBJECT: - entity->state_flags |= ENTITY_STATE_VISIBLE; - break; - - case TR_EFFECT_PLAYSTEPSOUND: - // Please note that we bypass land/water mask, as TR3-5 tends to ignore - // this flag and play step sound in any case on land, ignoring it - // completely in water rooms. - if(!Entity_GetSubstanceState(entity)) + else if(entity->dir_flag == ENT_MOVE_FORWARD) { - // TR3-5 footstep map. - // We define it here as a magic numbers array, because TR3-5 versions - // fortunately have no differences in footstep sounds order. - // Also note that some footstep types mutually share same sound IDs - // across different TR versions. - switch(entity->current_sector->material) - { - case SECTOR_MATERIAL_MUD: - Audio_Send(288, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_SNOW: // TR3 & TR5 only - if(World_GetVersion() != TR_IV) - { - Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - break; - - case SECTOR_MATERIAL_SAND: // Same as grass - Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_GRAVEL: - Audio_Send(290, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_ICE: // TR3 & TR5 only - if(World_GetVersion() != TR_IV) - { - Audio_Send(289, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - break; - - case SECTOR_MATERIAL_WATER: // BYPASS! - // Audio_Send(17, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_STONE: // DEFAULT SOUND, BYPASS! - // Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_WOOD: - Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_METAL: - Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_MARBLE: // TR4 only - if(World_GetVersion() == TR_IV) - { - Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); - } - break; - - case SECTOR_MATERIAL_GRASS: // Same as sand - Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_CONCRETE: // DEFAULT SOUND, BYPASS! - Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_OLDWOOD: // Same as wood - Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - - case SECTOR_MATERIAL_OLDMETAL: // Same as metal - Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); - break; - } + entity->dir_flag = ENT_MOVE_BACKWARD; } - break; - case TR_EFFECT_BUBBLE: - ///@FIXME: Spawn bubble particle here, when particle system is developed. - if(rand() % 100 > 60) + Anim_SetNextFrame(ss_anim, ss_anim->period); + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + Entity_DoAnimCommands(entity, ss_anim); + } + break; + + case TR_EFFECT_HIDEOBJECT: + entity->state_flags &= ~ENTITY_STATE_VISIBLE; + break; + + case TR_EFFECT_SHOWOBJECT: + entity->state_flags |= ENTITY_STATE_VISIBLE; + break; + + case TR_EFFECT_PLAYSTEPSOUND: + // Please note that we bypass land/water mask, as TR3-5 tends to ignore + // this flag and play step sound in any case on land, ignoring it + // completely in water rooms. + if(!Entity_GetSubstanceState(entity)) + { + // TR3-5 footstep map. + // We define it here as a magic numbers array, because TR3-5 versions + // fortunately have no differences in footstep sounds order. + // Also note that some footstep types mutually share same sound IDs + // across different TR versions. + switch(entity->current_sector->material) { - Audio_Send(TR_AUDIO_SOUND_BUBBLE, TR_AUDIO_EMITTER_ENTITY, entity->id); + case SECTOR_MATERIAL_MUD: + Audio_Send(288, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_SNOW: // TR3 & TR5 only + if(World_GetVersion() != TR_IV) + { + Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + case SECTOR_MATERIAL_SAND: // Same as grass + Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_GRAVEL: + Audio_Send(290, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_ICE: // TR3 & TR5 only + if(World_GetVersion() != TR_IV) + { + Audio_Send(289, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + case SECTOR_MATERIAL_WATER: // BYPASS! + // Audio_Send(17, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_STONE: // DEFAULT SOUND, BYPASS! + // Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_WOOD: + Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_METAL: + Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_MARBLE: // TR4 only + if(World_GetVersion() == TR_IV) + { + Audio_Send(293, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + case SECTOR_MATERIAL_GRASS: // Same as sand + Audio_Send(291, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_CONCRETE: // DEFAULT SOUND, BYPASS! + Audio_Send(-1, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_OLDWOOD: // Same as wood + Audio_Send(292, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; + + case SECTOR_MATERIAL_OLDMETAL: // Same as metal + Audio_Send(294, TR_AUDIO_EMITTER_ENTITY, entity->id); + break; } - break; - - default: - ///@FIXME: TODO ALL OTHER EFFECTS! - break; - } + } + break; + + case TR_EFFECT_BUBBLE: + ///@FIXME: Spawn bubble particle here, when particle system is developed. + if(rand() % 100 > 60) + { + Audio_Send(TR_AUDIO_SOUND_BUBBLE, TR_AUDIO_EMITTER_ENTITY, entity->id); + } + break; + + default: + ///@FIXME: TODO ALL OTHER EFFECTS! + break; } - break; - }; + }; + break; }; } } diff --git a/src/resource.cpp b/src/resource.cpp index 22675d71f..7851c444e 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1719,6 +1719,14 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct command.id = *pointer; switch(command.id) { + case TR_ANIMCOMMAND_PLAYEFFECT: + case TR_ANIMCOMMAND_PLAYSOUND: + effect.id = command.id; + effect.frame = *(++pointer) - tr_animation->frame_start; + effect.data = *(++pointer); + Anim_AddEffect(anim, &effect); + break; + case TR_ANIMCOMMAND_SETPOSITION: command.data[0] = (float)(*++pointer); // x = x; command.data[2] =-(float)(*++pointer); // z =-y @@ -1733,14 +1741,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct Anim_AddCommand(anim, &command); break; - case TR_ANIMCOMMAND_PLAYEFFECT: - case TR_ANIMCOMMAND_PLAYSOUND: - effect.id = command.id; - effect.frame = *(++pointer) - tr_animation->frame_start; - effect.data = *(++pointer); - Anim_AddEffect(anim, &effect); - break; - case TR_ANIMCOMMAND_KILL: case TR_ANIMCOMMAND_EMPTYHANDS: default: diff --git a/src/skeletal_model.h b/src/skeletal_model.h index 138efd2c9..b47cc2e3f 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -191,9 +191,9 @@ typedef struct animation_command_s typedef struct animation_effect_s { uint16_t id; - uint16_t frame; - uint16_t data; - uint16_t unused; + int16_t frame; + int16_t data; + int16_t unused; struct animation_effect_s *next; }animation_effect_t, *animation_effect_p; From e90afe793e7f1a28812d55d0aaea3d642a936795 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Mon, 22 Aug 2016 20:57:09 +0400 Subject: [PATCH 20/24] fixed play anim effect bit mask; --- src/entity.cpp | 26 ++++++++++++++------------ src/skeletal_model.c | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index c9a5f794d..b54ff1645 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -660,7 +660,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) { animation_frame_p next_af = ss_anim->model->animations + ss_anim->next_animation; animation_frame_p current_af = ss_anim->model->animations + ss_anim->current_animation; - int16_t next_frame = ss_anim->next_frame; + bool do_skip_frame = false; ///@DO COMMANDS for(animation_command_p command = current_af->commands; command; command = command->next) @@ -674,10 +674,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) entity->no_fix_all = 0x01; Mat4_vec3_rot_macro(tr, entity->transform, command->data); vec3_add(entity->transform + 12, entity->transform + 12, tr); - Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); - Entity_DoAnimCommands(entity, ss_anim); + do_skip_frame = true; } break; @@ -704,7 +701,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) ///@DO EFFECTS for(animation_effect_p effect = next_af->effects; effect; effect = effect->next) { - if(next_frame != effect->frame) + if(ss_anim->next_frame != effect->frame) { continue; } @@ -713,7 +710,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) { case TR_ANIMCOMMAND_PLAYSOUND: { - int16_t sound_index = 0x3FFFF & effect->data; + int16_t sound_index = 0x3FFF & effect->data; // Quick workaround for TR3 quicksand. if((Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_CONSUMED) || (Entity_GetSubstanceState(entity) == ENTITY_SUBSTANCE_QUICKSAND_SHALLOW) ) @@ -763,7 +760,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) entity->angles[0] += 180.0f; if(entity->move_type == MOVE_UNDERWATER) { - entity->angles[1] = -entity->angles[1]; // for underwater case + entity->angles[1] = -entity->angles[1]; // for underwater case } if(entity->dir_flag == ENT_MOVE_BACKWARD) { @@ -774,10 +771,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) entity->dir_flag = ENT_MOVE_BACKWARD; } - Anim_SetNextFrame(ss_anim, ss_anim->period); - Entity_UpdateTransform(entity); - Entity_UpdateRigidBody(entity, 1); - Entity_DoAnimCommands(entity, ss_anim); + do_skip_frame = true; } break; @@ -886,6 +880,14 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) break; }; } + + if(do_skip_frame) + { + Anim_SetNextFrame(ss_anim, ss_anim->period); // skip one frame + Entity_UpdateTransform(entity); + Entity_UpdateRigidBody(entity, 1); + Entity_DoAnimCommands(entity, ss_anim); + } } } diff --git a/src/skeletal_model.c b/src/skeletal_model.c index c1582e5a5..f296612b5 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -146,7 +146,7 @@ void SkeletalModel_InterpolateFrames(skeletal_model_p model) vec4_copy(bf->bone_tags[k].qrotate, anim->frames[0].bone_tags[k].qrotate); } bf++; - + for(uint16_t j = 1; j < anim->frames_count; j++) { for(uint16_t lerp_index = 1; lerp_index <= anim->original_frame_rate; lerp_index++) From 98f6e5322d5b624a1944a57ceb0e45476d4a86f0 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Mon, 22 Aug 2016 22:36:47 +0400 Subject: [PATCH 21/24] fixed anim state getting script function; --- src/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script.cpp b/src/script.cpp index e7d1582f2..b22a105ae 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -4223,7 +4223,7 @@ int lua_GetEntityAnimState(lua_State * lua) { if(ss_anim->type == anim_type_id) { - lua_pushinteger(lua, ent->bf->animations.current_state); + lua_pushinteger(lua, ent->bf->animations.next_state); return 1; } } From 2334536dfe616d2615169c6cbefa069ca024a932 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Tue, 23 Aug 2016 20:57:43 +0400 Subject: [PATCH 22/24] fixed "extra frame": resource module upgraded; --- src/anim_state_control.cpp | 2 +- src/character_controller.cpp | 32 +++++----- src/entity.cpp | 4 +- src/resource.cpp | 113 +++++++++++++++++++++++++++++++---- src/script.cpp | 2 +- src/skeletal_model.c | 104 +++----------------------------- src/skeletal_model.h | 12 ++-- 7 files changed, 134 insertions(+), 135 deletions(-) diff --git a/src/anim_state_control.cpp b/src/anim_state_control.cpp index 091980dbf..06f7a935e 100644 --- a/src/anim_state_control.cpp +++ b/src/anim_state_control.cpp @@ -242,7 +242,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim) ss_anim->anim_frame_flags = ANIM_NORMAL_CONTROL; int8_t low_vertical_space = (curr_fc->floor_hit.hit && curr_fc->ceiling_hit.hit && (curr_fc->ceiling_hit.point[2] - curr_fc->floor_hit.point[2] < ent->character->Height - LARA_HANG_VERTICAL_EPSILON)); - int8_t last_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count <= ss_anim->current_frame + 1; + int8_t last_frame = ss_anim->model->animations[ss_anim->current_animation].max_frame <= ss_anim->current_frame + 1; if(resp->kill == 1) // Stop any music, if Lara is dead. { diff --git a/src/character_controller.cpp b/src/character_controller.cpp index 470af87b9..48d2290ff 100644 --- a/src/character_controller.cpp +++ b/src/character_controller.cpp @@ -2425,7 +2425,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; if(ss_anim->current_frame < t - 1) { @@ -2458,7 +2458,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * { ss_anim->current_animation = 2; ss_anim->next_animation = 2; - ss_anim->current_frame = ss_anim->next_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; + ss_anim->current_frame = ss_anim->next_frame = ss_anim->model->animations[ss_anim->current_animation].max_frame - 1; ss_anim->frame_time = 0.0; ss_anim->current_state = WEAPON_STATE_IDLE_TO_HIDE; } @@ -2474,7 +2474,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * case WEAPON_STATE_FIRE_TO_IDLE: // Yes, same animation, reverse frames order; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; ss_anim->frame_time += time; ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; @@ -2498,7 +2498,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; if(ent->character->cmd.ready_weapon) { @@ -2544,7 +2544,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * else { ss_anim->frame_time = 0.0; - ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; + ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].max_frame - 1; ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } break; @@ -2561,7 +2561,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; if(ss_anim->current_frame < t - 1) { @@ -2585,7 +2585,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->frame_time = 0.0; ss_anim->current_animation = 0; ss_anim->next_animation = ss_anim->current_animation; - ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; + ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].max_frame - 1; ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } @@ -2593,7 +2593,7 @@ int Character_DoOneHandWeponFrame(struct entity_s *ent, struct ss_animation_s * case WEAPON_STATE_IDLE_TO_HIDE: // Yes, same animation, reverse frames order; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; ss_anim->frame_time += time; ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; @@ -2640,7 +2640,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * */ int16_t old_anim = ss_anim->next_animation; int16_t old_frame = ss_anim->next_frame; - + if(ss_anim->model->animation_count > 4) { float dt; @@ -2683,7 +2683,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; if(ss_anim->current_frame < t - 1) { @@ -2732,7 +2732,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * case WEAPON_STATE_FIRE_TO_IDLE: // Yes, same animation, reverse frames order; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; ss_anim->frame_time += time; ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; @@ -2756,7 +2756,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; if(ent->character->cmd.ready_weapon) { @@ -2802,7 +2802,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * else { ss_anim->frame_time = 0.0; - ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; + ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].max_frame - 1; ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } break; @@ -2819,7 +2819,7 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; ss_anim->lerp = dt / ss_anim->period; - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; if(ss_anim->current_frame < t - 1) { @@ -2843,14 +2843,14 @@ int Character_DoTwoHandWeponFrame(struct entity_s *ent, struct ss_animation_s * ss_anim->frame_time = 0.0; ss_anim->current_animation = 0; ss_anim->next_animation = ss_anim->current_animation; - ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].frames_count - 1; + ss_anim->current_frame = ss_anim->model->animations[ss_anim->current_animation].max_frame - 1; ss_anim->next_frame = (ss_anim->current_frame > 0) ? (ss_anim->current_frame - 1) : (0); ss_anim->current_state = WEAPON_STATE_FIRE_TO_IDLE; } break; case WEAPON_STATE_IDLE_TO_HIDE: - t = ss_anim->model->animations[ss_anim->current_animation].frames_count; + t = ss_anim->model->animations[ss_anim->current_animation].max_frame; ss_anim->frame_time += time; ss_anim->current_frame = (ss_anim->frame_time) / ss_anim->period; dt = ss_anim->frame_time - (float)ss_anim->current_frame * ss_anim->period; diff --git a/src/entity.cpp b/src/entity.cpp index b54ff1645..0f829392e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -343,7 +343,7 @@ void Entity_UpdateRigidBody(struct entity_s *ent, int force) else { if((ent->bf->animations.model == NULL) || !Physics_IsBodyesInited(ent->physics) || - ((force == 0) && (ent->bf->animations.model->animation_count == 1) && (ent->bf->animations.model->animations->frames_count == 1))) + ((force == 0) && (ent->bf->animations.model->animation_count == 1) && (ent->bf->animations.model->animations->max_frame == 1))) { return; } @@ -1031,7 +1031,7 @@ void Entity_Frame(entity_p entity, float time) } } else if(ss_anim->model && !(ss_anim->anim_frame_flags & ANIM_FRAME_LOCK) && - ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->frames_count > 1))) + ((ss_anim->model->animation_count > 1) || (ss_anim->model->animations->max_frame > 1))) { frame_switch_state = Anim_SetNextFrame(ss_anim, time); if(frame_switch_state >= 0x01) diff --git a/src/resource.cpp b/src/resource.cpp index 7851c444e..c80859187 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -99,6 +99,7 @@ void TR_GetBFrameBB_Pos(class VT_Level *tr, size_t frame_offset, struct bone int TR_GetNumAnimationsForMoveable(class VT_Level *tr, size_t moveable_ind); int TR_GetNumFramesForAnimation(class VT_Level *tr, size_t animation_ind); uint32_t TR_GetOriginalAnimationFrameOffset(uint32_t offset, uint32_t anim, class VT_Level *tr); +void TR_SkeletalModelInterpolateFrames(skeletal_model_p models); // Main functions which are used to translate legacy TR floor data // to native OpenTomb structs. @@ -1552,9 +1553,101 @@ void TR_GenRoomMesh(struct room_s *room, size_t room_index, struct anim_seq_s *a } +void TR_SkeletalModelInterpolateFrames(skeletal_model_p model, tr_animation_t *tr_animations) +{ + uint16_t new_frames_count; + animation_frame_p anim = model->animations; + bone_frame_p bf, new_bone_frames; + float lerp, t; + + for(uint16_t i = 0; i < model->animation_count; i++, anim++) + { + tr_animation_t *tr_anim = tr_animations + i; + if(anim->frames_count > 1 && tr_anim->frame_rate > 1) // we can't interpolate one frame or rate < 2! + { + new_frames_count = (uint16_t)tr_anim->frame_rate * (anim->frames_count - 1) + 1; + bf = new_bone_frames = (bone_frame_p)malloc(new_frames_count * sizeof(bone_frame_t)); + + /* + * the first frame does not changes + */ + bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t)); + bf->bone_tag_count = model->mesh_count; + vec3_set_zero(bf->pos); + vec3_copy(bf->centre, anim->frames[0].centre); + vec3_copy(bf->pos, anim->frames[0].pos); + vec3_copy(bf->bb_max, anim->frames[0].bb_max); + vec3_copy(bf->bb_min, anim->frames[0].bb_min); + for(uint16_t k = 0; k < model->mesh_count; k++) + { + vec3_copy(bf->bone_tags[k].offset, anim->frames[0].bone_tags[k].offset); + vec4_copy(bf->bone_tags[k].qrotate, anim->frames[0].bone_tags[k].qrotate); + } + bf++; + + for(uint16_t j = 1; j < anim->frames_count; j++) + { + for(uint16_t lerp_index = 1; lerp_index <= tr_anim->frame_rate; lerp_index++) + { + vec3_set_zero(bf->pos); + lerp = ((float)lerp_index) / (float)tr_anim->frame_rate; + t = 1.0f - lerp; + + bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t)); + bf->bone_tag_count = model->mesh_count; + + bf->centre[0] = t * anim->frames[j-1].centre[0] + lerp * anim->frames[j].centre[0]; + bf->centre[1] = t * anim->frames[j-1].centre[1] + lerp * anim->frames[j].centre[1]; + bf->centre[2] = t * anim->frames[j-1].centre[2] + lerp * anim->frames[j].centre[2]; + + bf->pos[0] = t * anim->frames[j-1].pos[0] + lerp * anim->frames[j].pos[0]; + bf->pos[1] = t * anim->frames[j-1].pos[1] + lerp * anim->frames[j].pos[1]; + bf->pos[2] = t * anim->frames[j-1].pos[2] + lerp * anim->frames[j].pos[2]; + + bf->bb_max[0] = t * anim->frames[j-1].bb_max[0] + lerp * anim->frames[j].bb_max[0]; + bf->bb_max[1] = t * anim->frames[j-1].bb_max[1] + lerp * anim->frames[j].bb_max[1]; + bf->bb_max[2] = t * anim->frames[j-1].bb_max[2] + lerp * anim->frames[j].bb_max[2]; + + bf->bb_min[0] = t * anim->frames[j-1].bb_min[0] + lerp * anim->frames[j].bb_min[0]; + bf->bb_min[1] = t * anim->frames[j-1].bb_min[1] + lerp * anim->frames[j].bb_min[1]; + bf->bb_min[2] = t * anim->frames[j-1].bb_min[2] + lerp * anim->frames[j].bb_min[2]; + + for(uint16_t k = 0; k < model->mesh_count; k++) + { + bf->bone_tags[k].offset[0] = t * anim->frames[j-1].bone_tags[k].offset[0] + lerp * anim->frames[j].bone_tags[k].offset[0]; + bf->bone_tags[k].offset[1] = t * anim->frames[j-1].bone_tags[k].offset[1] + lerp * anim->frames[j].bone_tags[k].offset[1]; + bf->bone_tags[k].offset[2] = t * anim->frames[j-1].bone_tags[k].offset[2] + lerp * anim->frames[j].bone_tags[k].offset[2]; + + vec4_slerp(bf->bone_tags[k].qrotate, anim->frames[j-1].bone_tags[k].qrotate, anim->frames[j].bone_tags[k].qrotate, lerp); + } + bf++; + } + } + + /* + * swap old and new animation bone brames + * free old bone frames; + */ + for(uint16_t j = 0; j < anim->frames_count; j++) + { + if(anim->frames[j].bone_tag_count) + { + anim->frames[j].bone_tag_count = 0; + free(anim->frames[j].bone_tags); + anim->frames[j].bone_tags = NULL; + } + } + free(anim->frames); + anim->frames = new_bone_frames; + anim->frames_count = new_frames_count; + } + } +} + + void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct base_mesh_s *base_mesh_array, class VT_Level *tr) { - tr_moveable_t *tr_moveable; + tr_moveable_t *tr_moveable = &tr->moveables[model_id]; // original tr structure tr_animation_t *tr_animation; uint32_t frame_offset, frame_step; @@ -1567,7 +1660,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct mesh_tree_tag_p tree_tag; animation_frame_p anim; - tr_moveable = &tr->moveables[model_id]; // original tr structure model->collision_map = (uint16_t*)malloc(model->mesh_count * sizeof(uint16_t)); model->mesh_tree = (mesh_tree_tag_p)calloc(model->mesh_count, sizeof(mesh_tree_tag_t)); tree_tag = model->mesh_tree; @@ -1629,6 +1721,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct model->animation_count = 1; model->animations = (animation_frame_p)malloc(sizeof(animation_frame_t)); model->animations->frames_count = 1; + model->animations->max_frame = 1; model->animations->frames = (bone_frame_p)calloc(model->animations->frames_count , sizeof(bone_frame_t)); bone_frame = model->animations->frames; @@ -1637,7 +1730,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct model->animations->next_frame = 0; model->animations->state_change = NULL; model->animations->state_change_count = 0; - model->animations->original_frame_rate = 1; model->animations->commands = NULL; model->animations->effects = NULL; bone_frame->bone_tag_count = model->mesh_count; @@ -1690,8 +1782,6 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct frame_step = tr_animation->frame_size; anim->id = i; - anim->original_frame_rate = tr_animation->frame_rate; - anim->speed_x = tr_animation->speed; anim->accel_x = tr_animation->accel; anim->speed_y = tr_animation->accel_lateral; @@ -1700,6 +1790,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct anim->effects = NULL; anim->state_id = tr_animation->state_id; + anim->max_frame = tr_animation->frame_end - tr_animation->frame_start + 1; anim->frames_count = TR_GetNumFramesForAnimation(tr, tr_moveable->animation_index + i); //Sys_DebugLog(LOG_FILENAME, "Anim[%d], %d", tr_moveable->animation_index, TR_GetNumFramesForAnimation(tr, tr_moveable->animation_index)); @@ -1875,7 +1966,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct /* * Animations interpolation to 1/30 sec like in original. Needed for correct state change works. */ - SkeletalModel_InterpolateFrames(model); + TR_SkeletalModelInterpolateFrames(model, tr->animations + tr_moveable->animation_index); /* * state change's loading */ @@ -1900,7 +1991,7 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct { anim->next_anim = model->animations + j; anim->next_frame = tr_animation->next_frame - tr->animations[tr_animation->next_animation].frame_start; - anim->next_frame %= anim->next_anim->frames_count; + anim->next_frame %= anim->next_anim->max_frame; if(anim->next_frame < 0) { anim->next_frame = 0; @@ -1940,16 +2031,16 @@ void TR_GenSkeletalModel(struct skeletal_model_s *model, size_t model_id, struct sch_p->anim_dispatch = (anim_dispatch_p)realloc(sch_p->anim_dispatch, sch_p->anim_dispatch_count * sizeof(anim_dispatch_t)); anim_dispatch_p adsp = sch_p->anim_dispatch + sch_p->anim_dispatch_count - 1; - uint16_t next_frames_count = model->animations[next_anim - tr_moveable->animation_index].frames_count; + uint16_t next_max_frame = model->animations[next_anim - tr_moveable->animation_index].max_frame; uint16_t next_frame = tr_adisp->next_frame - tr->animations[next_anim].frame_start; uint16_t low = tr_adisp->low - tr_animation->frame_start; uint16_t high = tr_adisp->high - tr_animation->frame_start; - adsp->frame_low = low % anim->frames_count; - adsp->frame_high = (high - 1) % anim->frames_count; + adsp->frame_low = low % anim->max_frame; + adsp->frame_high = (high - 1) % anim->max_frame; adsp->next_anim = next_anim - tr_moveable->animation_index; - adsp->next_frame = next_frame % next_frames_count; + adsp->next_frame = next_frame % next_max_frame; #if LOG_ANIM_DISPATCHES Sys_DebugLog(LOG_FILENAME, "anim_disp[%d], frames_count = %d: interval[%d.. %d], next_anim = %d, next_frame = %d", l, diff --git a/src/script.cpp b/src/script.cpp index b22a105ae..e4f9a953b 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -3152,7 +3152,7 @@ int lua_GetEntityAnim(lua_State * lua) lua_pushinteger(lua, ent->bf->animations.current_animation); lua_pushinteger(lua, ent->bf->animations.current_frame); - lua_pushinteger(lua, ent->bf->animations.model->animations[ent->bf->animations.current_animation].frames_count); + lua_pushinteger(lua, ent->bf->animations.model->animations[ent->bf->animations.current_animation].max_frame); return 3; } diff --git a/src/skeletal_model.c b/src/skeletal_model.c index f296612b5..ad0621b52 100644 --- a/src/skeletal_model.c +++ b/src/skeletal_model.c @@ -60,6 +60,7 @@ void SkeletalModel_Clear(skeletal_model_p model) } } anim->frames_count = 0; + anim->max_frame = 0; free(anim->frames); anim->frames = NULL; } @@ -116,97 +117,6 @@ void SkeletalModel_GenParentsIndexes(skeletal_model_p model) } -void SkeletalModel_InterpolateFrames(skeletal_model_p model) -{ - uint16_t new_frames_count; - animation_frame_p anim = model->animations; - bone_frame_p bf, new_bone_frames; - float lerp, t; - - for(uint16_t i = 0; i < model->animation_count; i++, anim++) - { - if(anim->frames_count > 1 && anim->original_frame_rate > 1) // we can't interpolate one frame or rate < 2! - { - new_frames_count = (uint16_t)anim->original_frame_rate * (anim->frames_count - 1) + 1; - bf = new_bone_frames = (bone_frame_p)malloc(new_frames_count * sizeof(bone_frame_t)); - - /* - * the first frame does not changes - */ - bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t)); - bf->bone_tag_count = model->mesh_count; - vec3_set_zero(bf->pos); - vec3_copy(bf->centre, anim->frames[0].centre); - vec3_copy(bf->pos, anim->frames[0].pos); - vec3_copy(bf->bb_max, anim->frames[0].bb_max); - vec3_copy(bf->bb_min, anim->frames[0].bb_min); - for(uint16_t k = 0; k < model->mesh_count; k++) - { - vec3_copy(bf->bone_tags[k].offset, anim->frames[0].bone_tags[k].offset); - vec4_copy(bf->bone_tags[k].qrotate, anim->frames[0].bone_tags[k].qrotate); - } - bf++; - - for(uint16_t j = 1; j < anim->frames_count; j++) - { - for(uint16_t lerp_index = 1; lerp_index <= anim->original_frame_rate; lerp_index++) - { - vec3_set_zero(bf->pos); - lerp = ((float)lerp_index) / (float)anim->original_frame_rate; - t = 1.0f - lerp; - - bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t)); - bf->bone_tag_count = model->mesh_count; - - bf->centre[0] = t * anim->frames[j-1].centre[0] + lerp * anim->frames[j].centre[0]; - bf->centre[1] = t * anim->frames[j-1].centre[1] + lerp * anim->frames[j].centre[1]; - bf->centre[2] = t * anim->frames[j-1].centre[2] + lerp * anim->frames[j].centre[2]; - - bf->pos[0] = t * anim->frames[j-1].pos[0] + lerp * anim->frames[j].pos[0]; - bf->pos[1] = t * anim->frames[j-1].pos[1] + lerp * anim->frames[j].pos[1]; - bf->pos[2] = t * anim->frames[j-1].pos[2] + lerp * anim->frames[j].pos[2]; - - bf->bb_max[0] = t * anim->frames[j-1].bb_max[0] + lerp * anim->frames[j].bb_max[0]; - bf->bb_max[1] = t * anim->frames[j-1].bb_max[1] + lerp * anim->frames[j].bb_max[1]; - bf->bb_max[2] = t * anim->frames[j-1].bb_max[2] + lerp * anim->frames[j].bb_max[2]; - - bf->bb_min[0] = t * anim->frames[j-1].bb_min[0] + lerp * anim->frames[j].bb_min[0]; - bf->bb_min[1] = t * anim->frames[j-1].bb_min[1] + lerp * anim->frames[j].bb_min[1]; - bf->bb_min[2] = t * anim->frames[j-1].bb_min[2] + lerp * anim->frames[j].bb_min[2]; - - for(uint16_t k = 0; k < model->mesh_count; k++) - { - bf->bone_tags[k].offset[0] = t * anim->frames[j-1].bone_tags[k].offset[0] + lerp * anim->frames[j].bone_tags[k].offset[0]; - bf->bone_tags[k].offset[1] = t * anim->frames[j-1].bone_tags[k].offset[1] + lerp * anim->frames[j].bone_tags[k].offset[1]; - bf->bone_tags[k].offset[2] = t * anim->frames[j-1].bone_tags[k].offset[2] + lerp * anim->frames[j].bone_tags[k].offset[2]; - - vec4_slerp(bf->bone_tags[k].qrotate, anim->frames[j-1].bone_tags[k].qrotate, anim->frames[j].bone_tags[k].qrotate, lerp); - } - bf++; - } - } - - /* - * swap old and new animation bone brames - * free old bone frames; - */ - for(uint16_t j = 0; j < anim->frames_count; j++) - { - if(anim->frames[j].bone_tag_count) - { - anim->frames[j].bone_tag_count = 0; - free(anim->frames[j].bone_tags); - anim->frames[j].bone_tags = NULL; - } - } - free(anim->frames); - anim->frames = new_bone_frames; - anim->frames_count = new_frames_count; - } - } -} - - void SkeletalModel_FillTransparency(skeletal_model_p model) { model->transparency_flags = MESH_FULL_OPAQUE; @@ -797,8 +707,8 @@ void Anim_SetAnimation(struct ss_animation_s *ss_anim, int animation, int frame) { animation_frame_p anim = &ss_anim->model->animations[animation]; ss_anim->lerp = 0.0; - frame %= anim->frames_count; - frame = (frame >= 0) ? (frame) : (anim->frames_count - 1 + frame); + frame %= anim->max_frame; + frame = (frame >= 0) ? (frame) : (anim->max_frame - 1 + frame); ss_anim->period = 1.0f / 30.0f; ss_anim->changing_curr = 0x04; @@ -838,9 +748,9 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) /* * Flag has a highest priority */ - if((new_frame + 1 >= next_anim->frames_count) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) + if((new_frame + 1 >= next_anim->max_frame) && (ss_anim->anim_frame_flags == ANIM_LOOP_LAST_FRAME)) { - ss_anim->next_frame = next_anim->frames_count - 1; + 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; @@ -882,9 +792,9 @@ int Anim_SetNextFrame(struct ss_animation_s *ss_anim, float time) } /* - * Check next anim if frame >= frames_count + * Check next anim if frame >= max_frame */ - if(new_frame + 1 > next_anim->frames_count) + if(new_frame + 1 > next_anim->max_frame) { ss_anim->current_animation = ss_anim->next_animation; ss_anim->current_frame = ss_anim->next_frame; diff --git a/src/skeletal_model.h b/src/skeletal_model.h index b47cc2e3f..190114cd0 100644 --- a/src/skeletal_model.h +++ b/src/skeletal_model.h @@ -203,8 +203,12 @@ typedef struct animation_effect_s typedef struct animation_frame_s { uint32_t id; - uint16_t original_frame_rate; uint16_t state_id; + uint16_t max_frame; + uint16_t frames_count; // Number of frames + uint16_t state_change_count; // Number of animation statechanges + struct bone_frame_s *frames; // Frame data + struct state_change_s *state_change; // Animation statechanges data struct animation_command_s *commands; struct animation_effect_s *effects; @@ -213,11 +217,6 @@ typedef struct animation_frame_s float accel_x; // Forward-backward accel float speed_y; // Left-right speed float accel_y; // Left-right accel - - uint16_t frames_count; // Number of frames - uint16_t state_change_count; // Number of animation statechanges - struct bone_frame_s *frames; // Frame data - struct state_change_s *state_change; // Animation statechanges data struct animation_frame_s *next_anim; // Next default animation int32_t next_frame; // Next default frame @@ -247,7 +246,6 @@ typedef struct skeletal_model_s void SkeletalModel_Clear(skeletal_model_p model); void SkeletalModel_GenParentsIndexes(skeletal_model_p model); -void SkeletalModel_InterpolateFrames(skeletal_model_p models); void SkeletalModel_FillTransparency(skeletal_model_p model); void SkeletalModel_FillSkinnedMeshMap(skeletal_model_p model); From 7b0d0e3525355d74a856237bf3cb3bd3360ac800 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Tue, 23 Aug 2016 22:05:58 +0400 Subject: [PATCH 23/24] fixed animation frame info returning in script; --- scripts/entity/entity_functions.lua | 26 ++++++++++++++------------ scripts/entity/script_switch.lua | 6 +++--- scripts/system/debug.lua | 2 +- scripts/trigger/trigger_functions.lua | 3 ++- src/script.cpp | 18 ++++++++++++------ 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/scripts/entity/entity_functions.lua b/scripts/entity/entity_functions.lua index 575e200bb..670d9e0b0 100644 --- a/scripts/entity/entity_functions.lua +++ b/scripts/entity/entity_functions.lua @@ -53,7 +53,7 @@ function door_init(id) -- NORMAL doors only! setEntityActivity(object_id, 1); entity_funcs[id].onActivate = function(object_id, activator_id) - local a, f, c = getEntityAnim(object_id); + local a, f, c = getEntityAnim(object_id, ANIM_TYPE_BASE); if(c == 1) then return swapEntityState(object_id, 0, 1); end; @@ -306,8 +306,10 @@ function heli_rig_TR2_init(id) -- Helicopter in Offshore Rig (TR2) if(getEntityAnimState(object_id, ANIM_TYPE_BASE) ~= 2) then setEntityAnimState(object_id, ANIM_TYPE_BASE, 2); else - local anim, frame, count = getEntityAnim(object_id); - if(frame == count-1) then disableEntity(object_id) end; + local anim, frame, count = getEntityAnim(object_id, ANIM_TYPE_BASE); + if(frame == count-1) then + disableEntity(object_id) + end; end end; end @@ -614,7 +616,7 @@ function wallblade_init(id) -- Wall blade (TR1-TR3) entity_funcs[id].onLoop = function(object_id) if(tickEntity(object_id) == TICK_STOPPED) then setEntityActivity(object_id, 0) end; - local anim_number = getEntityAnim(object_id); + local anim_number = getEntityAnim(object_id, ANIM_TYPE_BASE); if(anim_number == 2) then setEntityAnim(object_id, ANIM_TYPE_BASE, 3, 0); elseif(anim_number == 1) then @@ -695,7 +697,7 @@ function pickup_init(id, item_id) -- Pick-ups end local need_set_pos = true; - local curr_anim = getEntityAnim(activator_id); + local curr_anim = getEntityAnim(activator_id, ANIM_TYPE_BASE); if(curr_anim == 103) then -- Stay idle local dx, dy, dz = getEntityVector(object_id, activator_id); @@ -729,7 +731,7 @@ function pickup_init(id, item_id) -- Pick-ups end; end; - local a, f, c = getEntityAnim(activator_id); + local a, f, c = getEntityAnim(activator_id, ANIM_TYPE_BASE); -- Standing pickup anim makes action on frame 40 in TR1-3, in TR4-5 -- it was generalized with all rest animations by frame 16. if((a == 135) and (getLevelVersion() < TR_IV)) then @@ -776,14 +778,14 @@ function fallblock_init(id) -- Falling block (TR1-3) return; end - local anim = getEntityAnim(object_id); + local anim = getEntityAnim(object_id, ANIM_TYPE_BASE); if(anim == 0) then setEntityAnim(object_id, ANIM_TYPE_BASE, 1, 0); -- print("you trapped to id = "..object_id); local once = true; addTask( function() - local anim = getEntityAnim(object_id); + local anim = getEntityAnim(object_id, ANIM_TYPE_BASE); if(anim == 1) then return true; end; @@ -815,7 +817,7 @@ function fallceiling_init(id) -- Falling ceiling (TR1-3) return ENTITY_TRIGGERING_NOT_READY; end - local anim = getEntityAnim(object_id); + local anim = getEntityAnim(object_id, ANIM_TYPE_BASE); if(anim == 0) then setEntityAnim(object_id, ANIM_TYPE_BASE, 1, 0); setEntityVisibility(object_id, 1); @@ -834,7 +836,7 @@ function fallceiling_init(id) -- Falling ceiling (TR1-3) end; entity_funcs[id].onCollide = function(object_id, activator_id) - if((getEntityAnim(object_id) == 1) and (getEntityModelID(activator_id) == 0) and (getCharacterParam(activator_id, PARAM_HEALTH) > 0)) then + if((getEntityAnim(object_id, ANIM_TYPE_BASE) == 1) and (getEntityModelID(activator_id) == 0) and (getCharacterParam(activator_id, PARAM_HEALTH) > 0)) then setCharacterParam(activator_id, PARAM_HEALTH, 0); end; end @@ -872,11 +874,11 @@ function midastouch_init(id) -- Midas gold touch entity_funcs[id].onLoop = function(object_id) if(getEntityDistance(player, object_id) < 1024.0) then - local lara_anim, frame, count = getEntityAnim(player); + local lara_anim, frame, count = getEntityAnim(player, ANIM_TYPE_BASE); local lara_sector = getEntitySectorIndex(player); local hand_sector = getEntitySectorIndex(object_id); - if((lara_sector == hand_sector) and (getEntityMoveType(player) == MOVE_ON_FLOOR) and (getEntityAnim(player) ~= 50)) then + if((lara_sector == hand_sector) and (getEntityMoveType(player) == MOVE_ON_FLOOR) and (lara_anim ~= 50)) then setCharacterParam(player, PARAM_HEALTH, 0); entitySSAnimEnsureExists(player, ANIM_TYPE_MISK_1, 5); --ANIM_TYPE_MISK_1 - add const setEntityAnim(player, ANIM_TYPE_MISK_1, 1, 0); diff --git a/scripts/entity/script_switch.lua b/scripts/entity/script_switch.lua index f0d712ed9..e53d5dfce 100644 --- a/scripts/entity/script_switch.lua +++ b/scripts/entity/script_switch.lua @@ -328,7 +328,7 @@ function switch_activate(object_id, actor_id) -- actor ID is needed to activat end end - local t = getEntityAnim(object_id); + local t = getEntityAnim(object_id, ANIM_TYPE_BASE); if(on.ready_anim < 0 or on.ready_anim == t) then if(key ~= nil) then @@ -347,7 +347,7 @@ function switch_activate(object_id, actor_id) -- actor ID is needed to activat setEntityActivity(object_id, 1); addTask( function() - local a, f, c = getEntityAnim(actor_id); + local a, f, c = getEntityAnim(actor_id, ANIM_TYPE_BASE); if(on.switch_frame ~= nil) then c = on.switch_frame end @@ -371,7 +371,7 @@ function switch_activate(object_id, actor_id) -- actor ID is needed to activat setEntityActivity(object_id, 1); addTask( function() - local a, f, c = getEntityAnim(actor_id); + local a, f, c = getEntityAnim(actor_id, ANIM_TYPE_BASE); if(off.switch_frame ~= nil) then c = off.switch_frame end diff --git a/scripts/system/debug.lua b/scripts/system/debug.lua index ac7611fe7..aa9e8f4ee 100644 --- a/scripts/system/debug.lua +++ b/scripts/system/debug.lua @@ -109,7 +109,7 @@ function checkDebugKeys() end; function checkPlayerRagdollConditions() - local anim, frame, count = getEntityAnim(player); + local anim, frame, count = getEntityAnim(player, ANIM_TYPE_BASE); local version = getLevelVersion(); if(getEntityTypeFlag(player, ENTITY_TYPE_DYNAMIC) == 0) then diff --git a/scripts/trigger/trigger_functions.lua b/scripts/trigger/trigger_functions.lua index 7135f8b5a..c93929858 100644 --- a/scripts/trigger/trigger_functions.lua +++ b/scripts/trigger/trigger_functions.lua @@ -49,7 +49,8 @@ end; function moveToSink(entity_index, sink_index) local movetype = getEntityMoveType(entity_index); if(movetype == 5) then -- Dive, if on water. - if(getEntityAnim(entity_index) ~= 113) then + anim = getEntityAnim(entity_index, ANIM_TYPE_BASE); + if(anim ~= 113) then setEntityAnim(entity_index, ANIM_TYPE_BASE, 113, 0); setEntityMoveType(entity_index, 6); end; diff --git a/src/script.cpp b/src/script.cpp index e4f9a953b..0965bfb62 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -3135,9 +3135,9 @@ int lua_SetModelBodyPartFlag(lua_State * lua) int lua_GetEntityAnim(lua_State * lua) { - if(lua_gettop(lua) < 1) + if(lua_gettop(lua) < 2) { - Con_Warning("getEntityAnim: expecting arguments (entity_id)"); + Con_Warning("getEntityAnim: expecting arguments (entity_id, anim_type_id)"); return 0; } @@ -3150,11 +3150,17 @@ int lua_GetEntityAnim(lua_State * lua) return 0; } - lua_pushinteger(lua, ent->bf->animations.current_animation); - lua_pushinteger(lua, ent->bf->animations.current_frame); - lua_pushinteger(lua, ent->bf->animations.model->animations[ent->bf->animations.current_animation].max_frame); + int anim_id = lua_tointeger(lua, 2); + ss_animation_p ss_anim = SSBoneFrame_GetOverrideAnim(ent->bf, anim_id); + if(ss_anim && ss_anim->model) + { + lua_pushinteger(lua, ss_anim->next_animation); + lua_pushinteger(lua, ss_anim->next_frame); + lua_pushinteger(lua, ss_anim->model->animations[ss_anim->next_animation].max_frame); + return 3; + } - return 3; + return 0; } From e3ea641fb1c95a62d3c3b8188839486dbf9ce083 Mon Sep 17 00:00:00 2001 From: TeslaRus Date: Wed, 24 Aug 2016 19:22:22 +0400 Subject: [PATCH 24/24] no more max_frame > frames_count; added half-hack to anim move command condition; --- src/entity.cpp | 2 +- src/resource.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/entity.cpp b/src/entity.cpp index 0f829392e..af0859482 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -668,7 +668,7 @@ void Entity_DoAnimCommands(entity_p entity, struct ss_animation_s *ss_anim) switch(command->id) { case TR_ANIMCOMMAND_SETPOSITION: - if(ss_anim->changing_next >= 0x02) // This command executes ONLY at the end of animation. + if((ss_anim->onEndFrame == NULL) && (ss_anim->changing_next >= 0x02)) // This command executes ONLY at the end of animation. { float tr[3]; entity->no_fix_all = 0x01; diff --git a/src/resource.cpp b/src/resource.cpp index c80859187..09cfc50d8 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1625,7 +1625,7 @@ void TR_SkeletalModelInterpolateFrames(skeletal_model_p model, tr_animation_t *t } /* - * swap old and new animation bone brames + * swap old and new animation bone frames * free old bone frames; */ for(uint16_t j = 0; j < anim->frames_count; j++) @@ -1641,6 +1641,10 @@ void TR_SkeletalModelInterpolateFrames(skeletal_model_p model, tr_animation_t *t anim->frames = new_bone_frames; anim->frames_count = new_frames_count; } + if(anim->max_frame > anim->frames_count) + { + anim->max_frame = anim->frames_count; // i.e.: unused animations + } } }