From de88c1efe77f5888602df65ab7d066f086336437 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sat, 1 Apr 2023 16:11:58 +0300 Subject: [PATCH] Rob Sleeve, Interpolation, Shading fixes --- src/CRE/Glitter/curve.cpp | 17 +- src/CRE/auth_3d.cpp | 36 +- src/CRE/auth_3d.hpp | 4 +- src/CRE/draw_object.cpp | 22 +- src/CRE/hand_item.cpp | 35 +- src/CRE/item_table.cpp | 12 +- src/CRE/object.hpp | 6 - src/CRE/rob/rob.cpp | 274 +++++++++++- src/CRE/rob/rob.hpp | 15 +- src/CRE/rob/skin_param.cpp | 48 ++- src/CRE/sound.cpp | 10 +- src/CRE/sound.hpp | 2 +- src/KKdLib/a3da.cpp | 14 +- src/KKdLib/a3da.hpp | 4 +- src/KKdLib/interpolation.cpp | 113 ++--- src/KKdLib/interpolation.hpp | 12 +- src/KKdLib/mot.cpp | 41 +- src/KKdLib/vec.cpp | 4 + src/KKdLib/vec.hpp | 19 + src/ReDIVA/classes/data_view/auth_3d.cpp | 4 +- src/ReDIVA/data_initialize.cpp | 9 +- src/ReDIVA/pv_game.cpp | 1 - src/ReDIVA/pv_game.hpp | 1 - src/ReDIVA/render.cpp | 2 - src/ReDIVA/x_pv_game.cpp | 508 +++++++++++++++++++++-- src/ReDIVA/x_pv_game.hpp | 1 - 26 files changed, 931 insertions(+), 283 deletions(-) diff --git a/src/CRE/Glitter/curve.cpp b/src/CRE/Glitter/curve.cpp index 5d57b720..a09f669b 100644 --- a/src/CRE/Glitter/curve.cpp +++ b/src/CRE/Glitter/curve.cpp @@ -333,7 +333,6 @@ namespace Glitter { bool has_error_hermite = false; bool has_prev_error = false; bool has_prev_error_lerp = false; - bool has_prev_error_hermite = false; size_t i; for (i = reverse_min_count - 1; i < left_count; i++) { @@ -358,7 +357,7 @@ namespace Glitter { t1 = (float_t)(tt1 / (double_t)(i - 2)); t2 = (float_t)(tt2 / (double_t)(i - 2)); - constant = false; + constant = true; has_error = false; has_error_lerp = false; has_error_hermite = false; @@ -377,8 +376,6 @@ namespace Glitter { } } } - else - constant = true; } if (fabsf(t1) > 0.5f || fabsf(t2) > 0.5f) @@ -391,7 +388,6 @@ namespace Glitter { has_prev_succeded = true; has_prev_error = has_error; has_prev_error_lerp = has_error_lerp; - has_prev_error_hermite = has_error_hermite; if (i < left_count) continue; } @@ -405,13 +401,12 @@ namespace Glitter { t2 = t2_prev; has_error = has_prev_error; has_error_lerp = has_prev_error_lerp; - has_error_hermite = has_prev_error_hermite; + has_error_hermite = false; } - else - c = (int32_t)i; - - if (has_error_hermite) + else if (has_error_hermite) c = 1; + else + c = (int32_t)i; t2_old = glitter_curve_add_key(has_error, has_error_lerp, has_error_hermite, a, b, frame, step, c, t1, t2, t2_old, &keys_rev); @@ -421,7 +416,7 @@ namespace Glitter { } if (has_prev_succeded) { - t2_old = glitter_curve_add_key(has_prev_error, has_prev_error_lerp, has_prev_error_hermite, + t2_old = glitter_curve_add_key(has_prev_error, has_prev_error_lerp, false, a, b, frame, step, i, t1_prev, t2_prev, t2_old, &keys_rev); c = (int32_t)i; } diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index b1b6b5b9..ec126628 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -1686,15 +1686,15 @@ void auth_3d_material_list::interpolate(float_t frame) { blend_color.interpolate(frame); if (flags & AUTH_3D_MATERIAL_LIST_GLOW_INTENSITY) glow_intensity_value = glow_intensity.interpolate(frame); - if (flags & AUTH_3D_MATERIAL_LIST_INCANDESCENCE) - incandescence.interpolate(frame); + if (flags & AUTH_3D_MATERIAL_LIST_EMISSION) + emission.interpolate(frame); } void auth_3d_material_list::reset() { flags = (auth_3d_material_list_flags)0; blend_color.reset(); glow_intensity.reset(); - incandescence.reset(); + emission.reset(); name.clear(); name.shrink_to_fit(); glow_intensity_value = 0.0f; @@ -3315,22 +3315,22 @@ static void auth_3d_set_material_list(auth_3d* auth, render_context* rctx) { mat_list[mat_list_count].has_blend_color = {}; } - if (i.incandescence.flags) { + if (i.emission.flags) { vec4& emission = mat_list[mat_list_count].emission; vec4u8& has_emission = mat_list[mat_list_count].has_emission; - emission = i.incandescence.value; - has_emission.x = !!(i.incandescence.flags & AUTH_3D_RGBA_R); - has_emission.y = !!(i.incandescence.flags & AUTH_3D_RGBA_B); - has_emission.z = !!(i.incandescence.flags & AUTH_3D_RGBA_G); - has_emission.w = !!(i.incandescence.flags & AUTH_3D_RGBA_A); + emission = i.emission.value; + has_emission.x = !!(i.emission.flags & AUTH_3D_RGBA_R); + has_emission.y = !!(i.emission.flags & AUTH_3D_RGBA_B); + has_emission.z = !!(i.emission.flags & AUTH_3D_RGBA_G); + has_emission.w = !!(i.emission.flags & AUTH_3D_RGBA_A); } else { mat_list[mat_list_count].emission = {}; mat_list[mat_list_count].has_emission = {}; } - if (!i.blend_color.flags && !i.incandescence.flags) + if (!i.blend_color.flags && !i.emission.flags) continue; mat_list[mat_list_count].hash = i.hash; @@ -4661,14 +4661,14 @@ static void auth_3d_material_list_load(auth_3d* auth, auth_3d_material_list* ml, enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_GLOW_INTENSITY); } - if (mlf->flags & A3DA_MATERIAL_LIST_INCANDESCENCE) { - auth_3d_rgba_load(auth, &ml->incandescence, &mlf->incandescence); - enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_INCANDESCENCE); + if (mlf->flags & A3DA_MATERIAL_LIST_EMISSION) { + auth_3d_rgba_load(auth, &ml->emission, &mlf->emission); + enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_EMISSION); - /*auth_3d_key& r = ml->incandescence.r; - auth_3d_key& g = ml->incandescence.g; - auth_3d_key& b = ml->incandescence.b; - auth_3d_key& a = ml->incandescence.a; + /*auth_3d_key& r = ml->emission.r; + auth_3d_key& g = ml->emission.g; + auth_3d_key& b = ml->emission.b; + auth_3d_key& a = ml->emission.a; switch (r.type) { case AUTH_3D_KEY_NONE: @@ -5399,7 +5399,7 @@ static void auth_3d_material_list_load(auth_3d* auth, auth_3d_material_list* ml, } } - if (ml->flags & AUTH_3D_MATERIAL_LIST_INCANDESCENCE) { + if (ml->flags & AUTH_3D_MATERIAL_LIST_EMISSION) { if ((ident[12] || ident[13] || ident[14] || ident[15] || ident[16] || ident[17]) && (!ident[12] || !ident[13] || !ident[14] || !ident[15] || !ident[16] || !ident[17])) OutputDebugStringA("E\n"); diff --git a/src/CRE/auth_3d.hpp b/src/CRE/auth_3d.hpp index ec855898..9bd7dad2 100644 --- a/src/CRE/auth_3d.hpp +++ b/src/CRE/auth_3d.hpp @@ -95,7 +95,7 @@ enum auth_3d_light_flags { enum auth_3d_material_list_flags { AUTH_3D_MATERIAL_LIST_BLEND_COLOR = 0x01, AUTH_3D_MATERIAL_LIST_GLOW_INTENSITY = 0x02, - AUTH_3D_MATERIAL_LIST_INCANDESCENCE = 0x04, + AUTH_3D_MATERIAL_LIST_EMISSION = 0x04, }; enum auth_3d_model_transform_flags { @@ -585,7 +585,7 @@ struct auth_3d_material_list { auth_3d_material_list_flags flags; auth_3d_rgba blend_color; auth_3d_key glow_intensity; - auth_3d_rgba incandescence; + auth_3d_rgba emission; std::string name; uint32_t hash; diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index 19ed230a..adcc4c07 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -336,7 +336,7 @@ namespace mdl { } break; } - tex_index = 4; + tex_index = 3; } if (texture_id != -1) { @@ -355,6 +355,26 @@ namespace mdl { tex_id = 0; gl_state_active_bind_texture_2d(tex_index, tex_id); + + int32_t wrap_s; + if (texdata->attrib.m.mirror_u) + wrap_s = 2; + else if (texdata->attrib.m.repeat_u) + wrap_s = 1; + else + wrap_s = 0; + + int32_t wrap_t; + if (texdata->attrib.m.mirror_v) + wrap_t = 2; + else if (texdata->attrib.m.repeat_v) + wrap_t = 1; + else + wrap_t = 0; + + texture* tex = texture_storage_get_texture(::texture_id(0, texture_id)); + gl_state_bind_sampler(tex_index, rctx->render_manager.samplers[(wrap_t * 3 + + wrap_s) * 2 + (tex->max_mipmap_level > 0 ? 1 : 0)]); } } diff --git a/src/CRE/hand_item.cpp b/src/CRE/hand_item.cpp index 75da6584..4d34cb66 100644 --- a/src/CRE/hand_item.cpp +++ b/src/CRE/hand_item.cpp @@ -14,7 +14,7 @@ struct hand_item_handler { std::list file_handlers; - bool loaded; + bool ready; std::map, hand_item> hand_items; hand_item_handler(); @@ -33,7 +33,7 @@ static void hand_item_load(data_struct* data, static int32_t mtp_hand_array_get_mottbl_index(const char* str); -hand_item_handler hand_item_handler_data; +hand_item_handler* hand_item_handler_data; hand_item::hand_item() : file_size(), hand_mottbl_index(), hand_scale(), uid() { @@ -44,46 +44,51 @@ hand_item::~hand_item() { } void hand_item_handler_data_init() { - hand_item_handler_data = {}; + if (!hand_item_handler_data) + hand_item_handler_data = new hand_item_handler; } const hand_item* hand_item_handler_data_get_hand_item(int32_t uid, chara_index chara_index) { if (uid >= 0) - return hand_item_handler_data.get_hand_item(uid, chara_index); + return hand_item_handler_data->get_hand_item(uid, chara_index); return 0; } const std::map, hand_item>& hand_item_handler_data_get_hand_items() { - return hand_item_handler_data.hand_items; + return hand_item_handler_data->hand_items; } int32_t hand_item_handler_data_get_hand_item_uid(const char* str) { if (str) - return hand_item_handler_data.get_hand_item_uid(str); + return hand_item_handler_data->get_hand_item_uid(str); return -1; } bool hand_item_handler_data_load() { - return hand_item_handler_data.load(); + return hand_item_handler_data->load(); } void hand_item_handler_data_read() { - hand_item_handler_data.read(); + hand_item_handler_data->read(); } void hand_item_handler_data_free() { - hand_item_handler_data.clear(); + if (hand_item_handler_data) { + delete hand_item_handler_data; + hand_item_handler_data = 0; + } } -hand_item_handler::hand_item_handler() : loaded() { +hand_item_handler::hand_item_handler() : ready() { } hand_item_handler::~hand_item_handler() { - + clear(); } + void hand_item_handler::clear() { - loaded = false; + ready = false; hand_items.clear(); for (p_file_handler*& i : file_handlers) @@ -114,7 +119,7 @@ int32_t hand_item_handler::get_hand_item_uid(const char* str) { } bool hand_item_handler::load() { - if (loaded) + if (ready) return false; for (p_file_handler*& i : file_handlers) @@ -132,7 +137,7 @@ bool hand_item_handler::load() { } file_handlers.clear(); - loaded = true; + ready = true; return false; } @@ -144,7 +149,7 @@ void hand_item_handler::parse(p_file_handler* pfhndl) { } void hand_item_handler::read() { - loaded = false; + ready = false; data_struct* aft_data = &data_list[DATA_AFT]; for (const std::string& i : mdata_manager_get()->GetPrefixes()) { diff --git a/src/CRE/item_table.cpp b/src/CRE/item_table.cpp index 607a2041..3d44a83a 100644 --- a/src/CRE/item_table.cpp +++ b/src/CRE/item_table.cpp @@ -14,7 +14,7 @@ struct item_table_handler { chara_index chara_index; std::list file_handlers; - bool loaded; + bool ready; const char* file; item_table table; @@ -147,7 +147,7 @@ void item_table_handler_array_free() { delete[] item_table_handler_array; } -item_table_handler::item_table_handler() : file(), loaded() { +item_table_handler::item_table_handler() : file(), ready() { chara_index = CHARA_NONE; } @@ -162,7 +162,7 @@ void item_table_handler::clear() { i = 0; } file_handlers.clear(); - loaded = false; + ready = false; } const item_table_item* item_table_handler::get_item(int32_t item_no) { @@ -170,7 +170,7 @@ const item_table_item* item_table_handler::get_item(int32_t item_no) { } bool item_table_handler::load() { - if (chara_index < CHARA_MIKU || chara_index >= CHARA_MAX || loaded || !file) + if (chara_index < CHARA_MIKU || chara_index >= CHARA_MAX || ready || !file) return false; for (p_file_handler*& i : file_handlers) @@ -188,7 +188,7 @@ bool item_table_handler::load() { } file_handlers.clear(); - loaded = true; + ready = true; return false; } @@ -210,7 +210,7 @@ void item_table_handler::read() { } file_handlers.clear(); - loaded = false; + ready = false; data_struct* aft_data = &data_list[DATA_AFT]; for (const std::string& i : mdata_manager_get()->GetPrefixes()) { diff --git a/src/CRE/object.hpp b/src/CRE/object.hpp index bce8af63..f37d898a 100644 --- a/src/CRE/object.hpp +++ b/src/CRE/object.hpp @@ -17,12 +17,6 @@ #include "static_var.hpp" #include "texture.hpp" -struct material_change { - vec4 blend_color; - float_t glow_intensity; - vec4 incandescence; -}; - struct obj_mesh_index_buffer { GLuint buffer; GLsizeiptr size; diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 06e7b434..4d853f6b 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -14,6 +14,7 @@ #include "../../KKdLib/str_utils.hpp" #include "../../KKdLib/waitable_timer.hpp" #include "../data.hpp" +#include "../mdata_manager.hpp" #include "../pv_db.hpp" #include "../random.hpp" #include "../pv_expression.hpp" @@ -21,6 +22,13 @@ #include "motion.hpp" #include "skin_param.hpp" +enum rob_sleeve_type : uint8_t { + ROB_SLEEVE_L = 0x01, + ROB_SLEEVE_R = 0x02, + + ROB_SLEEVE_LR = 0x03, +}; + struct MhdFile { mothead* data; uint32_t set; @@ -369,6 +377,32 @@ struct rob_chara_age_age { void set_step_full(); }; +struct rob_sleeve { + rob_sleeve_type type; + rob_sleeve_data* l; + rob_sleeve_data* r; + + rob_sleeve(); + ~rob_sleeve(); +}; + +struct rob_sleeve_handler { + bool ready; + std::list file_handlers; + std::map, rob_sleeve> sleeves; + + rob_sleeve_handler(); + ~rob_sleeve_handler(); + + void clear(); + void get_sleeve_data(::chara_index chara_index, + int32_t cos, rob_sleeve_data& l, rob_sleeve_data& r); + bool load(); + void parse(p_file_handler* pfhndl); + void parse_sleeve_data(key_val& kv, rob_sleeve_data*& data); + void read(); +}; + struct osage_set_motion { int32_t motion_id; std::vector> frames; @@ -1053,6 +1087,7 @@ OpdMaker* opd_maker_array; PvOsageManager* pv_osage_manager_array; rob_cmn_mottbl_header* rob_cmn_mottbl_data; rob_chara_age_age* rob_chara_age_age_array; +rob_sleeve_handler* rob_sleeve_handler_data; RobThreadHandler* rob_thread_handler; TaskRobLoad* task_rob_load; TaskRobManager* task_rob_manager; @@ -2221,6 +2256,9 @@ void rob_init() { rob_mot_tbl_file_handler.reset(); } + if (!rob_sleeve_handler_data) + rob_sleeve_handler_data = new rob_sleeve_handler; + if (!rob_thread_handler) rob_thread_handler = new RobThreadHandler; @@ -2247,6 +2285,11 @@ void rob_free() { rob_thread_handler = 0; } + if (rob_sleeve_handler_data) { + delete rob_sleeve_handler_data; + rob_sleeve_handler_data = 0; + } + free_def(rob_cmn_mottbl_data); if (rob_chara_pv_data_array) { @@ -2457,6 +2500,33 @@ float_t rob_chara::get_max_face_depth() { return item_cos_data.get_max_face_depth(); } +int32_t rob_chara::get_rob_cmn_mottbl_motion_id(int32_t id) { + if (id >= 0xD6 && id <= 0xDF) + return pv_data.motion_face_ids[id - 0xD6]; + else if (id == 0xE0) + return data.motion.motion_id; + else if (id >= 0xE2 && id <= 0xEB) + return pv_data.motion_face_ids[id - 0xE2]; + + int32_t v2 = data.field_8.field_1A4; + if (rob_cmn_mottbl_data + && chara_index >= CHARA_MIKU + && chara_index >= 0 && chara_index < rob_cmn_mottbl_data->chara_count + && id >= 0 && id < rob_cmn_mottbl_data->mottbl_indices_count) { + rob_cmn_mottbl_sub_header* v4 = (rob_cmn_mottbl_sub_header*)((uint8_t*)rob_cmn_mottbl_data + + rob_cmn_mottbl_data->subheaders_offset); + if (v2 >= 0 && v2 < v4[chara_index].field_4) + return ((int32_t*)((uint8_t*)rob_cmn_mottbl_data + + *(int32_t*)((uint8_t*)rob_cmn_mottbl_data + + v2 * sizeof(int32_t) + v4[chara_index].data_offset)))[id]; + } + return -1; +} + +bool rob_chara::is_visible() { + return !!(data.field_0 & 0x01); +} + static int16_t sub_14054FE90(rob_chara* rob_chr, bool a3) { int16_t v3 = rob_chr->data.miku_rot.rot_y_int16; if (!a3 || !(rob_chr->data.field_0 & 0x10)) { @@ -3077,6 +3147,10 @@ void rob_chara::reset_data(rob_chara_pv_data* pv_data, rob_chr_data->adjust_data.height_adjust = this->pv_data.height_adjust; rob_chr_data->adjust_data.pos_adjust_y = chara_pos_adjust_y_table_get_value(this->pv_data.chara_size_index); rob_chara_bone_data_eyes_xrot_adjust(this->bone_data, chara_some_data_array, &pv_data->eyes_adjust); + this->bone_data->sleeve_adjust.sleeve_l = pv_data->sleeve_l; + this->bone_data->sleeve_adjust.sleeve_r = pv_data->sleeve_r; + this->bone_data->sleeve_adjust.enable1 = true; + this->bone_data->sleeve_adjust.enable2 = false; rob_chara_bone_data_get_ik_scale(this->bone_data, bone_data); rob_chara_load_default_motion(this, bone_data, mot_db); rob_chr_data->field_8.field_4.field_0 = 1; @@ -11352,31 +11426,17 @@ bool rob_chara_pv_data_array_check_chara_id(int32_t chara_id) { return rob_chara_pv_data_array[chara_id].type != ROB_CHARA_TYPE_NONE; } -int32_t rob_chara::get_rob_cmn_mottbl_motion_id(int32_t id) { - if (id >= 0xD6 && id <= 0xDF) - return pv_data.motion_face_ids[id - 0xD6]; - else if (id == 0xE0) - return data.motion.motion_id; - else if (id >= 0xE2 && id <= 0xEB) - return pv_data.motion_face_ids[id - 0xE2]; - - int32_t v2 = data.field_8.field_1A4; - if (rob_cmn_mottbl_data - && chara_index >= CHARA_MIKU - && chara_index >= 0 && chara_index < rob_cmn_mottbl_data->chara_count - && id >= 0 && id < rob_cmn_mottbl_data->mottbl_indices_count) { - rob_cmn_mottbl_sub_header* v4 = (rob_cmn_mottbl_sub_header*)((uint8_t*)rob_cmn_mottbl_data - + rob_cmn_mottbl_data->subheaders_offset); - if (v2 >= 0 && v2 < v4[chara_index].field_4) - return ((int32_t*)((uint8_t*)rob_cmn_mottbl_data - + *(int32_t*)((uint8_t*)rob_cmn_mottbl_data - + v2 * sizeof(int32_t) + v4[chara_index].data_offset)))[id]; - } - return -1; +void rob_sleeve_handler_data_get_sleeve_data( + ::chara_index chara_index, int32_t cos, rob_sleeve_data& l, rob_sleeve_data& r) { + rob_sleeve_handler_data->get_sleeve_data(chara_index, cos, l, r); } -bool rob_chara::is_visible() { - return !!(data.field_0 & 0x01); +bool rob_sleeve_handler_data_load() { + return rob_sleeve_handler_data->load(); +} + +void rob_sleeve_handler_data_read() { + rob_sleeve_handler_data->read(); } bool task_rob_load_add_task() { @@ -17171,6 +17231,174 @@ void rob_chara_age_age::set_step_full() { step_full = true; } +rob_sleeve::rob_sleeve() : type(), l(), r() { + +} + +rob_sleeve::~rob_sleeve() { + +} + +rob_sleeve_handler::rob_sleeve_handler() : ready() { + +} + +rob_sleeve_handler::~rob_sleeve_handler() { + +} + +void rob_sleeve_handler::clear() { + ready = false; + sleeves.clear(); + + for (p_file_handler*& i : file_handlers) + if (i) { + delete i; + i = 0; + } + file_handlers.clear(); +} + +void rob_sleeve_handler::get_sleeve_data(::chara_index chara_index, + int32_t cos, rob_sleeve_data& l, rob_sleeve_data& r) { + l = {}; + r = {}; + + auto elem = sleeves.find({ chara_index, cos }); + if (elem != sleeves.end()) { + if (elem->second.type & ROB_SLEEVE_L && elem->second.l) + l = *elem->second.l; + + if (elem->second.type & ROB_SLEEVE_R && elem->second.r) + r = *elem->second.r; + } +} + +bool rob_sleeve_handler::load() { + if (ready) + return false; + + for (p_file_handler*& i : file_handlers) + if (i->check_not_ready()) + return true; + + for (p_file_handler*& i : file_handlers) { + if (!i) + continue; + + parse(i); + + delete i; + i = 0; + } + file_handlers.clear(); + + ready = true; + return false; +} + +void rob_sleeve_handler::parse(p_file_handler* pfhndl) { + key_val kv; + kv.parse(pfhndl->get_data(), pfhndl->get_size()); + + int32_t count; + if (!kv.read("sleeve", "length", count)) + return; + + for (int32_t i = 0; i < count; i++) { + if (!kv.open_scope_fmt(i)) + continue; + + const char* chara; + int32_t cos; + const char* type_str; + kv.read("chara", chara); + kv.read("cos", cos); + kv.read("type", type_str); + + rob_sleeve_type type = (rob_sleeve_type)0; + if (!str_utils_compare(type_str, "L")) + type = ROB_SLEEVE_L; + else if (!str_utils_compare(type_str, "R")) + type = ROB_SLEEVE_R; + else if (!str_utils_compare(type_str, "LR")) + type = ROB_SLEEVE_LR; + + ::chara_index chara_index = chara_index_get_from_chara_name(chara); + + rob_sleeve& sleeve = sleeves.insert({ { chara_index, cos }, {} }).first->second; + switch (type) { + case ROB_SLEEVE_L: + parse_sleeve_data(kv, sleeve.l); + break; + case ROB_SLEEVE_R: + parse_sleeve_data(kv, sleeve.r); + break; + case ROB_SLEEVE_LR: + parse_sleeve_data(kv, sleeve.l); + parse_sleeve_data(kv, sleeve.r); + if (sleeve.l) { + rob_sleeve_data* l = sleeve.l; + rob_sleeve_data* r = sleeve.r; + r->czofs = -l->czofs; + r->zmin = -l->zmax; + r->zmax = -l->zmin; + } + break; + } + sleeve.type = type; + + kv.close_scope(); + } + + kv.close_scope(); +} + +void rob_sleeve_handler::parse_sleeve_data(key_val& kv, rob_sleeve_data*& data) { + if (data) { + delete data; + data = 0; + } + + int32_t is_default; + kv.read("is_default", is_default); + if (is_default > 0) + return; + + data = new rob_sleeve_data; + kv.read("radius", data->radius); + kv.read("cyofs", data->cyofs); + kv.read("czofs", data->czofs); + kv.read("ymin", data->ymin); + kv.read("ymax", data->ymax); + kv.read("zmin", data->zmin); + kv.read("zmax", data->zmax); + kv.read("mune_xofs", data->mune_xofs); + kv.read("mune_yofs", data->mune_yofs); + kv.read("mune_zofs", data->mune_zofs); + kv.read("mune_rad", data->mune_rad); +} + +void rob_sleeve_handler::read() { + ready = false; + + data_struct* aft_data = &data_list[DATA_AFT]; + for (const std::string& i : mdata_manager_get()->GetPrefixes()) { + std::string dir; + dir.assign("rom/"); + dir.append(i); + + const char* file = "rob_sleeve_data.txt"; + + if (!aft_data->check_file_exists(dir.c_str(), file)) + continue; + + p_file_handler* pfhndl = new p_file_handler; + pfhndl->read_file(aft_data, dir.c_str(), file); + file_handlers.push_back(pfhndl); + } +} + osage_set_motion::osage_set_motion() { motion_id = -1; } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index c2fffa8a..7563b974 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -1262,7 +1262,7 @@ struct struc_258 { struc_258(); }; -struct sleeve_data { +struct rob_sleeve_data { float_t radius; float_t cyofs; float_t czofs; @@ -1277,8 +1277,8 @@ struct sleeve_data { }; struct rob_chara_bone_data_sleeve_adjust { - sleeve_data sleeve_l; - sleeve_data sleeve_r; + rob_sleeve_data sleeve_l; + rob_sleeve_data sleeve_r; bool enable1; bool enable2; vec3 field_5C; @@ -1357,8 +1357,8 @@ struct rob_chara_pv_data { vec3 field_8; int16_t rot_y_int16; int16_t field_16; - sleeve_data sleeve_l; - sleeve_data sleeve_r; + rob_sleeve_data sleeve_l; + rob_sleeve_data sleeve_r; int32_t field_70; int32_t motion_face_ids[10]; int32_t chara_size_index; @@ -3534,6 +3534,11 @@ extern bool rob_chara_check_for_ageageagain_module(chara_index chara_index, int3 extern bool rob_chara_pv_data_array_check_chara_id(int32_t chara_id); +extern void rob_sleeve_handler_data_get_sleeve_data( + ::chara_index chara_index, int32_t cos, rob_sleeve_data& l, rob_sleeve_data& r); +extern bool rob_sleeve_handler_data_load(); +extern void rob_sleeve_handler_data_read(); + extern bool pv_osage_manager_array_get_disp(); extern void pv_osage_manager_array_set_not_reset_true(); extern void pv_osage_manager_array_set_pv_id(int32_t chara_id, int32_t pv_id, bool reset); diff --git a/src/CRE/rob/skin_param.cpp b/src/CRE/rob/skin_param.cpp index 8d14f1eb..2d5db712 100644 --- a/src/CRE/rob/skin_param.cpp +++ b/src/CRE/rob/skin_param.cpp @@ -19,7 +19,7 @@ struct osage_setting { void clear(); const osage_setting_osg_cat* get_cat_value( object_info* obj_info, const char* root_node); - void load_file(); + void load(); void parse(key_val* kv); rob_osage_parts parse_parts_string(std::string& s); }; @@ -75,7 +75,7 @@ struct sp_skp_db { ~sp_skp_db(); void clear(); - void load_file(); + void load(); void parse(key_val* kv); int32_t get_ext_skp_file(const osage_init_data& osage_init, @@ -89,8 +89,8 @@ static SkinParamManager* skin_param_manager_get(int32_t chara_id); static bool sp_skp_db_load_file(void* data, const char* path, const char* file, uint32_t hash); -osage_setting osage_setting_data; -sp_skp_db sp_skp_db_data; +osage_setting* osage_setting_data; +sp_skp_db* sp_skp_db_data; SkinParamManager* skin_param_manager; @@ -175,24 +175,27 @@ osage_setting_osg_cat::osage_setting_osg_cat() : exf() { const osage_setting_osg_cat* osage_setting_data_get_cat_value( object_info* obj_info, const char* root_node) { - return osage_setting_data.get_cat_value(obj_info, root_node); + return osage_setting_data->get_cat_value(obj_info, root_node); } bool osage_setting_data_obj_has_key(object_info key) { - return osage_setting_data.obj.find(key) != osage_setting_data.obj.end(); + return osage_setting_data->obj.find(key) != osage_setting_data->obj.end(); } void skin_param_data_init() { - osage_setting_data = {}; - sp_skp_db_data = {}; + if (!osage_setting_data) + osage_setting_data = new osage_setting; + + if (!sp_skp_db_data) + sp_skp_db_data = new sp_skp_db; if (!skin_param_manager) skin_param_manager = new SkinParamManager[ROB_CHARA_COUNT]; } void skin_param_data_load() { - osage_setting_data.load_file(); - sp_skp_db_data.load_file(); + osage_setting_data->load(); + sp_skp_db_data->load(); } void skin_param_data_free() { @@ -201,8 +204,15 @@ void skin_param_data_free() { skin_param_manager = 0; } - sp_skp_db_data.clear(); - osage_setting_data.clear(); + if (sp_skp_db_data) { + delete sp_skp_db_data; + sp_skp_db_data = 0; + } + + if (osage_setting_data) { + delete osage_setting_data; + osage_setting_data = 0; + } } bool skin_param_manager_array_check_task_ready() { @@ -507,18 +517,18 @@ void osage_setting::clear() { const osage_setting_osg_cat* osage_setting::get_cat_value( object_info* obj_info, const char* root_node) { - auto elem_obj = osage_setting_data.obj.find(*obj_info); - if (elem_obj == osage_setting_data.obj.end()) + auto elem_obj = osage_setting_data->obj.find(*obj_info); + if (elem_obj == osage_setting_data->obj.end()) return 0; - auto elem_cat = osage_setting_data.cat.find({ elem_obj->second, root_node }); - if (elem_cat == osage_setting_data.cat.end()) + auto elem_cat = osage_setting_data->cat.find({ elem_obj->second, root_node }); + if (elem_cat == osage_setting_data->cat.end()) return 0; return &elem_cat->second; } -void osage_setting::load_file() { +void osage_setting::load() { clear(); data_struct* aft_data = &data_list[DATA_AFT]; @@ -718,7 +728,7 @@ void SkinParamManager::AddFiles() { bool read_farc = false; if (skp_file->type == -1) { - skp_file->type = sp_skp_db_data.get_ext_skp_file(i, + skp_file->type = sp_skp_db_data->get_ext_skp_file(i, obj_info, file, farc_file, aft_data, aft_mot_db, aft_obj_db); if (skp_file->type == -1) { delete skp_file; @@ -994,7 +1004,7 @@ void sp_skp_db::clear() { farc_list_count = 0; } -void sp_skp_db::load_file() { +void sp_skp_db::load() { data_struct* aft_data = &data_list[DATA_AFT]; for (const std::string& i : mdata_manager_get()->GetPrefixes()) { std::string file; diff --git a/src/CRE/sound.cpp b/src/CRE/sound.cpp index c2d553b9..e4960be5 100644 --- a/src/CRE/sound.cpp +++ b/src/CRE/sound.cpp @@ -836,7 +836,7 @@ namespace sound { } } -sound_db_farc::sound_db_farc() : loaded() { +sound_db_farc::sound_db_farc() : ready() { } @@ -845,7 +845,7 @@ sound_db_farc::~sound_db_farc() { } bool sound_db_farc::load() { - if (loaded) + if (ready) return false; else if (file_handler.check_not_ready()) return true; @@ -853,12 +853,12 @@ bool sound_db_farc::load() { farc.read(file_handler.get_data(), file_handler.get_size()); if (farc.files.size() && sound_work->ParseProperty(this)) - loaded = true; + ready = true; return false; } bool sound_db_farc::read(const char* file_path) { - if (loaded) + if (ready) unload(); this->file_path.assign(file_path); @@ -871,7 +871,7 @@ bool sound_db_farc::unload() { return false; file_path.clear(); - loaded = false; + ready = false; file_handler.reset(); return true; } diff --git a/src/CRE/sound.hpp b/src/CRE/sound.hpp index c333dc03..017855bc 100644 --- a/src/CRE/sound.hpp +++ b/src/CRE/sound.hpp @@ -163,7 +163,7 @@ enum WaveAudioDataFormat { struct sound_db_farc { std::string file_path; - bool loaded; + bool ready; p_file_handler file_handler; farc farc; diff --git a/src/KKdLib/a3da.cpp b/src/KKdLib/a3da.cpp index 6f01c0b3..478497a5 100644 --- a/src/KKdLib/a3da.cpp +++ b/src/KKdLib/a3da.cpp @@ -907,8 +907,8 @@ static void a3da_read_text(a3da* a, void* data, size_t size) { enum_or(ml->flags, A3DA_MATERIAL_LIST_BLEND_COLOR); if (key_val_read(&kv, "glow_intensity", ml->glow_intensity)) enum_or(ml->flags, A3DA_MATERIAL_LIST_GLOW_INTENSITY); - if (key_val_read(&kv, "incandescence", ml->incandescence)) - enum_or(ml->flags, A3DA_MATERIAL_LIST_INCANDESCENCE); + if (key_val_read(&kv, "incandescence", ml->emission)) + enum_or(ml->flags, A3DA_MATERIAL_LIST_EMISSION); kv.read("name", ml->name); kv.close_scope(); @@ -1544,7 +1544,7 @@ static void a3da_write_text(a3da* a, void** data, size_t* size, bool a3dc) { key_val_out_write(&kv, s, "glow_intensity", ml->glow_intensity); kv.write(s, "hash_name", hash_string_murmurhash(ml->name)); if (ml->flags & A3DA_MATERIAL_LIST_BLEND_COLOR) - key_val_out_write(&kv, s, "incandescence", ml->incandescence); + key_val_out_write(&kv, s, "incandescence", ml->emission); kv.write(s, "name", ml->name); kv.close_scope(); @@ -1948,8 +1948,8 @@ static void a3da_read_data(a3da* a, void* data, size_t size) { a3dc_read_a3da_rgba(data, size, &i.blend_color); if (i.flags & A3DA_MATERIAL_LIST_GLOW_INTENSITY) a3dc_read_a3da_key(data, size, &i.glow_intensity); - if (i.flags & A3DA_MATERIAL_LIST_INCANDESCENCE) - a3dc_read_a3da_rgba(data, size, &i.incandescence); + if (i.flags & A3DA_MATERIAL_LIST_EMISSION) + a3dc_read_a3da_rgba(data, size, &i.emission); } for (a3da_object& i : a->object) { @@ -2148,8 +2148,8 @@ static void a3da_write_data(a3da* a, void** data, size_t* size) { a3dc_write_a3da_key(s, i.glow_intensity); if (i.flags & A3DA_MATERIAL_LIST_BLEND_COLOR) a3dc_write_a3da_rgba(s, i.blend_color); - if (i.flags & A3DA_MATERIAL_LIST_INCANDESCENCE) - a3dc_write_a3da_rgba(s, i.incandescence); + if (i.flags & A3DA_MATERIAL_LIST_EMISSION) + a3dc_write_a3da_rgba(s, i.emission); } for (a3da_object& i : a->object) { diff --git a/src/KKdLib/a3da.hpp b/src/KKdLib/a3da.hpp index 04e128fe..8ccf040b 100644 --- a/src/KKdLib/a3da.hpp +++ b/src/KKdLib/a3da.hpp @@ -103,7 +103,7 @@ enum a3da_light_flags { enum a3da_material_list_flags { A3DA_MATERIAL_LIST_BLEND_COLOR = 0x01, A3DA_MATERIAL_LIST_GLOW_INTENSITY = 0x02, - A3DA_MATERIAL_LIST_INCANDESCENCE = 0x04, + A3DA_MATERIAL_LIST_EMISSION = 0x04, }; enum a3da_model_transform_flags { @@ -358,7 +358,7 @@ struct a3da_material_list { a3da_material_list_flags flags; a3da_rgba blend_color; a3da_key glow_intensity; - a3da_rgba incandescence; + a3da_rgba emission; std::string name; a3da_material_list(); diff --git a/src/KKdLib/interpolation.cpp b/src/KKdLib/interpolation.cpp index 621a5040..8c9cd9df 100644 --- a/src/KKdLib/interpolation.cpp +++ b/src/KKdLib/interpolation.cpp @@ -52,53 +52,6 @@ void interpolate_chs_reverse(float_t* arr, size_t length, t2 = (float_t)(tt2 / (double_t)(f2 - f1 - 2)); } -void interpolate_chs_reverse_step_value(float_t* arr, size_t length, - float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f, uint8_t step) { - t1 = 0.0f; - t2 = 0.0f; - - if (!arr || length < 2 || f - f1 + 1 >= length || f < 1 || f < f1 || f + 2 > f2) - return; - - float_t df_1 = (float_t)((f - f1) * step); - float_t df_2 = (float_t)((f - f1 + 1) * step); - float_t _t1 = df_1 / (float_t)((f2 - f1) * step); - float_t _t2 = df_2 / (float_t)((f2 - f1) * step); - float_t t1_1 = _t1 - 1.0f; - float_t t2_1 = _t2 - 1.0f; - - float_t t1_t2_1 = arr[f] - (1.0f + 2.0f * _t1) * (t1_1 * t1_1) * arr[f1] - - _t1 * _t1 * (3.0f - 2.0f * _t1) * arr[f2]; - float_t t1_t2_2 = arr[f + 1] - (1.0f + 2.0f * _t2) * (t2_1 * t2_1) * arr[f1] - - _t2 * _t2 * (3.0f - 2.0f * _t2) * arr[f2]; - t1_t2_1 /= df_1 * t1_1; - t1_t2_2 /= df_2 * t2_1; - - t1 = (t1_t2_1 * _t2 - t1_t2_2 * _t1) / (_t1 - _t2); - t2 = (-t1_t2_1 * t2_1 + t1_t2_2 * t1_1) / (_t1 - _t2); -} - -void interpolate_chs_reverse_step(float_t* arr, size_t length, - float_t& t1, float_t& t2, size_t f1, size_t f2, uint8_t step) { - t1 = 0.0f; - t2 = 0.0f; - - if (f2 - f1 - 2 < 1) - return; - - float_t _t1 = 0.0f; - float_t _t2 = 0.0f; - double_t tt1 = 0.0; - double_t tt2 = 0.0; - for (size_t i = f1 + 1; i < f2 - 1; i++) { - interpolate_chs_reverse_step_value(arr, length, _t1, _t2, f1, f2, i, step); - tt1 += _t1; - tt2 += _t2; - } - t1 = (float_t)(tt1 / (double_t)(f2 - f1 - 2)); - t2 = (float_t)(tt2 / (double_t)(f2 - f1 - 2)); -} - int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std::vector& values) { size_t count = values_src.size(); if (!count) @@ -127,9 +80,6 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: return 0; } - int32_t start_time = 0; - int32_t end_time = (int32_t)(count - 1); - float_t* arr = values_src.data(); const float_t reverse_bias = 0.0001f; @@ -137,17 +87,15 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: float_t* a = arr; size_t left_count = count; - int32_t frame = start_time; - int32_t prev_frame = start_time; + int32_t frame = 0; + int32_t prev_frame = 0; float_t t2_old = 0.0f; while (left_count > 0) { if (left_count < reverse_min_count) { if (left_count > 1) { - float_t _t2 = t2_old; - for (size_t j = 0; j < left_count - 1; j++) { - values.push_back({ (float_t)(int32_t)(frame + j), a[j], _t2, 0.0f }); - _t2 = 0.0f; - } + values.push_back({ (float_t)frame, a[0], t2_old, 0.0f }); + for (size_t j = 1; j < left_count - 1; j++) + values.push_back({ (float_t)(int32_t)(frame + j), a[j] }); t2_old = 0.0f; } break; @@ -193,8 +141,8 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: i_prev = i; t1_prev = t1; t2_prev = t2; + has_prev_error = false; has_prev_succeded = true; - has_prev_error = has_error; if (i < left_count) continue; } @@ -203,44 +151,26 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: i = i_prev; t1 = t1_prev; t2 = t2_prev; - has_error = has_prev_error; + has_error = false; + has_prev_succeded = false; } - if (!has_error) - c = (int32_t)i; - else - c = 1; - - if (has_error) { - values.push_back({ (float_t)frame, a[0], t2_old, 0.0f }); - t2_old = 0.0f; - } - else { - values.push_back({ (float_t)frame, a[0], t2_old, t1 }); - t2_old = t2; - } - has_prev_succeded = false; - break; - if (!has_error) { - i_prev = i; - t1_prev = t1; - t2_prev = t2; - has_prev_succeded = true; - has_prev_error = has_error; - if (i < left_count) - continue; + c = (int32_t)i; + values.push_back({ (float_t)frame, a[0], t2_old, t1 }); + t2_old = t2; + has_prev_error = false; + break; } - break; + + has_prev_error = true; } if (has_prev_succeded) { if (has_error) { - float_t _t2 = t2_old; - for (size_t j = 0; j < c; j++) { - values.push_back({ (float_t)(frame + j), a[j], _t2, 0.0f }); - _t2 = 0.0f; - } + values.push_back({ (float_t)frame, a[0], t2_old, 0.0f }); + for (size_t j = 1; j < c; j++) + values.push_back({ (float_t)(int32_t)(frame + j), a[j] }); t2_old = 0.0f; } else { @@ -249,6 +179,11 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: } c = (int32_t)i; } + else if (has_prev_error) { + values.push_back({ (float_t)frame, a[0], t2_old, 0.0f }); + t2_old = 0.0f; + c = 1; + } prev_frame = frame; frame += c; @@ -256,7 +191,7 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: left_count -= c; } - values.push_back({ (float_t)(int32_t)(start_time + (count - 1)), arr[count - 1], t2_old, 0.0f }); + values.push_back({ (float_t)(int32_t)(count - 1), arr[count - 1], t2_old, 0.0f }); kft3* keys = values.data(); size_t length = values.size(); diff --git a/src/KKdLib/interpolation.hpp b/src/KKdLib/interpolation.hpp index 04fe16be..c833d6bf 100644 --- a/src/KKdLib/interpolation.hpp +++ b/src/KKdLib/interpolation.hpp @@ -88,6 +88,8 @@ inline std::vector interpolate_linear(float_t p1, float_t p2, size_t f1 inline float_t interpolate_chs_value(const float_t p1, const float_t p2, const float_t t1, const float_t t2, const float_t f1, const float_t f2, const float_t f) { + if (p1 == p2 && fabsf(t1) == 0.0f && fabsf(t2) == 0.0f) + return p1; float_t df = f - f1; float_t t = df / (f2 - f1); float_t t_1 = t - 1.0f; @@ -98,6 +100,8 @@ inline float_t interpolate_chs_value(const float_t p1, const float_t p2, inline vec2 interpolate_chs_value(const vec2 p1, const vec2 p2, const vec2 t1, const vec2 t2, const vec2 f1, const vec2 f2, const vec2 f) { + if (p1 == p2 && vec2::abs(t1) == 0.0f && vec2::abs(t2) == 0.0f) + return p1; __m128 _p1; __m128 _p2; __m128 _t1; @@ -129,6 +133,8 @@ inline vec2 interpolate_chs_value(const vec2 p1, const vec2 p2, inline vec3 interpolate_chs_value(const vec3 p1, const vec3 p2, const vec3 t1, const vec3 t2, const vec3 f1, const vec3 f2, const vec3 f) { + if (p1 == p2 && vec3::abs(t1) == 0.0f && vec3::abs(t2) == 0.0f) + return p1; __m128 _p1; __m128 _p2; __m128 _t1; @@ -160,6 +166,8 @@ inline vec3 interpolate_chs_value(const vec3 p1, const vec3 p2, inline vec4 interpolate_chs_value(const vec4 p1, const vec4 p2, const vec4 t1, const vec4 t2, const vec4 f1, const vec4 f2, const vec4 f) { + if (p1 == p2 && vec4::abs(t1) == 0.0f && vec4::abs(t2) == 0.0f) + return p1; __m128 _p1; __m128 _p2; __m128 _t1; @@ -204,8 +212,4 @@ extern void interpolate_chs_reverse_value(float_t* arr, size_t length, float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f); extern void interpolate_chs_reverse(float_t* arr, size_t length, float_t& t1, float_t& t2, size_t f1, size_t f2); -extern void interpolate_chs_reverse_step_value(float_t* arr, size_t length, - float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f, uint8_t step); -extern void interpolate_chs_reverse_step(float_t* arr, size_t length, - float_t& t1, float_t& t2, size_t f1, size_t f2, uint8_t step); extern int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std::vector& values); diff --git a/src/KKdLib/mot.cpp b/src/KKdLib/mot.cpp index cafea7c4..3bfce746 100644 --- a/src/KKdLib/mot.cpp +++ b/src/KKdLib/mot.cpp @@ -154,10 +154,11 @@ inline static float_t mot_set_add_key(bool has_error, float_t* a, int32_t frame, size_t i, float_t t1, float_t t2, float_t t2_old, std::vector& frames, std::vector& values) { if (has_error) { - float_t _t2 = t2_old; - for (size_t j = 0; j < i; j++) { - mot_set_add_key((uint16_t)(frame + j), a[j], _t2, frames, values); - _t2 = 0.0f; + mot_set_add_key((uint16_t)frame, a[0], t2_old, frames, values); + if (t2_old == 0.0f) + mot_set_add_key((uint16_t)frame, a[0], t2_old, frames, values); + for (size_t j = 1; j < i; j++) { + mot_set_add_key((uint16_t)(frame + j), a[j], 0.0f, frames, values); mot_set_add_key((uint16_t)(frame + j), a[j], 0.0f, frames, values); } return 0.0f; @@ -294,8 +295,8 @@ mot_key_set_type mot_set::fit_keys_into_curve(std::vector& values_src, i_prev = i; t1_prev = t1; t2_prev = t2; + has_prev_error = false; has_prev_succeded = true; - has_prev_error = has_error; if (i < left_count) continue; } @@ -304,34 +305,28 @@ mot_key_set_type mot_set::fit_keys_into_curve(std::vector& values_src, i = i_prev; t1 = t1_prev; t2 = t2_prev; - has_error = has_prev_error; + has_error = false; + has_prev_succeded = false; } - if (!has_error) - c = (int32_t)i; - else - c = 1; - - t2_old = mot_set_add_key(has_error, a, frame, c, t1, t2, t2_old, frames, values); - has_prev_succeded = false; - break; - if (!has_error) { - i_prev = i; - t1_prev = t1; - t2_prev = t2; - has_prev_succeded = true; - has_prev_error = has_error; - if (i < left_count) - continue; + c = (int32_t)i; + t2_old = mot_set_add_key(has_error, a, frame, c, t1, t2, t2_old, frames, values); + has_prev_error = false; + break; } - break; + + has_prev_error = true; } if (has_prev_succeded) { t2_old = mot_set_add_key(has_error, a, frame, c, t1_prev, t2_prev, t2_old, frames, values); c = (int32_t)i; } + else if (has_prev_error) { + t2_old = mot_set_add_key(has_error, a, frame, c, t1, t2, t2_old, frames, values); + c = 1; + } prev_frame = frame; frame += c; diff --git a/src/KKdLib/vec.cpp b/src/KKdLib/vec.cpp index b75e2750..1cad2579 100644 --- a/src/KKdLib/vec.cpp +++ b/src/KKdLib/vec.cpp @@ -9,5 +9,9 @@ const __m128 vec2_neg = { -0.0f, -0.0f, 0.0f, 0.0f }; const __m128 vec3_neg = { -0.0f, -0.0f, -0.0f, 0.0f }; const __m128 vec4_neg = { -0.0f, -0.0f, -0.0f, -0.0f }; +const vec4i vec2_abs = { (int32_t)0x7FFFFFFF, (int32_t)0x7FFFFFFF, (int32_t)0x00000000, (int32_t)0x00000000 }; +const vec4i vec3_abs = { (int32_t)0x7FFFFFFF, (int32_t)0x7FFFFFFF, (int32_t)0x7FFFFFFF, (int32_t)0x00000000 }; +const vec4i vec4_abs = { (int32_t)0x7FFFFFFF, (int32_t)0x7FFFFFFF, (int32_t)0x7FFFFFFF, (int32_t)0x7FFFFFFF }; + const vec4i vec4_mask_vec2 = { (int32_t)0xFFFFFFFF, (int32_t)0xFFFFFFFF, (int32_t)0x00000000, (int32_t)0x00000000 }; const vec4i vec4_mask_vec3 = { (int32_t)0xFFFFFFFF, (int32_t)0xFFFFFFFF, (int32_t)0xFFFFFFFF, (int32_t)0x00000000 }; diff --git a/src/KKdLib/vec.hpp b/src/KKdLib/vec.hpp index daebc234..ca49467d 100644 --- a/src/KKdLib/vec.hpp +++ b/src/KKdLib/vec.hpp @@ -302,6 +302,7 @@ struct vec2 { static float_t length_squared(const vec2& left); static float_t distance(const vec2& left, const vec2& right); static float_t distance_squared(const vec2& left, const vec2& right); + static vec2 abs(const vec2& left); static vec2 lerp(const vec2& left, const vec2& right, const vec2& blend); static vec2 lerp(const vec2& left, const vec2& right, const float_t blend); static vec2 normalize(const vec2& left); @@ -337,6 +338,7 @@ struct vec3 { static float_t length_squared(const vec3& left); static float_t distance(const vec3& left, const vec3& right); static float_t distance_squared(const vec3& left, const vec3& right); + static vec3 abs(const vec3& left); static vec3 lerp(const vec3& left, const vec3& right, const vec3& blend); static vec3 lerp(const vec3& left, const vec3& right, const float_t blend); static vec3 normalize(const vec3& left); @@ -374,6 +376,7 @@ struct vec4 { static float_t length_squared(const vec4& left); static float_t distance(const vec4& left, const vec4& right); static float_t distance_squared(const vec4& left, const vec4& right); + static vec4 abs(const vec4& left); static vec4 lerp(const vec4& left, const vec4& right, const vec4& blend); static vec4 lerp(const vec4& left, const vec4& right, const float_t blend); static vec4 normalize(const vec4& left); @@ -455,6 +458,10 @@ extern const __m128 vec2_neg; extern const __m128 vec3_neg; extern const __m128 vec4_neg; +extern const vec4i vec2_abs; +extern const vec4i vec3_abs; +extern const vec4i vec4_abs; + extern const vec4i vec4_mask_vec2; extern const vec4i vec4_mask_vec3; @@ -802,6 +809,10 @@ inline float_t vec2::distance_squared(const vec2& left, const vec2& right) { return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); } +inline vec2 vec2::abs(const vec2& left) { + return vec2::store_xmm(_mm_and_ps(vec2::load_xmm(left), _mm_castsi128_ps(vec4i::load_xmm(vec2_abs)))); +} + inline vec2 vec2::lerp(const vec2& left, const vec2& right, const vec2& blend) { __m128 b1; __m128 b2; @@ -1094,6 +1105,10 @@ inline float_t vec3::distance_squared(const vec3& left, const vec3& right) { return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); } +inline vec3 vec3::abs(const vec3& left) { + return vec3::store_xmm(_mm_and_ps(vec3::load_xmm(left), _mm_castsi128_ps(vec4i::load_xmm(vec3_abs)))); +} + inline vec3 vec3::lerp(const vec3& left, const vec3& right, const vec3& blend) { __m128 b1; __m128 b2; @@ -1388,6 +1403,10 @@ inline float_t vec4::distance_squared(const vec4& left, const vec4& right) { return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); } +inline vec4 vec4::abs(const vec4& left) { + return vec4::store_xmm(_mm_and_ps(vec4::load_xmm(left), _mm_castsi128_ps(vec4i::load_xmm(vec4_abs)))); +} + inline vec4 vec4::lerp(const vec4& left, const vec4& right, const vec4& blend) { __m128 b1; __m128 b2; diff --git a/src/ReDIVA/classes/data_view/auth_3d.cpp b/src/ReDIVA/classes/data_view/auth_3d.cpp index c4a8d010..417a943b 100644 --- a/src/ReDIVA/classes/data_view/auth_3d.cpp +++ b/src/ReDIVA/classes/data_view/auth_3d.cpp @@ -653,8 +653,8 @@ static void data_view_auth_3d_imgui_auth_3d_material_list(auth_3d_material_list* data_view_auth_3d_imgui_auth_3d_key(&ml->glow_intensity, 0, false); } - if (ml->flags & AUTH_3D_MATERIAL_LIST_INCANDESCENCE) - data_view_auth_3d_imgui_auth_3d_rgba(&ml->incandescence, "Incandescence"); + if (ml->flags & AUTH_3D_MATERIAL_LIST_EMISSION) + data_view_auth_3d_imgui_auth_3d_rgba(&ml->emission, "Emission"); ImGui::TreePop(); } diff --git a/src/ReDIVA/data_initialize.cpp b/src/ReDIVA/data_initialize.cpp index 685f2364..3204fe5a 100644 --- a/src/ReDIVA/data_initialize.cpp +++ b/src/ReDIVA/data_initialize.cpp @@ -4,6 +4,7 @@ */ #include "data_initialize.hpp" +#include "../CRE/rob/rob.hpp" #include "../CRE/auth_2d.hpp" #include "../CRE/data.hpp" #include "../CRE/hand_item.hpp" @@ -116,8 +117,9 @@ bool TaskDataInit::Ctrl() { //sub_1403882D0(); //sub_140388560(); hand_item_handler_data_read(); - //rob_sleeve_data_read_file(); - //sub_140542F80(); + rob_sleeve_handler_data_read(); + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) + rob_chara_age_age_array_reset(i); state = 9; break; case 9: @@ -142,8 +144,7 @@ bool TaskDataInit::Ctrl() { //&& !sub_140385220() //&& !sub_140388A50() && !hand_item_handler_data_load() - //&& !rob_sleeve_data_parse_file() - ) { + && !rob_sleeve_handler_data_load()) { //sub_14037F680(); //sub_1403F98D0(sub_1403F8C30()); //sub_140378060(); diff --git a/src/ReDIVA/pv_game.cpp b/src/ReDIVA/pv_game.cpp index db566be6..c5143fc4 100644 --- a/src/ReDIVA/pv_game.cpp +++ b/src/ReDIVA/pv_game.cpp @@ -3,7 +3,6 @@ GitHub/GitLab: korenkonder */ -#include #include "pv_game.hpp" #include "../CRE/Glitter/glitter.hpp" #include "../CRE/light_param/light.hpp" diff --git a/src/ReDIVA/pv_game.hpp b/src/ReDIVA/pv_game.hpp index b3c8d0c7..5a0e515c 100644 --- a/src/ReDIVA/pv_game.hpp +++ b/src/ReDIVA/pv_game.hpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index 585e492e..b8f1de03 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -863,7 +863,6 @@ static render_context* render_context_load() { dbg_set_id = aft_obj_db->get_object_set_id("DBG"); hand_item_handler_data_init(); - //rob_sleeve_data_init(); aet_manager_add_aet_sets(aft_aet_db); sprite_manager_add_spr_sets(aft_spr_db); @@ -1161,7 +1160,6 @@ static void render_context_dispose(render_context* rctx) { aet_manager_remove_aet_sets(aft_aet_db); hand_item_handler_data_free(); - //rob_sleeve_data_free(); //rob_chara_array_free_chara_id(0); render_timer->reset(); diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 83edf038..f012ae6b 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -240,7 +240,9 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys); #endif static void x_pv_game_reset_field(x_pv_game* xpvgm); static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, - std::set& object_hrc, std::set& material_list); + std::vector& object_hrc, std::vector& material_list); +static void x_pv_game_split_auth_3d_material_list(x_pv_game* xpvgm, + std::vector& object, std::vector& material_list); static void pv_game_dsc_data_find_playdata_item_anim(x_pv_game* xpvgm, int32_t chara_id); static void pv_game_dsc_data_find_playdata_set_motion(x_pv_game* xpvgm, int32_t chara_id); @@ -3678,6 +3680,8 @@ bool x_pv_game::Ctrl() { if (i.motion.size() && rob_chara_ids[chara_index] == -1) { rob_chara_pv_data pv_data; pv_data.chara_size_index = chara_init_data_get_chara_size_index(charas[chara_index]); + rob_sleeve_handler_data_get_sleeve_data( + charas[chara_index], modules[chara_index] + 1, pv_data.sleeve_l, pv_data.sleeve_r); int32_t chara_id = rob_chara_array_init_chara_index( charas[chara_index], &pv_data, modules[chara_index], true); if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) @@ -4136,8 +4140,8 @@ bool x_pv_game::Ctrl() { state_old = 18; } break; case 18: { - std::set object_hrc; - std::set material_list; + std::vector object_hrc; + std::vector material_list; for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) { x_pv_game_stage_effect& eff = stage_data.effect[i]; for (x_pv_game_stage_effect_auth_3d& j : eff.auth_3d) { @@ -4149,11 +4153,11 @@ bool x_pv_game::Ctrl() { continue; for (auth_3d_material_list& k : auth->material_list) - if (k.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_INCANDESCENCE)) - material_list.insert(k.name); + if (k.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_EMISSION)) + material_list.push_back(k.name); for (auth_3d_object_hrc& k : auth->object_hrc) - object_hrc.insert(k.object_info); + object_hrc.push_back(k.object_info); } } @@ -4169,16 +4173,66 @@ bool x_pv_game::Ctrl() { continue; for (auth_3d_material_list& l : auth->material_list) - if (l.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_INCANDESCENCE)) - material_list.insert(l.name); + if (l.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_EMISSION)) + material_list.push_back(l.name); for (auth_3d_object_hrc& l : auth->object_hrc) - object_hrc.insert(l.object_info); + object_hrc.push_back(l.object_info); } } + prj::sort_unique(object_hrc); + prj::sort_unique(material_list); + if (material_list.size()) x_pv_game_split_auth_3d_hrc_material_list(this, object_hrc, material_list); + + std::vector object; + material_list.clear(); + for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) { + x_pv_game_stage_effect& eff = stage_data.effect[i]; + for (x_pv_game_stage_effect_auth_3d& j : eff.auth_3d) { + if (!j.id.check_not_empty() || !j.id.check_loaded()) + continue; + + auth_3d* auth = j.id.get_auth_3d(); + if (!auth || !auth->material_list.size() || !auth->object.size()) + continue; + + for (auth_3d_material_list& k : auth->material_list) + if (k.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_EMISSION)) + material_list.push_back(k.name); + + for (auth_3d_object& k : auth->object) + object.push_back(k.object_info); + } + } + + for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) + for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) { + x_pv_game_stage_change_effect& chg_eff = stage_data.change_effect[i][j]; + for (x_pv_game_stage_effect_auth_3d& k : chg_eff.auth_3d) { + if (!k.id.check_not_empty() || !k.id.check_loaded()) + continue; + + auth_3d* auth = k.id.get_auth_3d(); + if (!auth || !auth->material_list.size() || !auth->object.size()) + continue; + + for (auth_3d_material_list& l : auth->material_list) + if (l.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_EMISSION)) + material_list.push_back(l.name); + + for (auth_3d_object& l : auth->object) + object.push_back(l.object_info); + } + } + + prj::sort_unique(object); + + //if (material_list.size()) + // x_pv_game_split_auth_3d_material_list(this, object, material_list); + state_old = 19; } break; case 19: { @@ -5345,7 +5399,7 @@ void XPVGameSelector::Window() { continue; ImGui::PushID(&j); - sprintf_s(buf1, sizeof(buf1), "%d", j.first); + sprintf_s(buf1, sizeof(buf1), "%d", j.first + 1); if (ImGui::Selectable(buf1, modules[i] == j.first) || ImGui::ItemKeyPressed(ImGuiKey_Enter) || (ImGui::IsItemFocused() && modules[i] != j.first)) @@ -7155,10 +7209,10 @@ static std::string x_pv_game_split_auth_3d_get_object_name( } static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, - std::set& object_hrc, std::set& material_list) { + std::vector& object_hrc, std::vector& material_list) { object_database& obj_db = xpvgm->stage_data.obj_db; std::map> object_hrc_material_list; - for (object_info i : object_hrc) { + for (const object_info i : object_hrc) { obj* obj = object_storage_get_obj(i); if (!obj) continue; @@ -7166,7 +7220,7 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, uint32_t num_material = obj->num_material; for (uint32_t j = 0; j < num_material; j++) { obj_material* material = &obj->material_array[j].material; - for (std::string k : material_list) { + for (const std::string k : material_list) { if (k.compare(material->name)) continue; @@ -7178,7 +7232,10 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, } } - for (auto i : object_hrc_material_list) { + for (auto& i : object_hrc_material_list) + prj::sort_unique(i.second); + + for (auto& i : object_hrc_material_list) { obj_set_handler* handler = object_storage_get_obj_set_handler(i.first.set_id); if (!handler) continue; @@ -7197,27 +7254,8 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, if (!skin) continue; - std::set bone_indices; - obj_mesh* mesh = obj->mesh_array; uint32_t num_mesh = obj->num_mesh; - for (uint32_t k = 0; k < num_mesh; k++, mesh++) { - uint32_t num_vertex = mesh->num_vertex; - obj_vertex_data* vertex = mesh->vertex_array; - for (uint32_t l = 0; l < num_vertex; l++, vertex++) { - if (vertex->bone_index.x != -1) - bone_indices.insert(vertex->bone_index.x); - - if (vertex->bone_index.y != -1) - bone_indices.insert(vertex->bone_index.y); - - if (vertex->bone_index.z != -1) - bone_indices.insert(vertex->bone_index.z); - - if (vertex->bone_index.w != -1) - bone_indices.insert(vertex->bone_index.w); - } - } obj_skin_bone* bone_array = skin->bone_array; uint32_t num_bone = skin->num_bone; @@ -7529,7 +7567,7 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, if (!skin) continue; - std::set hrc_nodes; + std::vector hrc_nodes; obj_skin_bone* bone_array = skin->bone_array; uint32_t num_bone = skin->num_bone; @@ -7567,11 +7605,13 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, if (!node->name.compare("BONE")) continue; - hrc_nodes.insert(node->name); + hrc_nodes.push_back(node->name); } } } + prj::sort_unique(hrc_nodes); + for (std::pair k : xpvgm->stage_data.auth_3d_ids) { auth_3d* auth = k.second.get_auth_3d(); if (!auth || !auth->object_hrc.size()) @@ -7749,6 +7789,404 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, } } +static int32_t x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, float_t play_control_size, + std::vector>& color, vec4u8& has_color, std::vector& morph) { + size_t count = (size_t)(int32_t)play_control_size; + + typedef std::pair vec4_pair; + + int32_t type = 0; + + bool has_data[8]; + has_data[0] = !!(ml.blend_color.flags & AUTH_3D_RGBA_R); + has_data[1] = !!(ml.blend_color.flags & AUTH_3D_RGBA_G); + has_data[2] = !!(ml.blend_color.flags & AUTH_3D_RGBA_B); + has_data[3] = !!(ml.blend_color.flags & AUTH_3D_RGBA_A); + has_data[4] = !!(ml.emission.flags & AUTH_3D_RGBA_R); + has_data[5] = !!(ml.emission.flags & AUTH_3D_RGBA_G); + has_data[6] = !!(ml.emission.flags & AUTH_3D_RGBA_B); + has_data[7] = !!(ml.emission.flags & AUTH_3D_RGBA_A); + + const int32_t has_data_count + = (has_data[0] ? 1 : 0) + (has_data[1] ? 1 : 0) + (has_data[2] ? 1 : 0) + (has_data[3] ? 1 : 0) + + (has_data[4] ? 1 : 0) + (has_data[5] ? 1 : 0) + (has_data[6] ? 1 : 0) + (has_data[7] ? 1 : 0); + + has_color.x = has_data[0] || has_data[4]; + has_color.y = has_data[1] || has_data[5]; + has_color.z = has_data[2] || has_data[6]; + has_color.w = has_data[3] || has_data[7]; + + + std::vector values(count); + vec4_pair* values_src = values.data(); + + if (has_data[0]) + for (size_t i = 0; i < count; i++) + values_src[i].first.x = ml.blend_color.r.interpolate((float_t)(int32_t)i); + + if (has_data[1]) + for (size_t i = 0; i < count; i++) + values_src[i].first.y = ml.blend_color.g.interpolate((float_t)(int32_t)i); + + if (has_data[2]) + for (size_t i = 0; i < count; i++) + values_src[i].first.z = ml.blend_color.b.interpolate((float_t)(int32_t)i); + + if (has_data[3]) + for (size_t i = 0; i < count; i++) + values_src[i].first.w = ml.blend_color.a.interpolate((float_t)(int32_t)i); + + if (has_data[4]) + for (size_t i = 0; i < count; i++) + values_src[i].second.x = ml.emission.r.interpolate((float_t)(int32_t)i); + + if (has_data[5]) + for (size_t i = 0; i < count; i++) + values_src[i].second.y = ml.emission.g.interpolate((float_t)(int32_t)i); + + if (has_data[6]) + for (size_t i = 0; i < count; i++) + values_src[i].second.z = ml.emission.b.interpolate((float_t)(int32_t)i); + + if (has_data[7]) + for (size_t i = 0; i < count; i++) + values_src[i].second.w = ml.emission.a.interpolate((float_t)(int32_t)i); + + { + vec4_pair val = *(vec4_pair*)&values_src[0]; + vec4_pair* arr = (vec4_pair*)&values_src[1]; + for (size_t i = count - 1; i; i--) + if (val != *arr++) + break; + + if (arr == (vec4_pair*)(values_src + count)) { + if (values_src[0].first != 0.0f || values_src[0].second != 0.0f) { + morph.push_back({ 0, (float_t)(int32_t)color.size() }); + color.push_back(values_src[0]); + return 1; + } + else + return 0; + } + } + + + float_t* arr = force_malloc_s(float_t, count); + vec4_pair* val = values_src; + + const float_t reverse_bias = 0.0001f; + const int32_t reverse_min_count = 4; + + float_t* a = arr; + vec4_pair* v = val; + size_t left_count = count; + int32_t frame = 0; + int32_t prev_frame = 0; + float_t t2_old = 0.0f; + while (left_count > 0) { + if (left_count < reverse_min_count) { + if (left_count > 1) { + morph.push_back({ (float_t)(int32_t)frame, + (float_t)(int32_t)color.size(), t2_old, 0.0f }); + color.push_back(v[0]); + for (size_t j = 1; j < left_count - 1; j++) { + morph.push_back({ (float_t)(int32_t)(frame + j), + (float_t)(int32_t)color.size() }); + color.push_back(v[j]); + } + t2_old = 0.0f; + } + break; + } + + size_t i = 0; + size_t i_prev = 0; + float_t t1 = 0.0f; + float_t t2 = 0.0f; + float_t t1_prev = 0.0f; + float_t t2_prev = 0.0f; + bool has_prev_succeded = false; + bool has_error = false; + bool has_prev_error = false; + + int32_t c = 0; + for (i = reverse_min_count - 1, i_prev = i; i < left_count; i++) { + float_t start[8]; + float_t end[8]; + float_t _t1[8]; + float_t _t2[8]; + *(vec4_pair*)start = v[0]; + *(vec4_pair*)end = v[i]; + for (size_t o = 0; o < 8; o++) { + if (!has_data[o]) + continue; + + float_t scale = fabsf(end[o] - start[o]) > 0.0f ? 1.0f / (end[o] - start[o]) : 0.0f; + float_t offset = -start[o]; + + for (size_t j = 0; j <= i; j++) + a[j] = (((float_t*)&v[j])[o] - offset) * scale; + + double_t tt1 = 0.0; + double_t tt2 = 0.0; + for (size_t j = 1; j < i; j++) { + float_t _t1 = 0.0f; + float_t _t2 = 0.0f; + interpolate_chs_reverse_value(a, left_count, _t1, _t2, 0, i, j); + tt1 += _t1; + tt2 += _t2; + } + _t1[o] = (float_t)(tt1 / (double_t)(i - 2)); + _t2[o] = (float_t)(tt2 / (double_t)(i - 2)); + } + + t1 = 0.0f; + t2 = 0.0f; + if (has_data[0]) { + t1 += _t1[0]; + t2 += _t2[0]; + } + + if (has_data[1]) { + t1 += _t1[1]; + t2 += _t2[1]; + } + + if (has_data[2]) { + t1 += _t1[2]; + t2 += _t2[2]; + } + + if (has_data[3]) { + t1 += _t1[3]; + t2 += _t2[3]; + } + + if (has_data[4]) { + t1 += _t1[4]; + t2 += _t2[4]; + } + + if (has_data[5]) { + t1 += _t1[5]; + t2 += _t2[5]; + } + + if (has_data[6]) { + t1 += _t1[6]; + t2 += _t2[6]; + } + + if (has_data[7]) { + t1 += _t1[7]; + t2 += _t2[7]; + } + + if (has_data_count) { + t1 /= (float_t)has_data_count; + t2 /= (float_t)has_data_count; + } + + has_error = false; + for (size_t j = 1; j < i; j++) { + float_t val = interpolate_chs_value(0.0f, 1.0f, t1, t2, 0.0f, (float_t)i, (float_t)j); + vec4 v_first = vec4::abs(vec4::lerp(v[0].first, v[i].first, val) - v[j].first); + vec4 v_second = vec4::abs(vec4::lerp(v[0].second, v[i].second, val) - v[j].second); + if (has_data[0] && v_first.x > reverse_bias + || has_data[1] && v_first.y > reverse_bias + || has_data[2] && v_first.z > reverse_bias + || has_data[3] && v_first.w > reverse_bias + || has_data[4] && v_second.x > reverse_bias + || has_data[5] && v_second.y > reverse_bias + || has_data[6] && v_second.z > reverse_bias + || has_data[7] && v_second.w > reverse_bias) { + has_error = true; + break; + } + } + + if (fabsf(t1) > 0.5f || fabsf(t2) > 0.5f) + has_error = true; + + if (!has_error) { + i_prev = i; + t1_prev = t1; + t2_prev = t2; + has_prev_error = false; + has_prev_succeded = true; + if (i < left_count) + continue; + } + + if (has_prev_succeded) { + i = i_prev; + t1 = t1_prev; + t2 = t2_prev; + has_error = false; + has_prev_succeded = false; + } + + if (!has_error) { + c = (int32_t)i; + morph.push_back({ (float_t)frame, + (float_t)(int32_t)color.size(), t2_old, t1 }); + color.push_back(v[0]); + t2_old = t2; + has_prev_error = false; + break; + } + + has_prev_error = true; + } + + if (has_prev_succeded) { + if (has_error) { + morph.push_back({ (float_t)frame, + (float_t)(int32_t)color.size(), t2_old, 0.0f }); + color.push_back(v[0]); + for (size_t j = 1; j < c; j++) { + morph.push_back({ (float_t)(frame + j), + (float_t)(int32_t)color.size() }); + color.push_back(v[j]); + } + t2_old = 0.0f; + } + else { + morph.push_back({ (float_t)frame, + (float_t)(int32_t)color.size(), t2_old, t1_prev }); + color.push_back(v[0]); + t2_old = t2_prev; + } + c = (int32_t)i; + } + else if (has_prev_error) { + morph.push_back({ (float_t)frame, + (float_t)(int32_t)color.size(), t2_old, 0.0f }); + color.push_back(v[0]); + t2_old = 0.0f; + c = 1; + } + + prev_frame = frame; + frame += c; + a += c; + v += c; + left_count -= c; + } + + free_def(arr); + + morph.push_back({ (float_t)(int32_t)(count - 1), + (float_t)(int32_t)color.size(), t2_old, 0.0f }); + color.push_back(val[count - 1]); + + kft3* keys = morph.data(); + size_t length = morph.size(); + for (size_t i = 0; i < count; i++) { + float_t frame = (float_t)(int32_t)i; + + kft3* first_key = keys; + kft3* key = keys; + size_t _length = length; + size_t temp; + while (_length > 0) + if (frame < key[temp = _length / 2].frame) + _length = temp; + else { + key += temp + 1; + _length -= temp + 1; + } + + if (key != first_key && key != &first_key[length]) { + float_t l_val = interpolate_linear_value(key[-1].value, key[0].value, + key[-1].frame, key[0].frame, frame); + float_t h_val = interpolate_chs_value(key[-1].value, key[0].value, + key[-1].tangent2, key[0].tangent1, + key[-1].frame, key[0].frame, frame); + if (fabsf(l_val - h_val) > reverse_bias) + return 3; + } + } + return 2; +} + +static void x_pv_game_split_auth_3d_material_list(x_pv_game* xpvgm, + std::vector& object, std::vector& material_list) { + object_database& obj_db = xpvgm->stage_data.obj_db; + std::map> object_material_list; + for (const object_info i : object) { + obj* obj = object_storage_get_obj(i); + if (!obj) + continue; + + uint32_t num_material = obj->num_material; + for (uint32_t j = 0; j < num_material; j++) { + obj_material* material = &obj->material_array[j].material; + for (const std::string k : material_list) { + if (k.compare(material->name)) + continue; + + auto elem = object_material_list.find(i); + if (elem == object_material_list.end()) + elem = object_material_list.insert({ i, {} }).first; + elem->second.push_back(k); + } + } + } + + for (auto& i : object_material_list) + prj::sort_unique(i.second); + + for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) { + x_pv_game_stage_effect& eff = xpvgm->stage_data.effect[i]; + for (x_pv_game_stage_effect_auth_3d& j : eff.auth_3d) { + if (!j.id.check_not_empty() || !j.id.check_loaded()) + continue; + + auth_3d* auth = j.id.get_auth_3d(); + if (!auth || !auth->material_list.size() || !auth->object.size()) + continue; + + printf_debug("%s\n", auth->file_name.c_str()); + + for (auth_3d_material_list& k : auth->material_list) + if (k.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_EMISSION)) { + std::vector> color; + vec4u8 has_color; + std::vector morph; + int32_t type = x_pv_game_split_auth_3d_material_list(k, + auth->play_control.size, color, has_color, morph); + printf_debug("%d %s\n", type, k.name.c_str()); + } + } + } + + for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) + for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) { + x_pv_game_stage_change_effect& chg_eff = xpvgm->stage_data.change_effect[i][j]; + for (x_pv_game_stage_effect_auth_3d& k : chg_eff.auth_3d) { + if (!k.id.check_not_empty() || !k.id.check_loaded()) + continue; + + auth_3d* auth = k.id.get_auth_3d(); + if (!auth || !auth->material_list.size() || !auth->object.size()) + continue; + + printf_debug("%s\n", auth->file_name.c_str()); + + for (auth_3d_material_list& l : auth->material_list) + if (l.flags & (AUTH_3D_MATERIAL_LIST_BLEND_COLOR | AUTH_3D_MATERIAL_LIST_EMISSION)) { + std::vector> color; + vec4u8 has_color; + std::vector morph; + int32_t type = x_pv_game_split_auth_3d_material_list(l, + auth->play_control.size, color, has_color, morph); + printf_debug("%d %s\n", type, l.name.c_str()); + } + } + } +} + static void pv_game_dsc_data_find_playdata_item_anim(x_pv_game* xpvgm, int32_t chara_id) { if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT) return; diff --git a/src/ReDIVA/x_pv_game.hpp b/src/ReDIVA/x_pv_game.hpp index 4281b133..899c64da 100644 --- a/src/ReDIVA/x_pv_game.hpp +++ b/src/ReDIVA/x_pv_game.hpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include