From c430fee76ffd54d1c19449f6f09613f686f7b186 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Tue, 3 Oct 2023 23:03:21 +0300 Subject: [PATCH] Better transition between motions in Edit PVs --- src/CRE/rob/ex_block.cpp | 82 +++--- src/CRE/rob/rob.cpp | 585 ++++++++++++++++++++------------------- src/CRE/rob/rob.hpp | 81 +++--- 3 files changed, 387 insertions(+), 361 deletions(-) diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index d5691a7e..840638f7 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -100,8 +100,6 @@ static void sub_14047F990(RobOsage* rob_osg, const mat4* root_matrix, const vec3* parent_scale, bool a4); static void sub_140480260(RobOsage* rob_osg, const mat4* root_matrix, const vec3* parent_scale, float_t step, bool disable_external_force); -static void sub_140482100(struc_476* a1, opd_blend_data* a2, struc_477* a3); -static void sub_140482DF0(struc_477* dst, struc_477* src0, struc_477* src1, float_t blend); static bool sub_140482FF0(mat4& mat, vec3& trans, skin_param_hinge* hinge, vec3* rot, int32_t& yz_order); static void sub_14053CE30(RobOsageNodeDataNormalRef* normal_ref, mat4* a2); static bool sub_14053D1B0(vec3* l_trans, vec3* r_trans, @@ -356,17 +354,39 @@ void RobOsageNodeData::SetForce(const skin_param_osage_root& skp_root, this->force = force; } -struc_477::struc_477() : length() { +opd_node_data::opd_node_data() : length() { } -struc_476::struc_476() { +opd_node_data::opd_node_data(float_t length, vec3 rotation) { + this->length = length; + this->rotation = rotation; +} + +void opd_node_data::lerp(opd_node_data& dst, const opd_node_data& src0, const opd_node_data& src1, float_t blend) { + dst.length = lerp_def(src0.length, src1.length, blend); + dst.rotation = vec3::lerp(src0.rotation, src1.rotation, blend); +} + +opd_node_data_pair::opd_node_data_pair() { } -RobOsageNode::RobOsageNode() : length(), trans(), trans_orig(), trans_diff(), field_28(), -child_length(), bone_node_ptr(), bone_node_mat(), sibling_node(), max_distance(), -field_94(), reset_data(), field_C8(), external_force(), mat(), field_1B0() { +void opd_node_data_pair::set_data(opd_blend_data* blend_data, opd_node_data&& node_data) { + if (!blend_data->use_blend) + curr = node_data; + else if (blend_data->type == MOTION_BLEND_FREEZE) { + if (blend_data->blend == 0.0f) + prev = curr; + opd_node_data::lerp(curr, prev, node_data, blend_data->blend); + } + else if (blend_data->type == MOTION_BLEND_CROSS) + opd_node_data::lerp(curr, curr, node_data, blend_data->blend); +} + +RobOsageNode::RobOsageNode() : length(), trans(), trans_orig(), trans_diff(), +field_28(), child_length(), bone_node_ptr(), bone_node_mat(), sibling_node(), +max_distance(), field_94(), reset_data(), field_C8(), external_force(), mat() { field_CC = 1.0f; force = 1.0f; data_ptr = &data; @@ -772,7 +792,7 @@ osage_ring_data::~osage_ring_data() { CLOTHNode::CLOTHNode() : flags(), trans(), trans_orig(), field_1C(), trans_diff(), normal(), tangent(), binormal(), tangent_sign(), texcoord(), field_64(), dist_top(), dist_bottom(), -dist_right(), dist_left(), field_80(), field_88(), reset_data(), field_B4(), field_D0() { +dist_right(), dist_left(), field_80(), field_88(), reset_data(), field_B4() { } @@ -1241,10 +1261,7 @@ void RobCloth::SetOsagePlayData(std::vector& opd_blend_data) { mat4_translate_mult(&mat, vec3::distance(v57, v26), 0.0f, 0.0f, &mat); - struc_477 v83; - v83.rotation = rotation; - v83.length = v29->dist_top; - sub_140482100(&v29->field_D0, i, &v83); + v29->opd_node_data.set_data(i, { v29->dist_top, rotation }); v26 = v61; } @@ -1264,9 +1281,9 @@ void RobCloth::SetOsagePlayData(std::vector& opd_blend_data) { sub_140482FF0(mat, v78, 0, 0, yz_order); for (size_t j = 1; j < nodes_count; j++, v50 += root_count) { - mat4_rotate_z_mult(&mat, v50->field_D0.field_0.rotation.z, &mat); - mat4_rotate_y_mult(&mat, v50->field_D0.field_0.rotation.y, &mat); - mat4_translate_mult(&mat, v50->field_D0.field_0.length, 0.0f, 0.0f, &mat); + mat4_rotate_z_mult(&mat, v50->opd_node_data.curr.rotation.z, &mat); + mat4_rotate_y_mult(&mat, v50->opd_node_data.curr.rotation.y, &mat); + mat4_translate_mult(&mat, v50->opd_node_data.curr.length, 0.0f, 0.0f, &mat); mat4_get_translation(&mat, &v50->trans); } } @@ -1493,7 +1510,7 @@ void ExClothBlock::Field_20() { rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; float_t step = get_delta_frame() * rob_itm_equip->osage_step; - if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data[0].field_C) + if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data.front().use_blend) step = 1.0f; sub_140218560(&rob, step, false); } @@ -1948,10 +1965,8 @@ void RobOsage::SetOsagePlayData(const mat4* root_matrix, sub_140482FF0(v87, v86, 0, &rotation, yz_order); mat4_set_translation(&v87, &v82); - struc_477 v72; - v72.rotation = rotation; - v72.length = vec3::distance(v62, v22) * inv_blend + vec3::distance(v77, v25) * blend; - sub_140482100(&j->field_1B0, i, &v72); + float_t length = vec3::distance(v62, v22) * inv_blend + vec3::distance(v77, v25) * blend; + j->opd_node_data.set_data(i, { length, rotation }); v22 = v62; v25 = v77; @@ -1961,8 +1976,8 @@ void RobOsage::SetOsagePlayData(const mat4* root_matrix, RobOsageNode* j_begin = nodes.data() + 1; RobOsageNode* j_end = nodes.data() + nodes.size(); for (RobOsageNode* j = j_begin; j != j_end; j++) { - float_t rot_y = j->field_1B0.field_0.rotation.y; - float_t rot_z = j->field_1B0.field_0.rotation.z; + float_t rot_y = j->opd_node_data.curr.rotation.y; + float_t rot_z = j->opd_node_data.curr.rotation.z; rot_y = clamp_def(rot_y, (float_t)-M_PI, (float_t)M_PI); rot_z = clamp_def(rot_z, (float_t)-M_PI, (float_t)M_PI); mat4_rotate_z_mult(&v85, rot_z, &v85); @@ -1973,7 +1988,7 @@ void RobOsage::SetOsagePlayData(const mat4* root_matrix, if (j->bone_node_mat) mat4_scale_rot(&v85, &parent_scale, j->bone_node_mat); - mat4_translate_mult(&v85, j->field_1B0.field_0.length, 0.0f, 0.0f, &v85); + mat4_translate_mult(&v85, j->opd_node_data.curr.length, 0.0f, 0.0f, &v85); j->trans_orig = j->trans; mat4_get_translation(&v85, &j->trans); } @@ -2068,7 +2083,7 @@ void ExOsageBlock::Field_10() { void ExOsageBlock::Field_18(int32_t stage, bool disable_external_force) { rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; float_t step = get_delta_frame() * rob_itm_equip->osage_step; - if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data[0].field_C) + if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data.front().use_blend) step = 1.0f; mat4* root_matrix = parent_bone_node->ex_data_mat; @@ -2109,7 +2124,7 @@ void ExOsageBlock::Field_20() { rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; float_t step = get_delta_frame() * rob_itm_equip->osage_step; - if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data[0].field_C) + if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data.front().use_blend) step = 1.0f; vec3 parent_scale = parent_bone_node->exp_data.parent_scale; @@ -3997,23 +4012,6 @@ static void sub_140480260(RobOsage* rob_osg, const mat4* root_matrix, rob_osg->root_matrix = *rob_osg->root_matrix_ptr; } -static void sub_140482100(struc_476* a1, opd_blend_data* a2, struc_477* a3) { - if (!a2->field_C) - a1->field_0 = *a3; - else if (a2->type == MOTION_BLEND_FREEZE) { - if (a2->blend == 0.0f) - a1->field_10 = a1->field_0; - sub_140482DF0(&a1->field_0, &a1->field_10, a3, a2->blend); - } - else if (a2->type == MOTION_BLEND_CROSS) - sub_140482DF0(&a1->field_0, &a1->field_0, a3, a2->blend); -} - -static void sub_140482DF0(struc_477* dst, struc_477* src0, struc_477* src1, float_t blend) { - dst->length = lerp_def(src0->length, src1->length, blend); - dst->rotation = vec3::lerp(src0->rotation, src1->rotation, blend); -} - static bool sub_140482FF0(mat4& mat, vec3& trans, skin_param_hinge* hinge, vec3* rot, int32_t& yz_order) { bool clipped = false; float_t z_rot; diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 57a69088..47920d5f 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -4780,7 +4780,7 @@ static float_t bone_data_limit_angle(float_t angle) { } static void bone_data_mult_0(bone_data* a1, int32_t skeleton_select) { - if (a1->flags) + if (a1->check_flags_not_null()) return; mat4 mat; @@ -4839,7 +4839,7 @@ static void bone_data_mult_1(bone_data* a1, mat4* parent_mat, bone_data* a3, boo mat4_translate_mult(&mat, &a1->trans, &mat); if (solve_ik) { a1->node[0].exp_data.rotation = 0.0f; - if (!a1->flags) + if (!a1->check_flags_not_null()) mat4_get_rotation(&a1->rot_mat[0], &a1->node[0].exp_data.rotation); else if (bone_data_mult_1_exp_data(a1, &a1->node[0].exp_data, a3)) mat4_rotate_zyx(&a1->node[0].exp_data.rotation, &a1->rot_mat[0]); @@ -5254,51 +5254,6 @@ static void bone_data_mult_ik(bone_data* a1, int32_t skeleton_select) { *a1->node[3].mat = mat; } -static vec3* bone_data_set_key_data(bone_data* data, vec3* keyframe_data, - bone_database_skeleton_type skeleton_type, bool get_data, bool reverse_x) { - bone_database_bone_type type = data->type; - if (type == BONE_DATABASE_BONE_POSITION_ROTATION) { - if (get_data) { - data->trans = *keyframe_data; - if (reverse_x) - data->trans.x = -data->trans.x; - } - keyframe_data++; - } - else if (type >= BONE_DATABASE_BONE_HEAD_IK_ROTATION - && type <= BONE_DATABASE_BONE_LEGS_IK_ROTATION) { - if (get_data) { - data->ik_target = *keyframe_data; - if (reverse_x) - data->ik_target.x = -data->ik_target.x; - } - keyframe_data++; - } - - if (get_data) { - if (type == BONE_DATABASE_BONE_TYPE_1 || type == BONE_DATABASE_BONE_POSITION) { - data->trans = *keyframe_data; - if (reverse_x) - data->trans.x = -data->trans.x; - } - else if (!data->flags) { - data->rotation = *keyframe_data; - if (reverse_x) { - const skeleton_rotation_offset* rot_off = skeleton_rotation_offset_array; - size_t index = data->motion_bone_index; - if (rot_off[index].x) - data->rotation.x = rot_off[index].rotation.x - data->rotation.x; - if (rot_off[index].y) - data->rotation.y = rot_off[index].rotation.y - data->rotation.y; - if (rot_off[index].z) - data->rotation.z = rot_off[index].rotation.z - data->rotation.z; - } - } - } - keyframe_data++; - return keyframe_data; -} - static void bone_data_parent_data_init(bone_data_parent* bone, rob_chara_bone_data* rob_bone_data, const bone_database* bone_data) { const char* base_name = bone_database_skeleton_type_to_string(rob_bone_data->base_skeleton_type); @@ -5454,7 +5409,7 @@ static void mot_blend_interpolate(mot_blend* a1, std::vector& bones, mot_key_data_interpolate(&a1->mot_key_data, frame, data->key_set_offset, data->key_set_count); data->frame = frame; } - keyframe_data = bone_data_set_key_data(data, keyframe_data, skeleton_type, get_data, 0); + keyframe_data = data->set_key_data(keyframe_data, skeleton_type, get_data, 0); } } @@ -6605,7 +6560,7 @@ static void mothead_func_68(mothead_func_data* func_data, motion_blend_mot* v2 = func_data->rob_chr->bone_data->motion_loaded.front(); v2->mot_key_data.frame = -1.0f; v2->mot_key_data.field_68.field_0 = ((int32_t*)data)[0]; - v2->mot_key_data.field_68.field_4 = ((float_t*)data)[0]; + v2->mot_key_data.field_68.field_4 = ((float_t*)data)[1]; } static void mothead_func_69_motion_max_frame(mothead_func_data* func_data, @@ -7013,7 +6968,7 @@ static void motion_blend_mot_interpolate(motion_blend_mot* a1) { data->frame = frame; } - keyframe_data = bone_data_set_key_data(data, keyframe_data, skeleton_type, get_data, reverse); + keyframe_data = data->set_key_data(keyframe_data, skeleton_type, get_data, reverse); } uint32_t bone_key_set_count = a1->bone_data.bone_key_set_count; @@ -7220,39 +7175,11 @@ static void motion_blend_mot_load_bone_data(motion_blend_mot* a1, sub_140413350(&a1->field_0, bone_check_func, a1->bone_data.motion_bone_count); } -static void sub_1401EB1D0(bone_data* a1, int32_t skeleton_select) { - if (!a1->flags) { - switch (a1->type) { - case BONE_DATABASE_BONE_ROTATION: - a1->rot_mat_prev[0][skeleton_select] = a1->rot_mat[0]; - break; - case BONE_DATABASE_BONE_TYPE_1: - case BONE_DATABASE_BONE_POSITION: - case BONE_DATABASE_BONE_POSITION_ROTATION: - a1->trans_prev[skeleton_select] = a1->trans; - a1->rot_mat_prev[0][skeleton_select] = a1->rot_mat[0]; - break; - case BONE_DATABASE_BONE_HEAD_IK_ROTATION: - a1->rot_mat_prev[0][skeleton_select] = a1->rot_mat[0]; - break; - case BONE_DATABASE_BONE_ARM_IK_ROTATION: - a1->rot_mat_prev[0][skeleton_select] = a1->rot_mat[0]; - a1->rot_mat_prev[1][skeleton_select] = a1->rot_mat[1]; - break; - case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - a1->rot_mat_prev[0][skeleton_select] = a1->rot_mat[0]; - a1->rot_mat_prev[1][skeleton_select] = a1->rot_mat[1]; - a1->rot_mat_prev[2][skeleton_select] = a1->rot_mat[2]; - break; - } - } -} - static void sub_140412E10(motion_blend_mot* a1, int32_t skeleton_select) { for (bone_data& i : a1->bone_data.bones) if ((1 << (i.motion_bone_index & 0x1F)) & a1->field_0.field_8.bitfield.data()[i.motion_bone_index >> 5]) { - sub_1401EB1D0(&i, skeleton_select); + i.store_curr_rot_trans(skeleton_select); if (i.type == BONE_DATABASE_BONE_POSITION_ROTATION && (a1->field_4F8.field_0 & 0x02)) i.trans_prev[skeleton_select] += a1->field_4F8.field_90; } @@ -7262,7 +7189,7 @@ static void sub_140412F20(mot_blend* a1, std::vector* a2) { for (bone_data& i : *a2) if (((1 << (i.motion_bone_index & 0x1F)) & a1->field_0.field_8.bitfield.data()[i.motion_bone_index >> 5]) != 0) - sub_1401EB1D0(&i, 0); + i.store_curr_rot_trans(0); } static void motion_blend_mot_load_file(motion_blend_mot* a1, uint32_t motion_id, @@ -7333,8 +7260,8 @@ static void motion_blend_mot_set_blend(motion_blend_mot* a1, a1->blend = &a1->combine; a1->blend->blend = clamp_def(blend, 0.0f, 1.0f); + a1->blend->field_8 = true; a1->blend->enable = true; - a1->blend->rot_y = true; break; } } @@ -7864,7 +7791,7 @@ static void sub_1405508F0(rob_chara* rob_chr, const motion_database* mot_db) { } static bool sub_1404190E0(rob_chara_bone_data* rob_bone_data) { - return rob_bone_data->eyelid.blend.enable || rob_bone_data->eyelid.blend.rot_y; + return rob_bone_data->eyelid.blend.field_8 || rob_bone_data->eyelid.blend.enable; } static void sub_140555F70(rob_chara* rob_chr, const motion_database* mot_db) { @@ -8259,12 +8186,6 @@ static void rob_disp_rob_chara_ctrl(rob_chara* rob_chr) { sub_140349C30(v3);*/ } -static bool sub_140413810(motion_blend_mot* a1) { - if (a1->blend && a1->blend->Field_30()) - return a1->blend->rot_y; - return false; -} - static void rob_disp_rob_chara_ctrl_thread_main(rob_chara* rob_chr) { if (rob_chr->bone_data->get_frame() < 0.0f) rob_chr->bone_data->set_frame(0.0f); @@ -10059,7 +9980,7 @@ static void sub_140415A10(motion_blend_mot* a1) { } static bool sub_140410A20(motion_blend_mot* a1) { - return !a1->blend || !a1->blend->rot_y; + return !a1->blend || !a1->blend->enable; } static void sub_140415B30(mot_blend* a1) { @@ -10158,48 +10079,9 @@ static void rob_chara_bone_data_reserve(rob_chara_bone_data* rob_bone_data) { rob_bone_data->nodes.resize(rob_bone_data->total_bone_count); } -static void sub_1401EAD00(bone_data* a1, bone_data* a2) { - if (a1->flags) - return; - - switch (a1->type) { - case BONE_DATABASE_BONE_TYPE_1: - case BONE_DATABASE_BONE_POSITION: - case BONE_DATABASE_BONE_POSITION_ROTATION: - a1->trans = a2->trans; - a1->trans_prev[0] = a2->trans_prev[0]; - break; - } - - switch (a1->type) { - case BONE_DATABASE_BONE_ROTATION: - case BONE_DATABASE_BONE_TYPE_1: - case BONE_DATABASE_BONE_POSITION: - case BONE_DATABASE_BONE_POSITION_ROTATION: - a1->rot_mat[0] = a2->rot_mat[0]; - a1->rot_mat_prev[0][0] = a2->rot_mat_prev[0][0]; - break; - case BONE_DATABASE_BONE_HEAD_IK_ROTATION: - a1->rot_mat[0] = a2->rot_mat[0]; - a1->rot_mat[1] = a2->rot_mat[1]; - a1->rot_mat_prev[0][0] = a2->rot_mat_prev[0][0]; - a1->rot_mat_prev[1][0] = a2->rot_mat_prev[1][0]; - break; - case BONE_DATABASE_BONE_ARM_IK_ROTATION: - case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - a1->rot_mat[0] = a2->rot_mat[0]; - a1->rot_mat[1] = a2->rot_mat[1]; - a1->rot_mat[2] = a2->rot_mat[2]; - a1->rot_mat_prev[0][0] = a2->rot_mat_prev[0][0]; - a1->rot_mat_prev[1][0] = a2->rot_mat_prev[1][0]; - a1->rot_mat_prev[2][0] = a2->rot_mat_prev[2][0]; - break; - } -} - static void sub_140412BB0(motion_blend_mot* a1, std::vector& bones) { for (bone_data& i : a1->bone_data.bones) - sub_1401EAD00(&i, &bones[i.motion_bone_index]); + i.copy_rot_trans(&bones[i.motion_bone_index]); } static void sub_14041AE40(rob_chara_bone_data* rob_bone_data) { @@ -10607,7 +10489,7 @@ static void sub_14040FBF0(motion_blend_mot* a1, float_t a2) { static void sub_140410A40(motion_blend_mot* a1, std::vector* a2, std::vector* a3) { MotionBlend* v4 = a1->blend; - if (!v4 || !v4->rot_y) + if (!v4 || !v4->enable) return; v4->Field_20(a2, a3); @@ -10619,16 +10501,17 @@ static void sub_140410A40(motion_blend_mot* a1, std::vector* a2, std: bone_data* v8 = 0; if (a3) v8 = &a3->data()[i.motion_bone_index]; - a1->blend->Blend(&a2->data()[i.motion_bone_index], v8); + v4->Blend(&a2->data()[i.motion_bone_index], v8); } } static void sub_140410B70(motion_blend_mot* a1, std::vector* a2) { MotionBlend* v3 = a1->blend; - if (!v3 || !v3->rot_y) + if (!v3 || !v3->enable) return; v3->Field_20(&a1->bone_data.bones, a2); + for (bone_data& i : a1->bone_data.bones) { if (!sub_140410250(&a1->field_0.field_8, i.motion_bone_index)) continue; @@ -10636,12 +10519,12 @@ static void sub_140410B70(motion_blend_mot* a1, std::vector* a2) { bone_data* v6 = 0; if (a2) v6 = &a2->data()[i.motion_bone_index]; - a1->blend->Blend(&a1->bone_data.bones.data()[i.motion_bone_index], v6); + v3->Blend(&a1->bone_data.bones.data()[i.motion_bone_index], v6); } } static void sub_140410CB0(mot_blend* a1, std::vector* a2) { - if (!a1->blend.rot_y) + if (!a1->blend.enable) return; for (bone_data& i : *a2) @@ -10672,13 +10555,16 @@ static void sub_1404182B0(rob_chara_bone_data* rob_bone_data) { if (sub_1404136B0(*j)) continue; + std::vector* bones = 0; if (j != rob_bone_data->motion_loaded.rbegin()) { auto v5 = j; v5--; - sub_140410B70(*j, &(*v5)->bone_data.bones); + bones = &(*v5)->bone_data.bones; } - else if ((*j)->get_type() == MOTION_BLEND_FREEZE) - sub_140410B70(*j, 0); + else if ((*j)->get_type() != MOTION_BLEND_FREEZE) + continue; + + sub_140410B70(*j, bones); } sub_140410CB0(&rob_bone_data->face, &v3->bone_data.bones); @@ -11566,6 +11452,127 @@ parent_mat(), node(), ik_segment_length(), ik_2nd_segment_length(), arm_length() eyes_xrot_adjust_pos = 1.0f; } +void bone_data::copy_rot_trans(bone_data* data) { + if (check_flags_not_null()) + return; + + switch (type) { + case BONE_DATABASE_BONE_TYPE_1: + case BONE_DATABASE_BONE_POSITION: + case BONE_DATABASE_BONE_POSITION_ROTATION: + trans = data->trans; + trans_prev[0] = data->trans_prev[0]; + break; + } + + switch (type) { + case BONE_DATABASE_BONE_ROTATION: + case BONE_DATABASE_BONE_TYPE_1: + case BONE_DATABASE_BONE_POSITION: + case BONE_DATABASE_BONE_POSITION_ROTATION: + rot_mat[0] = data->rot_mat[0]; + rot_mat_prev[0][0] = data->rot_mat_prev[0][0]; + break; + case BONE_DATABASE_BONE_HEAD_IK_ROTATION: + rot_mat[0] = data->rot_mat[0]; + rot_mat[1] = data->rot_mat[1]; + rot_mat_prev[0][0] = data->rot_mat_prev[0][0]; + rot_mat_prev[1][0] = data->rot_mat_prev[1][0]; + break; + case BONE_DATABASE_BONE_ARM_IK_ROTATION: + case BONE_DATABASE_BONE_LEGS_IK_ROTATION: + rot_mat[0] = data->rot_mat[0]; + rot_mat[1] = data->rot_mat[1]; + rot_mat[2] = data->rot_mat[2]; + rot_mat_prev[0][0] = data->rot_mat_prev[0][0]; + rot_mat_prev[1][0] = data->rot_mat_prev[1][0]; + rot_mat_prev[2][0] = data->rot_mat_prev[2][0]; + break; + } +} + +bool bone_data::check_flags_not_null() { + return !!flags; +} + +vec3* bone_data::set_key_data(vec3* keyframe_data, + bone_database_skeleton_type skeleton_type, bool get_data, bool reverse_x) { + if (type == BONE_DATABASE_BONE_POSITION_ROTATION) { + if (get_data) { + trans = *keyframe_data; + if (reverse_x) + trans.x = -trans.x; + } + keyframe_data++; + } + else if (type >= BONE_DATABASE_BONE_HEAD_IK_ROTATION + && type <= BONE_DATABASE_BONE_LEGS_IK_ROTATION) { + if (get_data) { + ik_target = *keyframe_data; + if (reverse_x) + ik_target.x = -ik_target.x; + } + keyframe_data++; + } + + if (get_data) { + if (type == BONE_DATABASE_BONE_TYPE_1 || type == BONE_DATABASE_BONE_POSITION) { + trans = *keyframe_data; + if (reverse_x) + trans.x = -trans.x; + } + else if (!flags) { + rotation = *keyframe_data; + if (reverse_x) { + const skeleton_rotation_offset* rot_off = skeleton_rotation_offset_array; + size_t index = motion_bone_index; + if (rot_off[index].x) + rotation.x = rot_off[index].rotation.x - rotation.x; + if (rot_off[index].y) + rotation.y = rot_off[index].rotation.y - rotation.y; + if (rot_off[index].z) + rotation.z = rot_off[index].rotation.z - rotation.z; + } + } + } + keyframe_data++; + return keyframe_data; +} + +void bone_data::store_curr_rot_trans(int32_t skeleton_select) { + if (check_flags_not_null()) + return; + + switch (type) { + case BONE_DATABASE_BONE_TYPE_1: + case BONE_DATABASE_BONE_POSITION: + case BONE_DATABASE_BONE_POSITION_ROTATION: + trans_prev[skeleton_select] = trans; + break; + } + + switch (type) { + case BONE_DATABASE_BONE_ROTATION: + rot_mat_prev[0][skeleton_select] = rot_mat[0]; + break; + case BONE_DATABASE_BONE_TYPE_1: + case BONE_DATABASE_BONE_POSITION: + case BONE_DATABASE_BONE_POSITION_ROTATION: + rot_mat_prev[0][skeleton_select] = rot_mat[0]; + break; + case BONE_DATABASE_BONE_HEAD_IK_ROTATION: + rot_mat_prev[0][skeleton_select] = rot_mat[0]; + rot_mat_prev[1][skeleton_select] = rot_mat[1]; + break; + case BONE_DATABASE_BONE_ARM_IK_ROTATION: + case BONE_DATABASE_BONE_LEGS_IK_ROTATION: + rot_mat_prev[0][skeleton_select] = rot_mat[0]; + rot_mat_prev[1][skeleton_select] = rot_mat[1]; + rot_mat_prev[2][skeleton_select] = rot_mat[2]; + break; + } +} + bone_data_parent::bone_data_parent() : rob_bone_data(), motion_bone_count(), ik_bone_count(), chain_pos(), global_trans(), global_rotation(), bone_key_set_count(), global_key_set_count(), rot_y() { @@ -11613,7 +11620,7 @@ rot_y(), prev_rot_y(), field_BC(), field_BD(), field_C0(), field_C4() { } -MotionBlend::MotionBlend() : enable(), rot_y(), duration(), frame(), offset(), blend() { +MotionBlend::MotionBlend() : field_8(), enable(), duration(), frame(), offset(), blend() { step = 1.0f; } @@ -11622,8 +11629,8 @@ MotionBlend::~MotionBlend() { } void MotionBlend::Reset() { + field_8 = false; enable = false; - rot_y = false; duration = 0.0f; frame = 0.0f; step = 1.0f; @@ -11640,16 +11647,16 @@ void MotionBlend::SetDuration(float_t duration, float_t step, float_t offset) { this->offset = offset; if (duration < 0.0f) { this->duration = 0.0f; - enable = false; + field_8 = false; } else { this->duration = duration; - enable = true; + field_8 = true; } frame = 0.0f; } -MotionBlendCross::MotionBlendCross() : field_20(), field_21() { +MotionBlendCross::MotionBlendCross() : trans_xz(), trans_y() { rot_y_mat = mat4_identity; field_64 = mat4_identity; field_A4 = mat4_identity; @@ -11662,8 +11669,8 @@ MotionBlendCross::~MotionBlendCross() { void MotionBlendCross::Reset() { MotionBlend::Reset(); - field_20 = false; - field_21 = false; + trans_xz = false; + trans_y = false; rot_y_mat = mat4_identity; field_64 = mat4_identity; field_A4 = mat4_identity; @@ -11675,96 +11682,98 @@ void MotionBlendCross::Field_10(float_t a2, float_t a3, int32_t a4) { } void MotionBlendCross::Step(struc_400* a2) { - field_20 = a2->field_0; - field_21 = true; + trans_xz = a2->field_0; + trans_y = true; if (duration <= 0.0f || duration <= frame || fabsf(duration - frame) <= 0.000001f) { + field_8 = false; enable = false; - rot_y = false; } else { - rot_y = true; + enable = true; blend = (frame + offset) / (duration + offset); frame += step; } - if (rot_y) + if (enable) mat4_rotate_y(-a2->prev_rot_y, &rot_y_mat); else rot_y_mat = mat4_identity; } -void MotionBlendCross::Field_20(std::vector* a2, std::vector* a3) { - if (!a2 || !a3) +void MotionBlendCross::Field_20(std::vector* bones_curr, std::vector* bones_prev) { + if (!bones_curr || !bones_prev) return; - bone_data* v4 = a2->data(); - bone_data* v7 = a3->data(); - - mat4_mult(&v4[4].rot_mat[0], &v4[0].rot_mat[0], &field_64); - mat4_mult(&v7[0].rot_mat[0], &rot_y_mat, &field_A4); - mat4_blend_rotation(&v4[0].rot_mat[0], &field_A4, &v4[0].rot_mat[0], blend); - mat4_mult(&v7[4].rot_mat[0], &field_A4, &field_A4); - mat4_blend_rotation(&v4[4].rot_mat[0], &v7[4].rot_mat[0], &v4[4].rot_mat[0], blend); - mat4_mult(&v4[4].rot_mat[0], &v4[0].rot_mat[0], &field_E4); + bone_data& n_hara_cp_curr = (*bones_curr)[MOTION_BONE_N_HARA_CP]; + bone_data& n_hara_curr = (*bones_curr)[MOTION_BONE_N_HARA]; + bone_data& n_hara_cp_prev = (*bones_prev)[MOTION_BONE_N_HARA_CP]; + bone_data& n_hara_prev = (*bones_prev)[MOTION_BONE_N_HARA]; + mat4_mult(&n_hara_curr.rot_mat[0], &n_hara_cp_curr.rot_mat[0], &field_64); + mat4_mult(&n_hara_cp_prev.rot_mat[0], &rot_y_mat, &field_A4); + mat4_blend_rotation(&field_A4, &n_hara_cp_curr.rot_mat[0], &n_hara_cp_curr.rot_mat[0], blend); + mat4_mult(&n_hara_prev.rot_mat[0], &field_A4, &field_A4); + mat4_blend_rotation(&n_hara_prev.rot_mat[0], &n_hara_curr.rot_mat[0], &n_hara_curr.rot_mat[0], blend); + mat4_mult(&n_hara_curr.rot_mat[0], &n_hara_cp_curr.rot_mat[0], &field_E4); mat4_transpose(&field_E4, &field_E4); } -void MotionBlendCross::Blend(bone_data* a2, bone_data* a3) { - if (!a2 || !a3 || a2->disable_mot_anim) +void MotionBlendCross::Blend(bone_data* curr, bone_data* prev) { + if (!curr || !prev || curr->check_flags_not_null()) return; - mat4 v15; - mat4 v16; + mat4 prev_mat; + mat4 mat; + mat4 ik_mat; - switch (a2->type) { + switch (curr->type) { case BONE_DATABASE_BONE_ROTATION: default: - if (a2->motion_bone_index == MOTION_BONE_KL_KOSI_Y) { - mat4_mult(&a3->rot_mat[0], &field_A4, &v16); - mat4_mult(&a2->rot_mat[0], &field_64, &v15); - mat4_blend_rotation(&v15, &v16, &v15, blend); - mat4_mult(&v15, &field_E4, &a2->rot_mat[0]); + if (curr->motion_bone_index == MOTION_BONE_KL_KOSI_Y) { + mat4_mult(&prev->rot_mat[0], &field_A4, &prev_mat); + mat4_mult(&curr->rot_mat[0], &field_64, &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); + mat4_mult(&mat, &field_E4, &curr->rot_mat[0]); } - else if (a2->motion_bone_index > MOTION_BONE_N_HARA) - mat4_blend_rotation(&a2->rot_mat[0], &a3->rot_mat[0], &a2->rot_mat[0], blend); + else if (curr->motion_bone_index < 0 || curr->motion_bone_index > MOTION_BONE_N_HARA) + mat4_blend_rotation(&prev->rot_mat[0], &curr->rot_mat[0], &curr->rot_mat[0], blend); break; case BONE_DATABASE_BONE_TYPE_1: case BONE_DATABASE_BONE_POSITION: - a2->trans = vec3::lerp(a3->trans, a2->trans, blend); + curr->trans = vec3::lerp(prev->trans, curr->trans, blend); break; case BONE_DATABASE_BONE_POSITION_ROTATION: - if (field_21) { - a2->trans.x = lerp_def(a3->trans.x, a2->trans.x, blend); - a2->trans.z = lerp_def(a3->trans.z, a2->trans.z, blend); + if (trans_xz) { + curr->trans.x = lerp_def(prev->trans.x, curr->trans.x, blend); + curr->trans.z = lerp_def(prev->trans.z, curr->trans.z, blend); } - if (field_20) - a2->trans.y = lerp_def(a3->trans.y, a2->trans.y, blend); + if (trans_y) + curr->trans.y = lerp_def(prev->trans.y, curr->trans.y, blend); break; case BONE_DATABASE_BONE_HEAD_IK_ROTATION: - if (a2->motion_bone_index == MOTION_BONE_CL_MUNE) { - mat4_mult(&a3->rot_mat[0], &field_A4, &v15); - mat4_mult(&a3->rot_mat[1], &v15, &v15); - mat4_mult(&a2->rot_mat[0], &field_64, &v16); - mat4_mult(&a2->rot_mat[1], &v16, &v16); - mat4_blend_rotation(&v16, &v15, &v16, blend); - mat4_mult(&v16, &field_E4, &v16); + if (curr->motion_bone_index == MOTION_BONE_CL_MUNE) { + mat4_mult(&prev->rot_mat[0], &field_A4, &prev_mat); + mat4_mult(&prev->rot_mat[1], &prev_mat, &prev_mat); + mat4_mult(&curr->rot_mat[0], &field_64, &mat); + mat4_mult(&curr->rot_mat[1], &mat, &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); + mat4_mult(&mat, &field_E4, &mat); } else { - mat4_mult(&a3->rot_mat[1], &a3->rot_mat[0], &v15); - mat4_mult(&a2->rot_mat[1], &a2->rot_mat[0], &v16); - mat4_blend_rotation(&v16, &v15, &v16, blend); + mat4_mult(&prev->rot_mat[1], &prev->rot_mat[0], &prev_mat); + mat4_mult(&curr->rot_mat[1], &curr->rot_mat[0], &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); } - mat4_transpose(&a2->rot_mat[0], &v15); - mat4_mult(&v16, &v15, &a2->rot_mat[1]); + mat4_transpose(&curr->rot_mat[0], &ik_mat); + mat4_mult(&mat, &ik_mat, &curr->rot_mat[1]); break; case BONE_DATABASE_BONE_ARM_IK_ROTATION: case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - mat4_blend_rotation(&a2->rot_mat[2], &a3->rot_mat[2], &a2->rot_mat[2], blend); - mat4_mult(&a3->rot_mat[1], &a3->rot_mat[0], &v15); - mat4_mult(&a2->rot_mat[1], &a2->rot_mat[0], &v16); - mat4_blend_rotation(&v16, &v15, &v16, blend); - mat4_transpose(&a2->rot_mat[0], &v15); - mat4_mult(&v16, &v15, &a2->rot_mat[1]); + mat4_blend_rotation(&prev->rot_mat[2], &curr->rot_mat[2], &curr->rot_mat[2], blend); + mat4_mult(&prev->rot_mat[1], &prev->rot_mat[0], &prev_mat); + mat4_mult(&curr->rot_mat[1], &curr->rot_mat[0], &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); + mat4_transpose(&curr->rot_mat[0], &ik_mat); + mat4_mult(&mat, &ik_mat, &curr->rot_mat[1]); break; } } @@ -11782,13 +11791,10 @@ MotionBlendCombine::~MotionBlendCombine() { } void MotionBlendCombine::Step(struc_400* a2) { - field_20 = a2->field_0; - field_21 = true; - if (rot_y) { - mat4 mat; - mat4_rotate_y(-a2->prev_rot_y, &mat); - rot_y_mat = mat; - } + trans_xz = a2->field_0; + trans_y = true; + if (enable) + mat4_rotate_y(-a2->prev_rot_y, &rot_y_mat); else rot_y_mat = mat4_identity; } @@ -11797,8 +11803,8 @@ bool MotionBlendCombine::Field_30() { return true; } -MotionBlendFreeze::MotionBlendFreeze() : field_20(), -field_21(), field_24(), field_28(), field_2C(), field_30() { +MotionBlendFreeze::MotionBlendFreeze() : trans_xz(), +trans_y(), field_24(), field_28(), field_2C(), field_30() { rot_y_mat = mat4_identity; field_74 = mat4_identity; field_B4 = mat4_identity; @@ -11811,8 +11817,8 @@ MotionBlendFreeze::~MotionBlendFreeze() { void MotionBlendFreeze::Reset() { MotionBlend::Reset(); - field_20 = false; - field_21 = false; + trans_xz = false; + trans_y = false; field_24 = 2; field_28 = 0.0f; field_2C = 0.0f; @@ -11839,29 +11845,29 @@ void MotionBlendFreeze::Step(struc_400* a2) { float_t v8 = field_2C; float_t v9 = v7 - v8; if (v7 < v8 || field_28 <= 0.0f || field_28 <= v9 || fabsf(field_28 - v9) <= 0.000001f) { + field_8 = false; enable = false; - rot_y = false; } else { - rot_y = true; + enable = true; field_24 = field_30; blend = 1.0f - (v9 + offset) / (field_28 + offset); if (a2->field_4) field_24 = field_30 + 1; - field_20 = a2->field_2; - field_21 = a2->field_3; + trans_xz = a2->field_2; + trans_y = a2->field_3; } } else { - rot_y = true; + enable = true; field_24 = 0; blend = (frame + offset) / (duration + offset); frame += step; - field_20 = a2->field_0; - field_21 = a2->field_1; + trans_xz = a2->field_0; + trans_y = a2->field_1; } - if (rot_y) { + if (enable) { mat4 mat; if (field_24) mat4_rotate_y(a2->rot_y, &mat); @@ -11873,75 +11879,78 @@ void MotionBlendFreeze::Step(struc_400* a2) { rot_y_mat = mat4_identity; } -void MotionBlendFreeze::Field_20(std::vector* a2, std::vector* a3) { - if (!a2) +void MotionBlendFreeze::Field_20(std::vector* bones_curr, std::vector* bones_prev) { + if (!bones_curr) return; - bone_data* v2 = a2->data(); - mat4_mult(&v2[4].rot_mat[0], &v2->rot_mat[0], &field_74); - mat4_mult(&v2->rot_mat_prev[0][field_24], &rot_y_mat, &field_B4); - mat4_blend_rotation(v2->rot_mat, &field_B4, v2->rot_mat, blend); - mat4_mult(&v2[4].rot_mat_prev[0][field_24], &field_B4, &field_B4); - mat4_blend_rotation(&v2[4].rot_mat[0], &v2[4].rot_mat_prev[0][field_24], &v2[4].rot_mat[0], blend); - mat4_mult(&v2[4].rot_mat[0], &v2->rot_mat[0], &field_F4); + bone_data& n_hara_cp = (*bones_curr)[MOTION_BONE_N_HARA_CP]; + bone_data& n_hara = (*bones_curr)[MOTION_BONE_N_HARA]; + mat4_mult(&n_hara.rot_mat[0], &n_hara_cp.rot_mat[0], &field_74); + mat4_mult(&n_hara_cp.rot_mat_prev[0][field_24], &rot_y_mat, &field_B4); + mat4_blend_rotation(&field_B4, &n_hara_cp.rot_mat[0], &n_hara_cp.rot_mat[0], blend); + mat4_mult(&n_hara.rot_mat_prev[0][field_24], &field_B4, &field_B4); + mat4_blend_rotation(&n_hara.rot_mat_prev[0][field_24], &n_hara.rot_mat[0], &n_hara.rot_mat[0], blend); + mat4_mult(&n_hara.rot_mat[0], &n_hara_cp.rot_mat[0], &field_F4); mat4_transpose(&field_F4, &field_F4); } -void MotionBlendFreeze::Blend(bone_data* a2, bone_data* a3) { - if (!a2 || a2->disable_mot_anim) +void MotionBlendFreeze::Blend(bone_data* curr, bone_data* prev) { + if (!curr || curr->check_flags_not_null()) return; - mat4 v15; - mat4 v16; - switch (a2->type) { + mat4 prev_mat; + mat4 mat; + mat4 ik_mat; + + switch (curr->type) { case BONE_DATABASE_BONE_ROTATION: default: - if (a2->motion_bone_index == MOTION_BONE_KL_KOSI_Y) { - mat4_mult(&a2->rot_mat_prev[0][field_24], &field_B4, &v16); - mat4_mult(&a2->rot_mat[0], &field_74, &v15); - mat4_blend_rotation(&v15, &v16, &v15, blend); - mat4_mult(&v15, &field_F4, &a2->rot_mat[0]); + if (curr->motion_bone_index == MOTION_BONE_KL_KOSI_Y) { + mat4_mult(&curr->rot_mat_prev[0][field_24], &field_B4, &prev_mat); + mat4_mult(&curr->rot_mat[0], &field_74, &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); + mat4_mult(&mat, &field_F4, &curr->rot_mat[0]); } - else if (a2->motion_bone_index > MOTION_BONE_N_HARA) - mat4_blend_rotation(a2->rot_mat, &a2->rot_mat_prev[0][field_24], a2->rot_mat, blend); + else if (curr->motion_bone_index < 0 || curr->motion_bone_index > MOTION_BONE_N_HARA) + mat4_blend_rotation(&curr->rot_mat_prev[0][field_24], &curr->rot_mat[0], &curr->rot_mat[0], blend); break; case BONE_DATABASE_BONE_TYPE_1: case BONE_DATABASE_BONE_POSITION: - a2->trans = vec3::lerp(a2->trans_prev[field_24], a2->trans, blend); + curr->trans = vec3::lerp(curr->trans_prev[field_24], curr->trans, blend); break; case BONE_DATABASE_BONE_POSITION_ROTATION: - if (field_21) { - a2->trans.x = lerp_def(a2->trans_prev[field_24].x, a2->trans.x, blend); - a2->trans.z = lerp_def(a2->trans_prev[field_24].z, a2->trans.z, blend); + if (trans_xz) { + curr->trans.x = lerp_def(curr->trans_prev[field_24].x, curr->trans.x, blend); + curr->trans.z = lerp_def(curr->trans_prev[field_24].z, curr->trans.z, blend); } - if (field_20) - a2->trans.y = lerp_def(a2->trans_prev[field_24].y, a2->trans.y, blend); + if (trans_y) + curr->trans.y = lerp_def(curr->trans_prev[field_24].y, curr->trans.y, blend); break; case BONE_DATABASE_BONE_HEAD_IK_ROTATION: - if (a2->motion_bone_index == MOTION_BONE_CL_MUNE) { - mat4_mult(&a2->rot_mat_prev[0][field_24], &field_B4, &v15); - mat4_mult(&a2->rot_mat_prev[1][field_24], &v15, &v15); - mat4_mult(&a2->rot_mat[0], &field_74, &v16); - mat4_mult(&a2->rot_mat[1], &v16, &v16); - mat4_blend_rotation(&v16, &v15, &v16, blend); - mat4_mult(&v16, &field_F4, &v16); + if (curr->motion_bone_index == MOTION_BONE_CL_MUNE) { + mat4_mult(&curr->rot_mat_prev[0][field_24], &field_B4, &prev_mat); + mat4_mult(&curr->rot_mat_prev[1][field_24], &prev_mat, &prev_mat); + mat4_mult(&curr->rot_mat[0], &field_74, &mat); + mat4_mult(&curr->rot_mat[1], &mat, &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); + mat4_mult(&mat, &field_F4, &mat); } else { - mat4_mult(&a2->rot_mat_prev[1][field_24], &a2->rot_mat_prev[0][field_24], &v15); - mat4_mult(&a2->rot_mat[1], &a2->rot_mat[0], &v16); - mat4_blend_rotation(&v16, &v15, &v16, blend); + mat4_mult(&curr->rot_mat_prev[1][field_24], &curr->rot_mat_prev[0][field_24], &prev_mat); + mat4_mult( &curr->rot_mat[1], &curr->rot_mat[0], &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); } - mat4_transpose(&a2->rot_mat[0], &v15); - mat4_mult(&v16, &v15, &a2->rot_mat[1]); + mat4_transpose(&curr->rot_mat[0], &ik_mat); + mat4_mult(&mat, &ik_mat, &curr->rot_mat[1]); break; case BONE_DATABASE_BONE_ARM_IK_ROTATION: case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - mat4_blend_rotation(&a2->rot_mat[2], &a2->rot_mat_prev[2][field_24], &a2->rot_mat[2], blend); - mat4_mult(&a2->rot_mat_prev[1][field_24], &a2->rot_mat_prev[0][field_24], &v15); - mat4_mult(&a2->rot_mat[1], &a2->rot_mat[0], &v16); - mat4_blend_rotation(&v16, &v15, &v16, blend); - mat4_transpose(&a2->rot_mat[0], &v15); - mat4_mult(&v16, &v15, &a2->rot_mat[1]); + mat4_blend_rotation(&curr->rot_mat_prev[2][field_24], &curr->rot_mat[2], &curr->rot_mat[2], blend); + mat4_mult(&curr->rot_mat_prev[1][field_24], &curr->rot_mat_prev[0][field_24], &prev_mat); + mat4_mult(&curr->rot_mat[1], &curr->rot_mat[0], &mat); + mat4_blend_rotation(&prev_mat, &mat, &mat, blend); + mat4_transpose(&curr->rot_mat[0], &ik_mat); + mat4_mult(&mat, &ik_mat, &curr->rot_mat[1]); break; } } @@ -11964,50 +11973,50 @@ void PartialMotionBlendFreeze::Field_10(float_t a2, float_t a3, int32_t a4) { void PartialMotionBlendFreeze::Step(struc_400* a1) { if (duration <= 0.0f || duration <= frame || fabsf(duration - frame) <= 0.000001f) { + field_8 = false; enable = false; - rot_y = false; } else { - rot_y = true; + enable = true; frame += step; blend = (offset + frame) / (offset + duration); } } -void PartialMotionBlendFreeze::Field_20(std::vector* a1, std::vector* a2) { +void PartialMotionBlendFreeze::Field_20(std::vector* bones_curr, std::vector* bones_prev) { } -void PartialMotionBlendFreeze::Blend(bone_data* a2, bone_data* a3) { - if (!a2 || a2->disable_mot_anim) +void PartialMotionBlendFreeze::Blend(bone_data* curr, bone_data* prev) { + if (!curr || curr->check_flags_not_null()) return; - float_t inv_blend = 1.0f - blend; - switch (a2->type) { + mat4 prev_mat; + mat4 mat; + mat4 ik_mat; + + switch (curr->type) { case BONE_DATABASE_BONE_ROTATION: default: - mat4_lerp_rotation(&a2->rot_mat_prev[0][0], &a2->rot_mat[0], &a2->rot_mat[0], blend); + mat4_lerp_rotation(&curr->rot_mat_prev[0][0], &curr->rot_mat[0], &curr->rot_mat[0], blend); break; case BONE_DATABASE_BONE_POSITION: case BONE_DATABASE_BONE_TYPE_1: - a2->trans = vec3::lerp(a2->trans_prev[0], a2->trans, blend); + curr->trans = vec3::lerp(curr->trans_prev[0], curr->trans, blend); break; case BONE_DATABASE_BONE_POSITION_ROTATION: - mat4_lerp_rotation(&a2->rot_mat_prev[0][0], &a2->rot_mat[0], &a2->rot_mat[0], blend); - a2->trans = vec3::lerp(a2->trans_prev[0], a2->trans, blend); + mat4_lerp_rotation(&curr->rot_mat_prev[0][0], &curr->rot_mat[0], &curr->rot_mat[0], blend); + curr->trans = vec3::lerp(curr->trans_prev[0], curr->trans, blend); break; case BONE_DATABASE_BONE_ARM_IK_ROTATION: case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - mat4_lerp_rotation(&a2->rot_mat_prev[2][0], &a2->rot_mat[2], &a2->rot_mat[2], blend); + mat4_lerp_rotation(&curr->rot_mat_prev[2][0], &curr->rot_mat[2], &curr->rot_mat[2], blend); case BONE_DATABASE_BONE_HEAD_IK_ROTATION: { - mat4 v15; - mat4 v16; - mat4 v17; - mat4_mult(&a2->rot_mat_prev[1][0], &a2->rot_mat_prev[0][0], &v16); - mat4_mult(&a2->rot_mat[1], &a2->rot_mat[0], &v15); - mat4_lerp_rotation(&v16, &v15, &v16, blend); - mat4_transpose(&a2->rot_mat[0], &v17); - mat4_mult(&v17, &v16, &a2->rot_mat[1]); + mat4_mult(&curr->rot_mat_prev[1][0], &curr->rot_mat_prev[0][0], &prev_mat); + mat4_mult(&curr->rot_mat[1], &curr->rot_mat[0], &mat); + mat4_lerp_rotation(&prev_mat, &mat, &mat, blend); + mat4_transpose(&curr->rot_mat[0], &ik_mat); + mat4_mult(&mat, &ik_mat, &curr->rot_mat[1]); } break; } } @@ -12039,6 +12048,12 @@ motion_blend_mot::~motion_blend_mot() { } +bool motion_blend_mot::get_blend_enable() { + if (blend && !blend->Field_30()) + return blend->enable; + return false; +} + MotionBlendType motion_blend_mot::get_type() { if (blend == &cross) return MOTION_BLEND_CROSS; @@ -13556,13 +13571,13 @@ void rob_chara_item_equip::set_opd_blend_data(std::list* a2) v11.motion_id = i->mot_key_data.motion_id; v11.frame = i->mot_play_data.frame_data.frame; v11.frame_count = (float_t)i->mot_key_data.mot.frame_count - 1.0f; - v11.field_C = false; + v11.use_blend = false; v11.type = MOTION_BLEND_NONE; v11.blend = 0.0f; - if (sub_140413810(i)) { + if (i->get_blend_enable()) { v11.type = i->get_type(); - v11.field_C = true; + v11.use_blend = true; v11.blend = i->blend->blend; } opd_blend_data.push_back(v11); @@ -13570,8 +13585,8 @@ void rob_chara_item_equip::set_opd_blend_data(std::list* a2) if (opd_blend_data.size()) { ::opd_blend_data* v9 = &opd_blend_data.back(); - if (v9->field_C && v9->type != MOTION_BLEND_FREEZE) - v9->field_C = false; + if (v9->use_blend && v9->type != MOTION_BLEND_FREEZE) + v9->use_blend = false; } if (use_opd) diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 98591b83..17806a31 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -950,6 +950,13 @@ struct bone_data { float_t eyes_xrot_adjust_pos; bone_data(); + + void copy_rot_trans(bone_data* data); + bool check_flags_not_null(); + vec3* set_key_data(vec3* keyframe_data, + bone_database_skeleton_type skeleton_type, bool get_data, bool reverse_x); + void store_curr_rot_trans(int32_t skeleton_select); + }; struct bone_data_parent { @@ -1032,8 +1039,8 @@ struct struc_400 { class MotionBlend { public: + bool field_8; bool enable; - bool rot_y; float_t duration; float_t frame; float_t step; @@ -1044,10 +1051,10 @@ public: virtual ~MotionBlend(); virtual void Reset(); - virtual void Field_10(float_t a2, float_t a3, int32_t a4) = 0; + virtual void Field_10(float_t, float_t, int32_t) = 0; virtual void Step(struc_400*) = 0; - virtual void Field_20(std::vector*, std::vector*) = 0; - virtual void Blend(bone_data*, bone_data*) = 0; + virtual void Field_20(std::vector* bones_curr, std::vector* bones_prev) = 0; + virtual void Blend(bone_data* curr, bone_data* prev) = 0; virtual bool Field_30(); void SetDuration(float_t duration, float_t step, float_t offset); @@ -1055,8 +1062,8 @@ public: class MotionBlendCross : public MotionBlend { public: - bool field_20; - bool field_21; + bool trans_xz; + bool trans_y; mat4 rot_y_mat; mat4 field_64; mat4 field_A4; @@ -1066,10 +1073,10 @@ public: virtual ~MotionBlendCross() override; virtual void Reset() override; - virtual void Field_10(float_t a2, float_t a3, int32_t a4) override; + virtual void Field_10(float_t, float_t, int32_t) override; virtual void Step(struc_400*) override; - virtual void Field_20(std::vector*, std::vector*) override; - virtual void Blend(bone_data*, bone_data*) override; + virtual void Field_20(std::vector* bones_curr, std::vector* bones_prev) override; + virtual void Blend(bone_data* curr, bone_data* prev) override; virtual bool Field_30() override; }; @@ -1084,8 +1091,8 @@ public: class MotionBlendFreeze : public MotionBlend { public: - bool field_20; - bool field_21; + bool trans_xz; + bool trans_y; int32_t field_24; float_t field_28; float_t field_2C; @@ -1099,10 +1106,10 @@ public: virtual ~MotionBlendFreeze() override; virtual void Reset() override; - virtual void Field_10(float_t a2, float_t a3, int32_t a4) override; + virtual void Field_10(float_t, float_t, int32_t) override; virtual void Step(struc_400*) override; - virtual void Field_20(std::vector*, std::vector*) override; - virtual void Blend(bone_data*, bone_data*) override; + virtual void Field_20(std::vector* bones_curr, std::vector* bones_prev) override; + virtual void Blend(bone_data* curr, bone_data* prev) override; }; class PartialMotionBlendFreeze : public MotionBlendFreeze { @@ -1111,10 +1118,10 @@ public: virtual ~PartialMotionBlendFreeze() override; virtual void Reset() override; - virtual void Field_10(float_t a2, float_t a3, int32_t a4) override; + virtual void Field_10(float_t, float_t, int32_t) override; virtual void Step(struc_400*) override; - virtual void Field_20(std::vector*, std::vector*) override; - virtual void Blend(bone_data*, bone_data*) override; + virtual void Field_20(std::vector* bones_curr, std::vector* bones_prev) override; + virtual void Blend(bone_data* curr, bone_data* prev) override; }; struct struc_313 { @@ -1151,6 +1158,7 @@ struct motion_blend_mot { motion_blend_mot(); ~motion_blend_mot(); + bool get_blend_enable(); MotionBlendType get_type(); void reset(); void set_step(float_t step); @@ -1550,24 +1558,38 @@ struct RobOsageNodeData { skin_param_osage_node* skp_osg_node, size_t index); }; +struct opd_blend_data { + uint32_t motion_id; + float_t frame; + float_t frame_count; + bool use_blend; + MotionBlendType type; + float_t blend; +}; + struct opd_vec3_data { const float_t* x; const float_t* y; const float_t* z; }; -struct struc_477 { +struct opd_node_data { float_t length; vec3 rotation; - struc_477(); + opd_node_data(); + opd_node_data(float_t length, vec3 rotation); + + static void lerp(opd_node_data& dst, const opd_node_data& src0, const opd_node_data& src1, float_t blend); }; -struct struc_476 { - struc_477 field_0; - struc_477 field_10; +struct opd_node_data_pair { + opd_node_data curr; + opd_node_data prev; - struc_476(); + opd_node_data_pair(); + + void set_data(opd_blend_data* blend_data, opd_node_data&& node_data); }; struct RobOsageNode { @@ -1591,7 +1613,7 @@ struct RobOsageNode { RobOsageNodeData* data_ptr; RobOsageNodeData data; std::vector opd_data; - struc_476 field_1B0; + opd_node_data_pair opd_node_data; RobOsageNode(); ~RobOsageNode(); @@ -1779,7 +1801,7 @@ struct CLOTHNode { RobOsageNodeResetData reset_data; int32_t field_B4; std::vector opd_data; - struc_476 field_D0; + opd_node_data_pair opd_node_data; CLOTHNode(); ~CLOTHNode(); @@ -1842,15 +1864,6 @@ struct RobClothSubMeshArray { RobClothSubMeshArray(); }; -struct opd_blend_data { - uint32_t motion_id; - float_t frame; - float_t frame_count; - bool field_C; - MotionBlendType type; - float_t blend; -}; - struct RobCloth : public CLOTH { std::vector root; rob_chara_item_equip_object* itm_eq_obj;