From b45d0e99e2860a8cf33b8183f6ee569853f487f2 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sun, 19 Apr 2026 23:37:03 +0300 Subject: [PATCH] Overhaul of Ex Data --- src/CRE/light_param.cpp | 10 +- src/CRE/light_param/wind.cpp | 126 +- src/CRE/light_param/wind.hpp | 39 +- src/CRE/mdl/disp_manager.cpp | 46 +- src/CRE/mdl/disp_manager.hpp | 22 +- src/CRE/rob/ex_block.cpp | 4260 ++++++++++++----------- src/CRE/rob/rob.cpp | 1279 +++---- src/CRE/rob/rob.hpp | 753 ++-- src/CRE/rob/skin_param.cpp | 14 +- src/KKdLib/obj.cpp | 3307 +++++++++--------- src/KKdLib/obj.hpp | 286 +- src/ReDIVA/data_test/rob_osage_test.cpp | 254 +- src/ReDIVA/data_test/rob_osage_test.hpp | 12 +- 13 files changed, 5294 insertions(+), 5114 deletions(-) diff --git a/src/CRE/light_param.cpp b/src/CRE/light_param.cpp index 549707de..9103f409 100644 --- a/src/CRE/light_param.cpp +++ b/src/CRE/light_param.cpp @@ -657,7 +657,7 @@ void light_param_data::set_light(const light_param_light* light) { } void light_param_data::set_wind(const light_param_wind* w) { - ::wind* wind = task_wind->ptr; + Wind* wind = task_wind->stage_wind.wind; if (w->has_scale) wind->scale = w->scale; @@ -665,8 +665,8 @@ void light_param_data::set_wind(const light_param_wind* w) { wind->cycle = w->cycle; if (w->has_rot) { - wind->rot_y = w->rot_y; - wind->rot_z = w->rot_z; + wind->yrot = w->rot_y; + wind->zrot = w->rot_z; } if (w->has_bias) @@ -674,8 +674,8 @@ void light_param_data::set_wind(const light_param_wind* w) { for (int32_t i = 0; i < 16; i++) if (w->has_spc[i]) { - wind->spc[i].cos = w->spc[i].cos; - wind->spc[i].sin = w->spc[i].sin; + wind->spectrum[i].cos = w->spc[i].cos; + wind->spectrum[i].sin = w->spc[i].sin; } } diff --git a/src/CRE/light_param/wind.cpp b/src/CRE/light_param/wind.cpp index 307b9927..f232a41d 100644 --- a/src/CRE/light_param/wind.cpp +++ b/src/CRE/light_param/wind.cpp @@ -7,112 +7,118 @@ #include "../rob/rob.hpp" #include "../app_system_detail.hpp" -static float_t wind_apply_spc(wind* w, float_t frame); -static void wind_ctrl(wind* w); - TaskWind* task_wind; -wind::wind() : scale(), cycle(), rot_y(), rot_z(), -bias(), spc(), wind_direction(), frame(), strength() { +Wind::Wind() : scale(), cycle(), yrot(), zrot(), +bias(), spectrum(), val(), frame(), strength() { count = 16; } -wind::~wind() { +Wind::~Wind() { } -float_t wind::get_scale() const { +float_t Wind::calc_spectrum(float_t time) const { + size_t count = this->count; + float_t value = 0.0f; + const WindSpectrum* spectrum = this->spectrum; + for (size_t i = 0; i < count; i++, spectrum++) { + float_t power = (float_t)(1 << (int32_t)i) * frame; + value += cosf(power) * spectrum->cos + sinf(power) * spectrum->sin; + } + return value + bias; +} + +void Wind::ctrl() { + float_t value = calc_spectrum(cycle * frame) * scale; + mat4 mat = mat4_identity; + mat4_mul_rotate_y(&mat, yrot * DEG_TO_RAD_FLOAT, &mat); + mat4_mul_rotate_z(&mat, zrot * DEG_TO_RAD_FLOAT, &mat); + + vec3 val(value, 0.0f, 0.0f); + mat4_transform_vector(&mat, &val, &val); + this->val = val * strength; + + if (strength >= 1.0f) + strength = 1.0f; + else + strength = strength + (float_t)(1.0 / 60.0); + + frame += get_delta_frame(); + if (frame > 65535.0f) + frame = 0.0f; +} + +float_t Wind::get_scale() const { return scale; } -void wind::set_scale(float_t value) { +void Wind::set_scale(float_t value) { scale = value; } -float_t wind::get_cycle() const { +float_t Wind::get_cycle() const { return cycle; } -void wind::set_cycle(float_t value) { +void Wind::set_cycle(float_t value) { cycle = value; } -void wind::get_rot(vec2* value) const { - value->x = rot_y; - value->y = rot_z; +void Wind::get_rot(vec2& value) const { + value.x = yrot; + value.y = zrot; } -void wind::set_rot(vec2* value) { - rot_y = value->x; - rot_z = value->y; +void Wind::set_rot(const vec2& value) { + yrot = value.x; + zrot = value.y; } -float_t wind::get_rot_y() const { - return rot_y; +float_t Wind::get_yrot() const { + return yrot; } -void wind::set_rot_y(float_t value) { - rot_y = value; +void Wind::set_yrot(float_t value) { + yrot = value; } -float_t wind::get_rot_z() const { - return rot_z; +float_t Wind::get_zrot() const { + return zrot; } -void wind::set_rot_z(float_t value) { - rot_z = value; +void Wind::set_zrot(float_t value) { + zrot = value; } -float_t wind::get_bias() const { +float_t Wind::get_bias() const { return bias; } -void wind::set_bias(float_t value) { +void Wind::set_bias(float_t value) { bias = value; } -void wind::reset() { +void Wind::reset() { strength = 0.0f; frame = 0.0f; - wind_direction = 0.0f; + val = 0.0f; } -static float_t wind_apply_spc(wind* w, float_t frame) { - size_t count = w->count; - float_t value = 0.0f; - wind_spc* spc = w->spc; - for (size_t i = 0; i < count; i++, spc++) { - float_t power = (float_t)(1 << (int32_t)i) * frame; - value += cosf(power) * spc->cos + sinf(power) * spc->sin; - } - return value + w->bias; +StageWind::StageWind() { + wind = new Wind; } -static void wind_ctrl(wind* w) { - float_t value = wind_apply_spc(w, w->cycle * w->frame) * w->scale; - mat4 mat = mat4_identity; - mat4_mul_rotate_y(&mat, w->rot_y * DEG_TO_RAD_FLOAT, &mat); - mat4_mul_rotate_z(&mat, w->rot_z * DEG_TO_RAD_FLOAT, &mat); - vec3 wind_direction = 0.0f; - wind_direction.x = value; - mat4_transform_vector(&mat, &wind_direction, &wind_direction); - w->wind_direction = wind_direction * w->strength; - if (w->strength >= 1.0f) - w->strength = 1.0f; - else - w->strength = w->strength + (float_t)(1.0 / 60.0); - - w->frame += get_delta_frame(); - if (w->frame > 65535.0f) - w->frame = 0.0f; +StageWind::~StageWind() { + delete wind; } TaskWind::TaskWind() { - ptr = new wind; + } -TaskWind:: ~TaskWind() { - delete ptr; +TaskWind::~TaskWind() { + } bool TaskWind::init() { @@ -121,12 +127,12 @@ bool TaskWind::init() { bool TaskWind::ctrl() { if (!pv_osage_manager_array_get_disp()) - wind_ctrl(ptr); + stage_wind.wind->ctrl(); return false; } bool TaskWind::dest() { - ptr->reset(); + stage_wind.wind->reset(); return true; } @@ -139,7 +145,7 @@ void task_wind_init() { } bool task_wind_hide_task() { - task_wind->ptr->reset(); + task_wind->stage_wind.wind->reset(); return task_wind->hide(); } diff --git a/src/CRE/light_param/wind.hpp b/src/CRE/light_param/wind.hpp index b4ae6cfd..46e9c492 100644 --- a/src/CRE/light_param/wind.hpp +++ b/src/CRE/light_param/wind.hpp @@ -11,44 +11,53 @@ #include "../static_var.hpp" #include "../task.hpp" -struct wind_spc { +struct WindSpectrum { float_t cos; float_t sin; }; -struct wind { +struct Wind { float_t scale; float_t cycle; - float_t rot_y; - float_t rot_z; + float_t yrot; + float_t zrot; float_t bias; size_t count; - wind_spc spc[16]; - vec3 wind_direction; + WindSpectrum spectrum[16]; + vec3 val; float_t frame; float_t strength; - wind(); - ~wind(); + Wind(); + ~Wind(); + float_t calc_spectrum(float_t time) const; + void ctrl(); float_t get_scale() const; void set_scale(float_t value); float_t get_cycle() const; void set_cycle(float_t value); - void get_rot(vec2* value) const; - void set_rot(vec2* value); - float_t get_rot_y() const; - void set_rot_y(float_t value); - float_t get_rot_z() const; - void set_rot_z(float_t value); + void get_rot(vec2& value) const; + void set_rot(const vec2& value); + float_t get_yrot() const; + void set_yrot(float_t value); + float_t get_zrot() const; + void set_zrot(float_t value); float_t get_bias() const; void set_bias(float_t value); void reset(); }; +struct StageWind { + Wind* wind; + + StageWind(); + ~StageWind(); +}; + class TaskWind : public app::Task { public: - wind* ptr; + StageWind stage_wind; TaskWind(); virtual ~TaskWind() override; diff --git a/src/CRE/mdl/disp_manager.cpp b/src/CRE/mdl/disp_manager.cpp index 55885629..0f9d45cf 100644 --- a/src/CRE/mdl/disp_manager.cpp +++ b/src/CRE/mdl/disp_manager.cpp @@ -37,6 +37,10 @@ static const GLuint BONE_INDEX_INDEX = 15; static void sub_140436760(const cam_data& cam); +RobSkinCol::RobSkinCol() : type() { + +} + material_list_struct::material_list_struct() : blend_color(), has_blend_color(), emission(), has_emission() { hash = (uint32_t)-1; } @@ -68,10 +72,6 @@ morph_struct::morph_struct() : weight() { } -texture_data_struct::texture_data_struct() : field_0() { - -} - namespace mdl { static void bind_dummy_vertex_attrib_array(uint32_t index, bool* vertex_attrib_array = 0, const int32_t value = 1); @@ -2836,7 +2836,7 @@ namespace mdl { void DispManager::entry_obj_by_object_info_object_skin(object_info obj_info, const std::vector* texture_pattern, - const texture_data_struct* texture_data, float_t alpha, + const RobSkinCol* skin_col, float_t alpha, const mat4* matrices, const mat4* ex_data_matrices, const mat4* mat, const mat4& global_mat) { obj_skin* skin = objset_info_storage_get_obj_skin(obj_info); if (!skin) @@ -2844,29 +2844,29 @@ namespace mdl { obj_skin_set_matrix_buffer(skin, matrices, ex_data_matrices, rctx_ptr->matrix_buffer, mat, global_mat); - vec4 texture_color_coefficients; - vec4 texture_color_offset; - vec4 texture_specular_coefficients; - vec4 texture_specular_offset; - if (texture_data && !texture_data->field_0) { + vec4 blend_color; + vec4 offset_color; + vec4 blend_specular; + vec4 offset_specular; + if (skin_col && !skin_col->type) { vec4 value; - get_texture_color_coeff(texture_color_coefficients); - *(vec3*)&value = texture_data->texture_color_coefficients * *(vec3*)&texture_color_coefficients; + get_texture_color_coeff(blend_color); + *(vec3*)&value = skin_col->blend_color * *(vec3*)&blend_color; value.w = 0.0f; set_texture_color_coefficients(value); - get_texture_color_offset(texture_color_offset); - *(vec3*)&value = texture_data->texture_color_offset; + get_texture_color_offset(offset_color); + *(vec3*)&value = skin_col->offset_color; value.w = 0.0f; set_texture_color_offset(value); - get_texture_specular_coeff(texture_specular_coefficients); - *(vec3*)&value = texture_data->texture_specular_coefficients * *(vec3*)&texture_specular_coefficients; + get_texture_specular_coeff(blend_specular); + *(vec3*)&value = skin_col->blend_specular * *(vec3*)&blend_specular; value.w = 0.0f; set_texture_specular_coefficients(value); - get_texture_specular_offset(texture_specular_offset); - *(vec3*)&value = texture_data->texture_specular_offset; + get_texture_specular_offset(offset_specular); + *(vec3*)&value = skin_col->offset_specular; value.w = 0.0f; set_texture_specular_offset(value); } @@ -2883,11 +2883,11 @@ namespace mdl { if (texture_pattern && texture_pattern_count) set_texture_pattern(); - if (texture_data && !texture_data->field_0) { - set_texture_color_coefficients(texture_color_coefficients); - set_texture_color_offset(texture_color_offset); - set_texture_specular_coefficients(texture_specular_coefficients); - set_texture_specular_offset(texture_specular_offset); + if (skin_col && !skin_col->type) { + set_texture_color_coefficients(blend_color); + set_texture_color_offset(offset_color); + set_texture_specular_coefficients(blend_specular); + set_texture_specular_offset(offset_specular); } } diff --git a/src/CRE/mdl/disp_manager.hpp b/src/CRE/mdl/disp_manager.hpp index 18d1230d..9d4f7dc6 100644 --- a/src/CRE/mdl/disp_manager.hpp +++ b/src/CRE/mdl/disp_manager.hpp @@ -18,6 +18,16 @@ #define TEXTURE_PATTERN_COUNT 24 #define TEXTURE_TRANSFORM_COUNT 24 +struct RobSkinCol { + int32_t type; + vec3 blend_color; + vec3 offset_color; + vec3 blend_specular; + vec3 offset_specular; + + RobSkinCol(); +}; + struct material_list_struct { uint32_t hash; vec4 blend_color; @@ -53,16 +63,6 @@ struct morph_struct { morph_struct(); }; -struct texture_data_struct { - int32_t field_0; - vec3 texture_color_coefficients; - vec3 texture_color_offset; - vec3 texture_specular_coefficients; - vec3 texture_specular_offset; - - texture_data_struct(); -}; - struct cam_data; struct render_data_context; @@ -566,7 +566,7 @@ namespace mdl { const std::vector& instances, float_t r, float_t g, float_t b, float_t a); void entry_obj_by_object_info_object_skin(object_info obj_info, const std::vector* texture_pattern, - const texture_data_struct* texture_data, float_t alpha, + const RobSkinCol* skin_col, float_t alpha, const mat4* matrices, const mat4* ex_data_matrices, const mat4* mat, const mat4& global_mat); void entry_obj_etc(const mat4& mat, const EtcObj& etc); void entry_obj_etc_screen(const mat4& mat, const EtcObj& etc); diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index 7f942558..db0cc814 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -9,24 +9,27 @@ #include "../app_system_detail.hpp" #include "../data.hpp" #include "../gl_state.hpp" +#include "../sprite.hpp" #include "skin_param.hpp" -struct exp_func_op1 { +struct ExpFuncUnaryTbl { const char* name; float_t(*func)(float_t v1); }; -struct exp_func_op2 { +struct ExpFuncBinaryTbl { const char* name; float_t(*func)(float_t v1, float_t v2); }; -struct exp_func_op3 { +struct ExpFuncTernaryTbl { const char* name; float_t(*func)(float_t v1, float_t v2, float_t v3); }; -static float_t ex_expression_block_stack_get_value(ex_expression_block_stack* stack); +static const ExpFuncUnaryTbl* ExpFuncUnaryTblFindFunc(std::string& name, const ExpFuncUnaryTbl* array); +static const ExpFuncBinaryTbl* ExpFuncBinaryTblFindFunc(std::string& name, const ExpFuncBinaryTbl* array); +static const ExpFuncTernaryTbl* ExpFuncTernaryTblFindFunc(std::string& name, const ExpFuncTernaryTbl* array); static float_t exp_abs(float_t v1); static float_t exp_acos(float_t v1); @@ -43,9 +46,6 @@ static float_t exp_eq(float_t v1, float_t v2); static float_t exp_exp(float_t v1); static float_t exp_floor(float_t v1); static float_t exp_fmod(float_t v1, float_t v2); -static const exp_func_op1* exp_func_op1_find_func(std::string& name, const exp_func_op1* array); -static const exp_func_op2* exp_func_op2_find_func(std::string& name, const exp_func_op2* array); -static const exp_func_op3* exp_func_op3_find_func(std::string& name, const exp_func_op3* array); static float_t exp_ge(float_t v1, float_t v2); static float_t exp_gt(float_t v1, float_t v2); static float_t exp_le(float_t v1, float_t v2); @@ -67,19 +67,21 @@ static float_t exp_sub(float_t v1, float_t v2); static float_t exp_tan(float_t v1); static void apply_gravity(vec3& vec, const vec3& p0, const vec3& p1, - const float_t osage_gravity_const, const float_t weight); -static float_t calculate_tbn(const vec3& pos_a, const vec3& pos_b, - const float_t uv_a_y, const float_t uv_b_y, - vec3& tangent, vec3& binormal, vec3& normal); -static float_t calculate_tbn(const vec3& pos_a, const vec3& pos_b, const vec3& pos_c, - const vec2& texcoord_a, const vec2& texcoord_b, const vec2& texcoord_c, - vec3& tangent, vec3& binormal, vec3& normal); + const float_t gravity, const float_t weight); +static float_t calc_tangent_basis(const vec3& v1, const vec3& v2, const vec3& pos_c, + const vec2& uv0, const vec2& uv1, const vec2& uv2, vec3& tangent, vec3& binormal, vec3& normal); +static float_t calc_tangent_basis(const vec3& v1, const vec3& v2, + const float_t t1, const float_t t2, vec3& tangent, vec3& binormal, vec3& normal); +static void calc_tangent_basis_sub(CLOTH_VERTEX* vtx, const CLOTH_VERTEX* vtxL, const CLOTH_VERTEX* vtxR, + const CLOTH_VERTEX* vtxU, const CLOTH_VERTEX* vtxD); static void closest_pt_segment_segment(vec3& vec, const vec3& p0, const vec3& q0, const OsageCollision::Work* cls); -static bool rotate_matrix_to_direction(mat4& mat, const vec3& direction, - const skin_param_hinge* hinge, vec3* rot, const int32_t& yz_order); -static void segment_limit_distance(vec3& p0, const vec3& p1, const float_t max_distance); +static void length_limit(vec3& p, const vec3& r, const float_t rr); +static bool make_axis_matrix(mat4& mat, const vec3& axis, + const skin_param_hinge* hinge, vec3* rot, const ROTTYPE& rottype); +static void modify_cloth_object(obj_mesh* mesh, obj_mesh_vertex_buffer* vb, + CLOTH_VERTEX* vtxarg, float_t sgn, int32_t num_idx, uint16_t* idxtbl, bool do_ura); -static const exp_func_op1 exp_func_op1_array[] = { +static const ExpFuncUnaryTbl exp_func_unary_tbl[] = { { "neg" , exp_neg }, { "sin" , exp_sin }, { "cos" , exp_cos }, @@ -99,7 +101,7 @@ static const exp_func_op1 exp_func_op1_array[] = { { 0 , 0 }, }; -static const exp_func_op2 exp_func_op2_array[] = { +static const ExpFuncBinaryTbl exp_func_binary_tbl[] = { { "+" , exp_add }, { "-" , exp_sub }, { "*" , exp_mul }, @@ -120,7 +122,7 @@ static const exp_func_op2 exp_func_op2_array[] = { { 0 , 0 }, }; -static const exp_func_op3 exp_func_op3_array[] = { +static const ExpFuncTernaryTbl exp_func_ternary_tbl[] = { { "rand", exp_rand }, { "cond", exp_cond }, { 0 , 0 }, @@ -138,17 +140,20 @@ static const char* expression_component_names[] = { "scalez", }; -size_t rob_cloth_iterations_count = 0; -int32_t rob_cloth_update_vertices_flags = 0x03; -bool rob_cloth_update_normals_select = false; -static bool rob_osage_enable_sibling_node = true; +static bool rob_osage_enable_distance = true; + +bool calc_normal_flag = false; +size_t cloth_init_cnt = 0; +int32_t cloth_modify_flag = 0x03; +int32_t dbg_init_flag = 0; +int32_t dbg_osage_line_disp_flag = 0; #if OPD_PLAY_GEN extern std::atomic_bool opd_play_gen_run; #endif -ExNodeBlock::ExNodeBlock() : bone_node_ptr(), type(), name(), parent_bone_node(), -parent_name(), parent_node(), item_equip_object(), is_parent(), done(), has_children_node() { +ExNodeBlock::ExNodeBlock() : dst_node(), type(), name(), parent(), +parent_name(), parent_node(), skin_disp(), is_parent(), done(), has_children_node() { } @@ -160,94 +165,107 @@ void ExNodeBlock::CtrlBegin() { done = false; } -void ExNodeBlock::Reset() { - bone_node_ptr = 0; +void ExNodeBlock::dest() { + dst_node = 0; } void ExNodeBlock::CtrlEnd() { done = false; } -void ExNodeBlock::InitData(bone_node* bone_node, ExNodeType type, - const char* name, rob_chara_item_equip_object* itm_eq_obj) { - bone_node_ptr = bone_node; +// 0x1405EEBF0 +void ExNodeBlock::init_members() { + dst_node = 0; + type = EX_NODE_TYPE_NULL; + name = 0; + parent = 0; + skin_disp = 0; + is_parent = false; +} + +// 0x1405EEB80 +void ExNodeBlock::set_data(bone_node* node, ExNodeType type, + const char* name, const rob_chara_item_equip_object* skin_disp) { + init_members(); + + dst_node = node; this->type = type; this->name = name ? name : "(null)"; - parent_bone_node = 0; - item_equip_object = itm_eq_obj; + parent = 0; + this->skin_disp = skin_disp; } ExNullBlock::ExNullBlock() { - Init(); + init(); } ExNullBlock::~ExNullBlock() { } -void ExNullBlock::Init() { - bone_node_ptr = 0; - type = EX_NONE; +void ExNullBlock::init() { + dst_node = 0; + type = EX_NODE_TYPE_NULL; name = 0; - parent_bone_node = 0; - item_equip_object = 0; - cns_data = 0; + parent = 0; + skin_disp = 0; + data = 0; } void ExNullBlock::CtrlBegin() { done = false; } -void ExNullBlock::CtrlStep(int32_t stage, bool disable_external_force) { +void ExNullBlock::CtrlStep(int32_t stage, bool disable_ex_force) { } -void ExNullBlock::CtrlMain() { - if (!bone_node_ptr) +void ExNullBlock::ctrl() { + if (!dst_node) return; - mat4 mat; - mat4 ex_data_mat = *parent_bone_node->ex_data_mat; - bone_node_ptr->exp_data.mat_set(parent_bone_node->exp_data.parent_scale, ex_data_mat, mat); - *bone_node_ptr->ex_data_mat = ex_data_mat; - *bone_node_ptr->mat = mat; + mat4 dsp_mat; + mat4 mat = *parent->no_scale_mat; + dst_node->transform.CalcMatrixHS(parent->transform.hsc, mat, dsp_mat); + *dst_node->no_scale_mat = mat; + *dst_node->mat_ptr = dsp_mat; } void ExNullBlock::CtrlOsagePlayData() { - CtrlMain(); + ctrl(); } -void ExNullBlock::Disp(const mat4& mat, render_context* rctx) { +void ExNullBlock::disp(const mat4& mat, render_context* rctx) { } -void ExNullBlock::Field_40() { +void ExNullBlock::disp_debug() { } -void ExNullBlock::CtrlInitBegin() { - CtrlMain(); +void ExNullBlock::pos_init() { + ctrl(); } -void ExNullBlock::CtrlInitMain() { +void ExNullBlock::pos_init_cont() { } -void ExNullBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, - obj_skin_block_constraint* cns_data, const char* cns_data_name, const bone_database* bone_data) { - bone_node* node = itm_eq_obj->get_bone_node(cns_data_name, bone_data); - type = EX_NONE; - bone_node_ptr = node; - this->cns_data = cns_data; - name = node->name; - item_equip_object = itm_eq_obj; +void ExNullBlock::set_data(const rob_chara_item_equip_object* skin_disp, + const obj_skin_ex_node_constraint* data, const char* name, const bone_database* bone_data) { + bone_node* node = (bone_node*)skin_disp->get_node(name, bone_data); + type = EX_NODE_TYPE_NULL; + dst_node = node; + this->data = data; + this->name = node->name; + this->skin_disp = skin_disp; } -RobOsageNodeDataNormalRef::RobOsageNodeDataNormalRef() : set(), n(), u(), d(), l(), r() { +RobJointNodeDataNormalRef::RobJointNodeDataNormalRef() : set(), n(), u(), d(), l(), r() { } -bool RobOsageNodeDataNormalRef::Check() { +bool RobJointNodeDataNormalRef::Check() { set = false; if (!n) return set; @@ -279,7 +297,7 @@ bool RobOsageNodeDataNormalRef::Check() { } // 0x14053CE30 -void RobOsageNodeDataNormalRef::GetMat(mat4* mat) { +void RobJointNodeDataNormalRef::GetMat(mat4* mat) { if (!set) return; @@ -288,16 +306,16 @@ void RobOsageNodeDataNormalRef::GetMat(mat4* mat) { vec3 d_trans; vec3 l_trans; vec3 r_trans; - mat4_get_translation(n->bone_node_ptr->ex_data_mat, &n_trans); - mat4_get_translation(u->bone_node_ptr->ex_data_mat, &u_trans); - mat4_get_translation(d->bone_node_ptr->ex_data_mat, &d_trans); - mat4_get_translation(l->bone_node_ptr->ex_data_mat, &l_trans); - mat4_get_translation(r->bone_node_ptr->ex_data_mat, &r_trans); + mat4_get_translation(n->dst_node->no_scale_mat, &n_trans); + mat4_get_translation(u->dst_node->no_scale_mat, &u_trans); + mat4_get_translation(d->dst_node->no_scale_mat, &d_trans); + mat4_get_translation(l->dst_node->no_scale_mat, &l_trans); + mat4_get_translation(r->dst_node->no_scale_mat, &r_trans); vec3 z_axis; vec3 y_axis; vec3 x_axis; - if (RobOsageNodeDataNormalRef::GetAxes( + if (RobJointNodeDataNormalRef::GetAxes( l_trans, r_trans, u_trans, d_trans, z_axis, y_axis, x_axis)) { mat4 temp = mat4( x_axis.x, x_axis.y, x_axis.z, 0.0f, @@ -309,7 +327,7 @@ void RobOsageNodeDataNormalRef::GetMat(mat4* mat) { } // 0x14053CAC0 -void RobOsageNodeDataNormalRef::Load() { +void RobJointNodeDataNormalRef::Load() { if (!Check()) return; @@ -327,7 +345,7 @@ void RobOsageNodeDataNormalRef::Load() { vec3 z_axis; vec3 y_axis; vec3 x_axis; - if (RobOsageNodeDataNormalRef::GetAxes( + if (RobJointNodeDataNormalRef::GetAxes( l_trans, r_trans, u_trans, d_trans, z_axis, y_axis, x_axis)) { mat4 temp = mat4( x_axis.x, y_axis.x, z_axis.x, 0.0f, @@ -341,7 +359,7 @@ void RobOsageNodeDataNormalRef::Load() { } // 0x14053D1B0 -bool RobOsageNodeDataNormalRef::GetAxes(const vec3& l_trans, const vec3& r_trans, +bool RobJointNodeDataNormalRef::GetAxes(const vec3& l_trans, const vec3& r_trans, const vec3& u_trans, const vec3& d_trans, vec3& z_axis, vec3& y_axis, vec3& x_axis) { z_axis = d_trans - u_trans; if (fabsf(vec3::length_squared(z_axis)) <= 0.000001f) @@ -393,19 +411,34 @@ skin_param_osage_node::skin_param_osage_node() : coli_r(), inertial_cancel() { hinge.limit(); } -RobOsageNodeResetData::RobOsageNodeResetData() : length() { +RobJointNodeResetData::RobJointNodeResetData() : length() { } -RobOsageNodeData::RobOsageNodeData() : force(), normal_ref() { +RobJointNodeData::RobJointNodeData() : force(), normal_ref() { } -RobOsageNodeData::~RobOsageNodeData() { +RobJointNodeData::~RobJointNodeData() { } -void RobOsageNodeData::Reset() { +void RobJointNodeData::SetForce(const skin_param_osage_root& skp_root, + skin_param_osage_node* skp_osg_node, size_t index) { + this->skp_osg_node = *skp_osg_node; + this->skp_osg_node.hinge.limit(); + + float_t force = skp_root.force; + float_t force_gain = skp_root.force_gain; + for (; index >= 4; index -= 4) + force = force * force_gain * force_gain * force_gain * force_gain; + for (; index; index--) + force *= force_gain; + this->force = force; +} + +// 0x140482D00 +void RobJointNodeData::reset() { force = 0.0f; boc.clear(); normal_ref.set = false; @@ -422,20 +455,6 @@ void RobOsageNodeData::Reset() { skp_osg_node.hinge.limit(); } -void RobOsageNodeData::SetForce(const skin_param_osage_root& skp_root, - skin_param_osage_node* skp_osg_node, size_t index) { - this->skp_osg_node = *skp_osg_node; - this->skp_osg_node.hinge.limit(); - - float_t force = skp_root.force; - float_t force_gain = skp_root.force_gain; - for (; index >= 4; index -= 4) - force = force * force_gain * force_gain * force_gain * force_gain; - for (; index; index--) - force *= force_gain; - this->force = force; -} - opd_node_data::opd_node_data() : length() { } @@ -456,7 +475,7 @@ opd_node_data_pair::opd_node_data_pair() { } // 0x140482100 -void opd_node_data_pair::set_data(opd_blend_data* blend_data, const opd_node_data& node_data) { +void opd_node_data_pair::set_data(const opd_blend_data* blend_data, const opd_node_data& node_data) { if (!blend_data->use_blend) curr = node_data; else if (blend_data->type == MOTION_BLEND_FREEZE) { @@ -468,70 +487,71 @@ void opd_node_data_pair::set_data(opd_blend_data* blend_data, const opd_node_dat opd_node_data::lerp(curr, curr, node_data, blend_data->blend); } -RobOsageNode::RobOsageNode() : length(), child_length(), bone_node_ptr(), -bone_node_mat(), sibling_node(), max_distance(), hit() { +RobJointNode::RobJointNode() : length_back(), length_next(), dst_node(), +dst_node_mat(), distance(), length_dist(), hit() { friction = 1.0f; force = 1.0f; data_ptr = &data; opd_data.resize(3); } -RobOsageNode::~RobOsageNode() { +RobJointNode::~RobJointNode() { } // 0x140482180 -void RobOsageNode::CheckFloorCollision(const float_t& floor_height) { +void RobJointNode::CheckFloorCollision(const float_t& floor_height) { float_t pos_y = data_ptr->skp_osg_node.coli_r + floor_height; if (pos_y <= pos.y) return; pos.y = pos_y; - pos = GetPrevNode().pos + vec3::normalize(pos - GetPrevNode().pos) * length; - delta_pos = 0.0f; + pos = GetPrevNode().pos + vec3::normalize(pos - GetPrevNode().pos) * length_back; + vec = 0.0f; hit += 1.0f; } // 0x140482490 -void RobOsageNode::CheckNodeDistance(const float_t& step, const float_t& parent_scale) { +void RobJointNode::CheckNodeDistance(const float_t& step, const float_t& hsc) { if (step != 1.0f) { - vec3 d = pos - fixed_pos; + vec3 d = pos - old_pos; float_t dist = vec3::length(d); if (dist != 0.0f) d *= 1.0f / dist; - pos = fixed_pos + d * (step * dist); + pos = old_pos + d * (step * dist); } - segment_limit_distance(pos, GetPrevNode().pos, length * parent_scale); + length_limit(pos, GetPrevNode().pos, length_back * hsc); - if (rob_osage_enable_sibling_node) { - if (sibling_node) - segment_limit_distance(pos, sibling_node->pos, max_distance); + if (rob_osage_enable_distance) { + if (distance) + length_limit(pos, distance->pos, length_dist); } } -void RobOsageNode::Reset() { - length = 0.0f; +// 0x140482B00 +void RobJointNode::reset() { + length_back = 0.0f; pos = 0.0f; - fixed_pos = 0.0f; - delta_pos = 0.0f; + old_pos = 0.0f; + vec = 0.0f; vel = 0.0f; - child_length = 0.0f; - bone_node_ptr = 0; - bone_node_mat = 0; - sibling_node = 0; - max_distance = 0.0f; + length_next = 0.0f; + dst_node = 0; + dst_node_mat = 0; + distance = 0; + length_dist = 0.0f; rel_pos = 0.0f; reset_data.pos = 0.0f; - reset_data.delta_pos = 0.0f; + reset_data.vec = 0.0f; reset_data.rotation = 0.0f; reset_data.length = 0.0f; hit = 0.0f; friction = 1.0f; - external_force = 0.0f; + ex_force = 0.0f; force = 1.0f; - data.Reset(); + data.reset(); data_ptr = &data; opd_data.clear(); opd_data.resize(3); @@ -544,53 +564,50 @@ vec_center(), vec_center_length(), vec_center_length_squared(), friction() { } // 0x140485450 -void OsageCollision::Work::update_cls_work(OsageCollision::Work* cls, - SkinParam::CollisionParam* cls_param, const mat4* transform) { - cls->type = SkinParam::CollisionTypeEnd; - if (!cls_param || !transform) +void OsageCollision::Work::update_cls_work(OsageCollision::Work* work, + const SkinParam::CollisionParam* cls, const mat4* motmat) { + work->type = SkinParam::CollisionTypeEnd; + if (!cls || !motmat) return; - for (; cls_param->type; cls++, cls_param++) { - cls->type = cls_param->type; - cls->radius = cls_param->radius; - mat4_transform_point(&transform[cls_param->node_idx[0]], - &cls_param->pos[0], &cls->pos[0]); + for (; cls->type; work++, cls++) { + work->type = cls->type; + work->radius = cls->radius; + mat4_transform_point(&motmat[cls->node_idx[0]], &cls->pos[0], &work->pos[0]); - switch (cls->type) { + switch (work->type) { case SkinParam::CollisionTypePlane: - mat4_transform_vector(&transform[cls_param->node_idx[0]], - &cls_param->pos[1], &cls->pos[1]); + mat4_transform_vector(&motmat[cls->node_idx[0]], &cls->pos[1], &work->pos[1]); break; case SkinParam::CollisionTypeCapsule: case SkinParam::CollisionTypeEllipse: - mat4_transform_point(&transform[cls_param->node_idx[1]], - &cls_param->pos[1], &cls->pos[1]); - cls->vec_center = cls->pos[1] - cls->pos[0]; - cls->vec_center_length_squared = vec3::length_squared(cls->vec_center); - cls->vec_center_length = sqrtf(cls->vec_center_length_squared); - if (cls->vec_center_length < 0.01f) - cls->type = SkinParam::CollisionTypeBall; + mat4_transform_point(&motmat[cls->node_idx[1]], &cls->pos[1], &work->pos[1]); + work->vec_center = work->pos[1] - work->pos[0]; + work->vec_center_length_squared = vec3::length_squared(work->vec_center); + work->vec_center_length = sqrtf(work->vec_center_length_squared); + if (work->vec_center_length < 0.01f) + work->type = SkinParam::CollisionTypeBall; break; } } - cls->type = SkinParam::CollisionTypeEnd; + work->type = SkinParam::CollisionTypeEnd; } // 0x140485410 -void OsageCollision::Work::update_cls_work(OsageCollision::Work* cls, - std::vector& cls_list, const mat4* transform) { +void OsageCollision::Work::update_cls_work(OsageCollision::Work* work, + const std::vector& cls_list, const mat4* motmat) { if (!cls_list.size()) { - cls->type = SkinParam::CollisionTypeEnd; - cls->radius = 0.0f; - cls->pos[0] = 0.0f; - cls->pos[1] = 0.0f; - cls->vec_center = 0.0f; - cls->vec_center_length = 0.0f; - cls->vec_center_length_squared = 0.0f; - cls->friction = 1.0f; + work->type = SkinParam::CollisionTypeEnd; + work->radius = 0.0f; + work->pos[0] = 0.0f; + work->pos[1] = 0.0f; + work->vec_center = 0.0f; + work->vec_center_length = 0.0f; + work->vec_center_length_squared = 0.0f; + work->friction = 1.0f; } else - update_cls_work(cls, cls_list.data(), transform); + update_cls_work(work, cls_list.data(), motmat); } OsageCollision::OsageCollision() { @@ -1051,159 +1068,167 @@ osage_ring_data& osage_ring_data::operator=(const osage_ring_data& ring) { return *this; } -CLOTHNode::CLOTHNode() : flags(), tangent_sign(), dist_top(), -dist_bottom(), dist_right(), dist_left(), reset_data() { +CLOTH_VERTEX::CLOTH_VERTEX() : flag(), m(), length_up(), +length_down(), length_left(), length_right(), reset_data() { } -CLOTHNode::~CLOTHNode() { +CLOTH_VERTEX::~CLOTH_VERTEX() { } -// 0x14021A890 -void CLOTHNode::CalculateTBN(const CLOTHNode* right, const CLOTHNode* left, - const CLOTHNode* top, const CLOTHNode* bottom) { - const vec3 pos_a = top->pos - bottom->pos; - const vec3 pos_b = left->pos - right->pos; - - const float_t pos_b_length = vec3::length(pos_a); - const float_t pos_a_length = vec3::length(pos_b); - if (pos_b_length <= 0.000001f || pos_a_length <= 0.000001f) - return; - - const vec2 uv_a = top->texcoord - bottom->texcoord; - const vec2 uv_b = left->texcoord - right->texcoord; - - float_t r = uv_b.y * uv_a.x - uv_a.y * uv_b.x; - if (fabsf(r) > 0.000001f) { - r = 1.0f / r; - tangent_sign = calculate_tbn(pos_a, pos_b, - uv_a.y * r, uv_b.y * r, tangent, binormal, normal); - } -} - -CLOTH::CLOTH() : flags(), root_count(), nodes_count(), wind_direction(), -inertia(), set_external_force(), external_force(), skin_param_ptr(), mats() { - Reset(); +CLOTH::CLOTH() : flag(), width(), height(), wind_dir(), +wet(), use_ex_force(), ex_force(), skin_param_ptr() { + init(); } CLOTH::~CLOTH() { } -void CLOTH::Init() { - lines.clear(); - if (nodes_count <= 1) +void CLOTH::set_spring() { + spring.clear(); + if (height <= 1) return; - CLOTHLine line = {}; - const size_t root_count = this->root_count; - for (size_t i = 1; i < nodes_count; i++) { - for (size_t j = 0; j < root_count; j++) { - size_t top = (i - 1) * root_count + j; - size_t center = i * root_count + j; - line.idx[0] = top; - line.idx[1] = center; - line.length = vec3::distance(nodes.data()[top].pos, nodes.data()[center].pos); - lines.push_back(line); + CLOTH_SPRING line = {}; + const size_t width = this->width; + for (size_t i = 1; i < height; i++) { + for (size_t j = 0; j < width; j++) { + size_t top = (i - 1) * width + j; + size_t center = i * width + j; + line.index0 = top; + line.index1 = center; + line.length = vec3::distance(vtxarg.data()[top].pos, vtxarg.data()[center].pos); + spring.push_back(line); - if (j < root_count - 1) { - size_t left = i * root_count + j + 1; - line.idx[0] = center; - line.idx[1] = left; - line.length = vec3::distance(nodes.data()[center].pos, nodes.data()[left].pos); - lines.push_back(line); + if (j < width - 1) { + size_t left = i * width + j + 1; + line.index0 = center; + line.index1= left; + line.length = vec3::distance(vtxarg.data()[center].pos, vtxarg.data()[left].pos); + spring.push_back(line); } } - if (flags & 0x04) { - line.idx[0] = i * root_count; - line.idx[1] = (i + 1) * root_count - 1; - lines.push_back(line); + if (flag.ring) { + line.index0 = i * width; + line.index1 = (i + 1) * width - 1; + spring.push_back(line); } } } -void CLOTH::SetSkinParamColiR(float_t value) { +void CLOTH::set_coli_r(float_t value) { skin_param_ptr->coli_r = value; } -void CLOTH::SetSkinParamFriction(float_t value) { +void CLOTH::set_friction(float_t value) { skin_param_ptr->friction = value; } -void CLOTH::SetSkinParamWindAfc(float_t value) { +void CLOTH::set_wind_affect(float_t value) { skin_param_ptr->wind_afc = value; } -void CLOTH::SetWindDirection(const vec3& value) { - this->wind_direction = value; +void CLOTH::set_wind_dir(const vec3& value) { + wind_dir = value; } -void CLOTH::SetInertia(float_t value) { - inertia = value; +void CLOTH::set_wetness(float_t value) { + wet = value; } -void CLOTH::SetSkinParamHinge(float_t hinge_y, float_t hinge_z) { +void CLOTH::set_angle_limit(float_t y, float_t z) { skin_param_hinge& hinge = skin_param_ptr->hinge; - hinge.ymax = hinge_y; - hinge.zmax = hinge_z; - hinge.ymin = -hinge_y; - hinge.zmin = -hinge_z; + hinge.ymax = y; + hinge.zmax = z; + hinge.ymin = -y; + hinge.zmin = -z; hinge.limit(); } -CLOTHNode* CLOTH::GetNodes() { - return nodes.data(); +CLOTH_VERTEX* CLOTH::get_vertex() { + return vtxarg.data(); } -void CLOTH::Reset() { - flags &= ~0x01; - root_count = 0; - nodes_count = 0; - nodes.clear(); - wind_direction = 0.0f; - inertia = 0.0f; - set_external_force = false; - external_force = 0.0f; +void CLOTH::init() { + flag.exec = 0; + width = 0; + height = 0; + vtxarg.clear(); + wind_dir = 0.0f; + wet = 0.0f; + use_ex_force = false; + ex_force = 0.0f; skin_param.reset(); skin_param_ptr = &skin_param; } -void CLOTH::ResetData() { - Reset(); +void CLOTH::disp_debug() { + if (!dbg_osage_line_disp_flag) + return; + + const color4u8 color_spring = color_red; + + const CLOTH_VERTEX* vtx = vtxarg.data(); + for (const auto& i : spring) + spr::put_sprite_3d_line(vtx[i.index0].pos, vtx[i.index1].pos, color_spring); } -RobClothSubMeshArray::RobClothSubMeshArray() { - arr[0] = {}; - arr[1] = {}; - arr[2] = {}; - arr[3] = {}; +void CLOTH::dest() { + init(); } -RobCloth::RobCloth() : itm_eq_obj(), cls_root(), cls_data(), move_cancel(), osage_reset(), -mesh(), submesh(), vertex_buffer(), index_buffer(), reset_data_list() { - ResetData(); +RobCloth::RobCloth() : local_mat(), skin_disp(), root_data(), data(), move_cancel(), osage_reset(), +mesh(), submesh(), vb(), ib(), reset_data_list() { + dest(); } RobCloth::~RobCloth() { - ResetData(); + dest(); } -void RobCloth::ResetData() { - Reset(); - mats = 0; - itm_eq_obj = 0; - cls_root = 0; - cls_data = 0; +void RobCloth::disp_debug() { + CLOTH::disp_debug(); + + if (!dbg_osage_line_disp_flag) + return; + + const color4u8 color_spring = color_red; + + const color4u8 color_tangent = color_green; + const color4u8 color_binormal = color_cyan; + const color4u8 color_normal = color_white; + + const CLOTH_VERTEX* vtx = vtxarg.data(); + for (const auto& i : spring) + spr::put_sprite_3d_line(vtx[i.index0].pos, vtx[i.index1].pos, color_spring); + + vtx += width; + for (size_t i = 1; i < height; i++) { + for (size_t j = 0; j < width; j++, vtx++) { + spr::put_sprite_3d_line(vtx->pos, vtx->tangent * 0.05f + vtx->pos, color_tangent); + spr::put_sprite_3d_line(vtx->pos, vtx->binormal * 0.05f + vtx->pos, color_binormal); + spr::put_sprite_3d_line(vtx->pos, vtx->normal * 0.05f + vtx->pos, color_normal); + } + } +} + +void RobCloth::dest() { + vb[0].unload(); + vb[1].unload(); + init(); + local_mat = 0; + skin_disp = 0; + root_data = 0; + data = 0; move_cancel = 0.0f; osage_reset = false; mesh[0] = {}; mesh[1] = {}; - vertex_buffer[0].unload(); - vertex_buffer[1].unload(); - index_buffer[0] = {}; - index_buffer[1] = {}; + ib[0] = {}; + ib[1] = {}; motion_reset_data.clear(); reset_data_list = 0; } @@ -1215,238 +1240,46 @@ void RobCloth::AddMotionResetData(uint32_t motion_id, float_t frame) { if (elem != motion_reset_data.end()) motion_reset_data.erase(elem); - std::list reset_data_list; - CLOTHNode* i_begin = nodes.data() + root_count; - CLOTHNode* i_end = nodes.data() + nodes.size(); - for (CLOTHNode* i = i_begin; i != i_end; i++) + std::list reset_data_list; + CLOTH_VERTEX* i_begin = vtxarg.data() + width; + CLOTH_VERTEX* i_end = vtxarg.data() + vtxarg.size(); + for (CLOTH_VERTEX* i = i_begin; i != i_end; i++) reset_data_list.push_back(i->reset_data); motion_reset_data.insert({ { motion_id, frame_int }, reset_data_list }); } -// 0x1402187D0 -void RobCloth::ApplyPhysics(bool ignore_friction) { - float_t fric = (1.0f - inertia) * (1.0f - skin_param_ptr->air_res); - - float_t osage_gravity = get_osage_gravity_const(); - - vec3 external_force = wind_direction * skin_param_ptr->wind_afc; - if (set_external_force) { - external_force += external_force; - osage_gravity = 0.0f; - } - - const size_t root_count = this->root_count; - const size_t nodes_count = this->nodes_count; - - float_t force = skin_param_ptr->force; - CLOTHNode* node = &nodes.data()[root_count]; - for (size_t i = 1; i < nodes_count; i++) { - RobClothRoot* root = this->root.data(); - for (size_t j = 0; j < root_count; j++, root++, node++) { - mat4 mat = root->mat; - - vec3 direction; - mat4_transform_vector(&mat, &node->direction, &direction); - - const float_t _fric = ignore_friction ? (node->delta_pos.y >= 0.0f ? 1.0f : 0.0f) : fric; - vec3 vel = direction * force - node->delta_pos * _fric + external_force; - vel.y -= osage_gravity; - node->delta_pos += vel; - - node->prev_pos = node->pos; - node->pos += node->delta_pos; - } - force *= skin_param_ptr->force_gain; - } -} - // 0x1402196D0 void RobCloth::ApplyResetData() { - const size_t root_count = this->root_count; - const size_t nodes_count = this->nodes_count; + const size_t width = this->width; + const size_t height = this->height; if (reset_data_list) { auto reset_data = this->reset_data_list->begin(); - CLOTHNode* i_begin = nodes.data() + root_count; - CLOTHNode* i_end = nodes.data() + nodes.size(); - for (CLOTHNode* i = i_begin; i != i_end; i++) + CLOTH_VERTEX* i_begin = vtxarg.data() + width; + CLOTH_VERTEX* i_end = vtxarg.data() + vtxarg.size(); + for (CLOTH_VERTEX* i = i_begin; i != i_end; i++) i->reset_data = *reset_data++; reset_data_list = 0; } - RobClothRoot* root = this->root.data(); - for (size_t i = 0; i < root_count; i++, root++) { - CLOTHNode* node = &nodes.data()[i + root_count]; - for (size_t j = 1; j < nodes_count; j++, node += root_count) { - mat4_transform_point(&root->mat_pos, &node->reset_data.pos, &node->pos); - mat4_transform_vector(&root->mat_pos, &node->reset_data.delta_pos, &node->delta_pos); - } - } -} - -void RobCloth::ColiSet(const mat4* transform) { - if (skin_param_ptr->coli.size()) - OsageCollision::Work::update_cls_work(coli_chara, skin_param_ptr->coli.data(), transform); - OsageCollision::Work::update_cls_work(coli_ring, ring.skp_root_coli, transform); -} - -// 0x14021AA60 -void RobCloth::CollideNodes(const float_t step, bool a3) { - const ssize_t root_count = this->root_count; - const size_t nodes_count = this->nodes_count; - - const float_t inv_step = 1.0f / step; - - const RobClothRoot* root = this->root.data(); - CLOTHNode* node = &nodes.data()[root_count]; - const float_t floor_height = ring.get_floor_height(node->pos, skin_param_ptr->coli_r); - - for (size_t i = 1; i < nodes_count; i++) { - for (ssize_t j = 0; j < root_count; j++, node++) { - float_t fric = (1.0f - inertia) * skin_param_ptr->friction; - if (step != 1.0f) { - vec3 delta_pos = node->pos - node->prev_pos; - - float_t trans_length = vec3::length(delta_pos); - if (trans_length * step > 0.0f && trans_length != 0.0f) - delta_pos *= 1.0f / trans_length; - - node->pos = node->prev_pos + delta_pos * (trans_length * step); - } - segment_limit_distance(node[0].pos, node[-root_count].pos, node[0].dist_top); - - int32_t hit = OsageCollision::osage_cls_work_list(node->pos, - skin_param_ptr->coli_r, ring.coli_object, &fric); - hit += OsageCollision::osage_cls(coli_ring, node->pos, skin_param_ptr->coli_r); - hit += OsageCollision::osage_cls(coli_chara, node->pos, skin_param_ptr->coli_r); - - if (floor_height > node->pos.y && floor_height < 1001.0f) { - node->pos.y = floor_height; - node->delta_pos = 0.0f; - } - - mat4 mat = root->mat; - mat4_set_translation(&mat, &node[-root_count].pos); - - int32_t yz_order = 1; - rotate_matrix_to_direction(mat, node->direction, 0, 0, yz_order); - - vec3 direction; - mat4_inverse_transform_point(&mat, &node->pos, &direction); - - rotate_matrix_to_direction(mat, direction, &skin_param_ptr->hinge, - &node->reset_data.rotation, yz_order); - mat4_mul_translate(&mat, node->dist_top, 0.0f, 0.0f, &mat); - mat4_get_translation(&mat, &node->pos); - - if (hit) - node->delta_pos *= fric; - - node->delta_pos = (node->pos - node->prev_pos) * inv_step; - - if (!a3) { - const mat4& inv_mat_pos = this->root.data()[j].inv_mat_pos; - mat4_transform_point(&inv_mat_pos, &node->pos, &node->reset_data.pos); - mat4_transform_vector(&inv_mat_pos, &node->delta_pos, &node->reset_data.delta_pos); - } - } - } -} - -// 0x14021D480 -void RobCloth::CtrlInitBegin() { - GetRootData(); - - const float_t osage_gravity_const = get_osage_gravity_const(); - - const ssize_t root_count = this->root_count; - const size_t nodes_count = this->nodes_count; - - CLOTHNode* node = &nodes.data()[root_count]; - const float_t floor_height = ring.get_floor_height(node->pos, skin_param_ptr->coli_r); - - for (size_t i = 1; i < nodes_count; i++) { - RobClothRoot* root = this->root.data(); - for (ssize_t j = 0; j < root_count; j++, root++, node++) { - mat4 mat = root->mat; - - vec3 v38; - mat4_transform_vector(&mat, &node->direction, &v38); - v38.y -= osage_gravity_const; - - node[0].pos = node[-root_count].pos + vec3::normalize(v38) * node->dist_top; - - OsageCollision::osage_cls_work_list(node->pos, skin_param_ptr->coli_r, ring.coli_object); - OsageCollision::osage_cls(coli_ring, node->pos, skin_param_ptr->coli_r); - OsageCollision::osage_cls(coli_chara, node->pos, skin_param_ptr->coli_r); - - if (floor_height > node->pos.y && floor_height < 1001.0f) - node->pos.y = floor_height; - - node->delta_pos = 0.0f; - node->prev_pos = node->pos; - } - } - - for (size_t i = 0; i < rob_cloth_iterations_count; ++i) - CtrlStep(1.0f); - - node = &nodes.data()[root_count]; - for (size_t i = 1; i < nodes_count; i++) - for (ssize_t j = 0; j < root_count; j++, node++) - node->delta_pos = 0.0f; -} - -// 0x14021D840 -void RobCloth::CtrlInitMain() { - CtrlMain(1.0f, true); -} - -// 0x140218560 -void RobCloth::CtrlMain(const float_t step, bool ignore_friction) { - GetRootData(); - - if (osage_reset) { - ApplyResetData(); - osage_reset = false; - } - - if (move_cancel > 0.0f) { - const size_t root_count = this->root_count; - const size_t nodes_count = this->nodes_count; - - float_t move_cancel = this->move_cancel; - for (size_t i = 0; i < root_count; i++) { - const mat4& mat_pos = root.data()[i].mat_pos; - CLOTHNode* node = &nodes.data()[i + root_count]; - for (size_t j = 1; j < nodes_count; j++, node += root_count) { - vec3 pos; - mat4_transform_point(&mat_pos, &node->reset_data.pos, &pos); - node->pos += (pos - node->pos) * move_cancel; - } - } - } - - if (step > 0.0f && !get_pause()) { - ApplyPhysics(ignore_friction); - NodesLimitDistance(); - CollideNodes(step, false); - - if (!ignore_friction) { - set_external_force = false; - external_force = 0.0f; + CLOTH_WEIGHTED_ROOT* root = this->root.data(); + for (size_t i = 0; i < width; i++, root++) { + CLOTH_VERTEX* vtx = &vtxarg.data()[i + width]; + for (size_t j = 1; j < height; j++, vtx += width) { + mat4_transform_point(&root->mat_pos, &vtx->reset_data.pos, &vtx->pos); + mat4_transform_vector(&root->mat_pos, &vtx->reset_data.vec, &vtx->vec); } } } // 0x140218E40 -void RobCloth::CtrlOsagePlayData(std::vector& opd_blend_data) { - GetRootData(); +void RobCloth::CtrlOsagePlayData(const std::vector& opd_blend_data) { + calc_root(); - ::opd_blend_data* i_begin = opd_blend_data.data() + opd_blend_data.size(); - ::opd_blend_data* i_end = opd_blend_data.data(); - for (::opd_blend_data* i = i_begin; i != i_end; ) { + const ::opd_blend_data* i_begin = opd_blend_data.data() + opd_blend_data.size(); + const ::opd_blend_data* i_end = opd_blend_data.data(); + for (const ::opd_blend_data* i = i_begin; i != i_end; ) { i--; float_t frame = i->frame; @@ -1471,23 +1304,23 @@ void RobCloth::CtrlOsagePlayData(std::vector& opd_blend_data) { float_t blend = frame - (float_t)(int64_t)frame; float_t inv_blend = 1.0f - blend; - for (size_t j = 0; j < root_count; j++) { - CLOTHNode& root_node = nodes.data()[j]; + for (size_t j = 0; j < width; j++) { + CLOTH_VERTEX& root_node = vtxarg.data()[j]; vec3 parent_trans = root_node.pos; mat4 mat = root.data()[j].mat; - mat4_mul_translate(&mat, &root_node.fixed_pos, &mat); + mat4_mul_translate(&mat, &root_node.org_pos, &mat); - CLOTHNode* v29 = &nodes.data()[j + root_count]; + CLOTH_VERTEX* v29 = &vtxarg.data()[j + width]; - vec3 direction; - mat4_transform_vector(&mat, &v29->direction, &direction); + vec3 localvec; + mat4_transform_vector(&mat, &v29->localvec, &localvec); - int32_t yz_order = 0; - rotate_matrix_to_direction(mat, direction, 0, 0, yz_order); + ROTTYPE rottype = ROTTYPE_YZ; + make_axis_matrix(mat, localvec, 0, 0, rottype); const mat4& mat_pos = root.data()[j].mat_pos; - for (size_t k = 1; k < nodes_count; k++, v29 += root_count) { + for (size_t k = 1; k < height; k++, v29 += width) { opd_vec3_data* opd = &v29->opd_data[i - i_end]; const float_t* opd_x = opd->x; const float_t* opd_y = opd->y; @@ -1508,36 +1341,36 @@ void RobCloth::CtrlOsagePlayData(std::vector& opd_blend_data) { vec3 _trans = curr_trans * inv_blend + next_trans * blend; - vec3 direction; - mat4_inverse_transform_point(&mat, &_trans, &direction); + vec3 localvec; + mat4_inverse_transform_point(&mat, &_trans, &localvec); vec3 rotation = 0.0f; - int32_t yz_order = 0; - rotate_matrix_to_direction(mat, direction, 0, &rotation, yz_order); + ROTTYPE rottype = ROTTYPE_YZ; + make_axis_matrix(mat, localvec, 0, &rotation, rottype); mat4_mul_translate(&mat, vec3::distance(_trans, parent_trans), 0.0f, 0.0f, &mat); - v29->opd_node_data.set_data(i, { v29->dist_top, rotation }); + v29->opd_node_data.set_data(i, { v29->length_up, rotation }); parent_trans = _trans; } } } - for (size_t i = 0; i < root_count; i++) { - CLOTHNode& root_node = nodes.data()[i]; + for (size_t i = 0; i < width; i++) { + CLOTH_VERTEX& root_node = vtxarg.data()[i]; mat4 mat = root.data()[i].mat; - mat4_mul_translate(&mat, &root_node.fixed_pos, &mat); + mat4_mul_translate(&mat, &root_node.org_pos, &mat); - CLOTHNode* v50 = &nodes.data()[i + root_count]; + CLOTH_VERTEX* v50 = &vtxarg.data()[i + width]; - vec3 direction; - mat4_transform_vector(&mat, &v50->direction, &direction); + vec3 localvec; + mat4_transform_vector(&mat, &v50->localvec, &localvec); - int32_t yz_order = 0; - rotate_matrix_to_direction(mat, direction, 0, 0, yz_order); + ROTTYPE rottype = ROTTYPE_YZ; + make_axis_matrix(mat, localvec, 0, 0, rottype); - for (size_t j = 1; j < nodes_count; j++, v50 += root_count) { + for (size_t j = 1; j < height; j++, v50 += width) { mat4_mul_rotate_z(&mat, v50->opd_node_data.curr.rotation.z, &mat); mat4_mul_rotate_y(&mat, v50->opd_node_data.curr.rotation.y, &mat); mat4_mul_translate(&mat, v50->opd_node_data.curr.length, 0.0f, 0.0f, &mat); @@ -1546,252 +1379,10 @@ void RobCloth::CtrlOsagePlayData(std::vector& opd_blend_data) { } } -// 0x14021DC60 -void RobCloth::CtrlStep(const float_t step) { - if (step <= 0.0f) - return; - - GetRootData(); - ApplyPhysics(true); - NodesLimitDistance(); - CollideNodes(step, true); -} - -void RobCloth::Disp(const mat4& mat, render_context* rctx) { - obj* obj = objset_info_storage_get_obj(itm_eq_obj->obj_info); - if (!obj) - return; - - std::vector* textures = objset_info_storage_get_obj_set_gentex(itm_eq_obj->obj_info.set_id); - - vec3 center = (nodes.data()[0].pos + nodes.data()[root_count * nodes_count - 1].pos) * 0.5f; - - ::obj o = *obj; - o.num_mesh = index_buffer[1].buffer != 0 ? 2 : 1; - o.mesh_array = mesh; - o.bounding_sphere.center = center; - o.bounding_sphere.radius *= 2.0f; - - for (int32_t i = 0; i < o.num_mesh; i++) { - obj_mesh& mesh = this->mesh[i]; - mesh.bounding_sphere.center = center; - for (int32_t j = 0; j < mesh.num_submesh; j++) { - obj_sub_mesh& submesh = mesh.submesh_array[j]; - submesh.bounding_sphere.center = center; - } - } - - rctx->disp_manager->set_texture_pattern((int32_t)itm_eq_obj->texture_pattern.size(), itm_eq_obj->texture_pattern.data()); - rctx->disp_manager->entry_obj_by_obj(mat, &o, textures, vertex_buffer, index_buffer, 0, itm_eq_obj->alpha); - rctx->disp_manager->set_texture_pattern(); -} - -// 0x140219940 -void RobCloth::GetRootData() { - for (size_t i = 0; i < root_count; i++) { - RobClothRoot& root = this->root.data()[i]; - CLOTHNode& root_node = nodes.data()[i]; - - mat4 m = mat4_null; - for (int32_t j = 0; j < 4; j++) { - if (!root.bone_mat[j] || !root.node_mat[j]) - continue; - - mat4 mat; - mat4_mul(root.bone_mat[j], root.node_mat[j], &mat); - - float_t weight = root.weight[j]; - mat4_mul_scale(&mat, weight, weight, weight, weight, &mat); - mat4_add(&m, &mat, &m); - } - root.mat = m; - - mat4_transform_point(&m, &root_node.fixed_pos, &root_node.pos); - mat4_transform_vector(&m, &root.normal, &root_node.normal); - mat4_transform_vector(&m, (vec3*)&root.tangent, &root_node.tangent); - root_node.tangent_sign = root.tangent.w; - root_node.prev_pos = root_node.pos; - - mat4_mul_translate(&m, &root_node.fixed_pos, &m); - root.mat_pos = m; - mat4_invert(&m, &m); - root.inv_mat_pos = m; - } -} - -void RobCloth::InitData(size_t root_count, size_t nodes_count, obj_skin_block_cloth_root* root, - obj_skin_block_cloth_node* nodes, mat4* mats, int32_t loop, - rob_chara_item_equip_object* itm_eq_obj, const bone_database* bone_data) { - this->itm_eq_obj = itm_eq_obj; - obj* obj = objset_info_storage_get_obj(itm_eq_obj->obj_info); - if (!obj) - return; - - obj_mesh_index_buffer* index_buffer = objset_info_storage_get_obj_mesh_index_buffer(itm_eq_obj->obj_info); - uint32_t mesh_name_index = obj->get_obj_mesh_index(cls_data->mesh_name); - uint32_t backface_mesh_name_index = obj->get_obj_mesh_index(cls_data->backface_mesh_name); - - mesh[0] = obj->mesh_array[mesh_name_index]; - if (cls_data->backface_mesh_name && backface_mesh_name_index != -1) - mesh[1] = obj->mesh_array[backface_mesh_name_index]; - else - mesh[1] = {}; - - for (int32_t i = 0; i < 2; i++) { - RobClothSubMeshArray& submesh = this->submesh[i]; - for (int32_t j = 0; j < mesh[i].num_submesh; j++) { - obj_sub_mesh& cloth_mesh = submesh.arr[j]; - cloth_mesh = mesh[i].submesh_array[j]; - cloth_mesh.attrib.m.cloth = 0; - cloth_mesh.bounding_sphere.radius = 1000.0f; - cloth_mesh.axis_aligned_bounding_box.center = 0.0f; - cloth_mesh.axis_aligned_bounding_box.size = { 1000.0f, 1000.0f, 1000.0f }; - mesh[i].submesh_array[j].attrib.m.cloth = 1; - } - mesh[i].submesh_array = submesh.arr; - mesh[i].bounding_sphere.radius = 1000.0f; - } - - this->index_buffer[0] = index_buffer[mesh_name_index]; - if (!vertex_buffer[0].load(mesh[0], GL::BUFFER_USAGE_STREAM)) - return; - - this->index_buffer[1] = {}; - if (cls_data->backface_mesh_name && backface_mesh_name_index != -1) - this->index_buffer[1] = index_buffer[backface_mesh_name_index]; - - if (cls_data->backface_mesh_name && !vertex_buffer[1].load(mesh[1], GL::BUFFER_USAGE_STREAM)) - return; - - flags = (((flags ^ (0x04 * loop)) & 0x04) ^ flags) | 0x03; - - this->root_count = root_count; - this->nodes_count = nodes_count; - this->cls_root = root; - this->mats = mats; - - this->root.clear(); - this->root.reserve(root_count); - - for (size_t i = 0; i < root_count; i++) { - this->root.push_back({}); - RobClothRoot& cls_root = this->root.back(); - cls_root.pos = root[i].pos; - cls_root.normal = root[i].normal; - for (int32_t j = 0; j < 4; j++) { - obj_skin_block_cloth_root_bone_weight& bone_weight = root[i].bone_weights[j]; - cls_root.node[j] = 0; - cls_root.node_mat[j] = 0; - cls_root.bone_mat[j] = &mats[bone_weight.matrix_index]; - if (bone_weight.bone_name) { - cls_root.node[j] = itm_eq_obj->get_bone_node(bone_weight.bone_name, bone_data); - if (cls_root.node[j]) - cls_root.node_mat[j] = cls_root.node[j]->mat; - } - cls_root.weight[j] = bone_weight.weight; - } - } - - this->nodes.clear(); - this->nodes.reserve(root_count); - - for (size_t i = 0; i < root_count; i++) { - this->nodes.push_back({}); - CLOTHNode& v55 = this->nodes.back(); - v55.pos = root[i].pos; - v55.fixed_pos = root[i].pos; - } - - std::vector index_array(root_count * nodes_count, 0); - uint16_t* mesh_index_array = cls_data->mesh_index_array; - for (size_t i = 0; i < cls_data->num_mesh_index; i++) - index_array.data()[mesh_index_array[i]] = i; - - obj_mesh* mesh = objset_info_storage_get_obj_mesh(itm_eq_obj->obj_info, cls_data->mesh_name); - obj_vertex_format vertex_format = (obj_vertex_format)0; - obj_vertex_data* vertex_array = 0; - if (mesh) { - vertex_format = mesh->vertex_format; - vertex_array = mesh->vertex_array; - } - - if (mesh && vertex_format - & (OBJ_VERTEX_TEXCOORD0 | OBJ_VERTEX_TANGENT | OBJ_VERTEX_NORMAL | OBJ_VERTEX_POSITION)) { - for (size_t i = 0; i < root_count; ++i) - this->root.data()[i].tangent = vertex_array[index_array.data()[i]].tangent; - } - - for (size_t i = 1; i < nodes_count; i++) - for (size_t j = 0; j < root_count; j++) { - this->nodes.push_back({}); - obj_skin_block_cloth_node& node = nodes[(i - 1) * root_count + j]; - CLOTHNode& v72 = this->nodes.back(); - v72.pos = node.pos; - v72.fixed_pos = node.pos; - v72.normal = { 0.0f, 0.0f, 1.0f }; - v72.tangent = { 1.0f, 0.0f, 0.0f }; - v72.delta_pos = node.delta_pos; - v72.direction = vec3::normalize(node.delta_pos); - v72.dist_top = node.dist_top; - v72.dist_bottom = node.dist_bottom; - v72.dist_right = node.dist_right; - v72.dist_left = node.dist_left; - v72.reset_data = {}; - - uint32_t flags = 0x00; - if (i) - flags |= 0x01; - if (i != nodes_count - 1) - flags |= 0x02; - if (j) - flags |= 0x04; - if (j != root_count - 1) - flags |= 0x08; - v72.flags = flags; - - if (mesh && vertex_format & OBJ_VERTEX_TEXCOORD0) - v72.texcoord = vertex_array[index_array.data()[i * root_count + j]].texcoord0; - } - - Init(); -} - -void RobCloth::InitDataParent(obj_skin_block_cloth* cls_data, - rob_chara_item_equip_object* itm_eq_obj, const bone_database* bone_data) { - ResetData(); - this->cls_data = cls_data; - InitData(cls_data->num_root, cls_data->num_node, cls_data->root_array, - cls_data->node_array, cls_data->mat_array, cls_data->loop, itm_eq_obj, bone_data); - - obj* obj = objset_info_storage_get_obj(itm_eq_obj->obj_info); - if (!obj) - return; - - for (int32_t i = 0; i < 2; i++) { - if (!mesh[i].num_vertex || !mesh[i].vertex_array || !index_buffer[i].buffer) - continue; - - obj_mesh_vertex_buffer* obj_vert_buf = &vertex_buffer[i]; - obj_mesh_index_buffer* obj_index_buf = &index_buffer[i]; - - obj_mesh* mesh = &this->mesh[i]; - for (int32_t j = 0; j < mesh->num_submesh; j++) { - obj_material_data* material = &obj->material_array[mesh->submesh_array[j].material_index]; - for (int32_t k = 0; k < (mesh->attrib.m.double_buffer ? 2 : 1); k++) { - extern render_context* rctx_ptr; - rctx_ptr->disp_manager->add_vertex_array(mesh, &mesh->submesh_array[j], material, - obj_vert_buf->get_buffer(), obj_vert_buf->get_offset(), obj_index_buf->buffer, 0, 0); - - obj_vert_buf->cycle_index(); - } - } - } -} - const float_t* RobCloth::LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count) { - CLOTHNode* i_begin = nodes.data() + root_count; - CLOTHNode* i_end = nodes.data() + nodes.size(); - for (CLOTHNode* i = i_begin; i != i_end; i++) { + CLOTH_VERTEX* i_begin = vtxarg.data() + width; + CLOTH_VERTEX* i_end = vtxarg.data() + vtxarg.size(); + for (CLOTH_VERTEX* i = i_begin; i != i_end; i++) { if (node_index >= i->opd_data.size()) i->opd_data.resize(node_index + 1); @@ -1813,119 +1404,31 @@ void RobCloth::LoadSkinParam(void* kv, const char* name, const bone_database* bo SetSkinParamOsageRoot(root); } -// 0x140219D10 -void RobCloth::NodesLimitDistance() { - CLOTHNode* node = nodes.data(); - const ssize_t root_count = this->root_count; - const size_t nodes_count = this->nodes_count; - - for (size_t i = nodes_count - 2; i; i--) { - CLOTHNode* v7 = &node[root_count * i]; - for (ssize_t j = 0; j < root_count; j++, v7++) - segment_limit_distance(v7->pos, v7[root_count].pos, v7->dist_bottom); - } - - if (nodes_count <= 1) - return; - - vec3* v11 = (vec3*)operator new(sizeof(vec3) * root_count); - vec3* v12 = (vec3*)operator new(sizeof(vec3) * root_count); - memset(v11, 0, sizeof(vec3) * root_count); - memset(v12, 0, sizeof(vec3) * root_count); - - vec3* v13 = &v11[root_count - 2]; - vec3* v14 = v12 + 1; - CLOTHNode* v15 = &node[root_count]; - CLOTHNode* v16 = &node[2 * root_count - 1]; - for (size_t i = nodes_count - 1; i; i--) { - if (root_count) { - vec3* v17 = v12; - vec3* v17a = v11; - CLOTHNode* v18 = v15; - for (ssize_t j = root_count; j > 0; j--, v17++, v17a++, v18++) { - *v17 = v18->pos; - *v17a = v18->pos; - } - } - - if (root_count - 2 >= 0) { - vec3* v20 = v13; - CLOTHNode* v22 = v16 - 1; - for (ssize_t j = root_count - 1; j > 0; j--, v20--, v22--) - segment_limit_distance(v20[0], v20[1], v22->dist_left); - v14 = v12 + 1; - } - - if (flags & 0x04) - segment_limit_distance(v11[root_count - 1], v11[0], v16->dist_right); - - if (root_count > 1) { - vec3* v23 = v14; - CLOTHNode* v24 = v15 + 1; - for (ssize_t j = root_count - 1; j > 0; j--, v23++, v24++) - segment_limit_distance(v23[0], v23[-1], v24->dist_right); - v14 = v12 + 1; - } - - if (flags & 0x04) - segment_limit_distance(v12[0], v12[root_count - 1], v15->dist_left); - - if (root_count > 0) { - vec3* v27 = v11; - vec3* v28 = v12; - CLOTHNode* v36 = v15; - for (ssize_t j = root_count; j > 0; j--, v27++, v28++, v36++) - v36->pos = (*v27 + *v28) * 0.5f; - } - v16 += root_count; - v15 += root_count; - } - - operator delete(v11); - operator delete(v12); -} - -void RobCloth::ResetExtrenalForce() { - set_external_force = false; - external_force = 0.0f; -} - -void RobCloth::SetForceAirRes(float_t force, float_t force_gain, float_t air_res) { - skin_param_ptr->force = force; - skin_param_ptr->force_gain = force_gain; - skin_param_ptr->air_res = air_res; -} - void RobCloth::SetMotionResetData(uint32_t motion_id, float_t frame) { osage_reset = true; auto elem = motion_reset_data.find({ motion_id, (int32_t)prj::roundf(frame * 1000.0f) }); - if (elem != motion_reset_data.end() && elem->second.size() + root_count == nodes.size()) { + if (elem != motion_reset_data.end() && elem->second.size() + width == vtxarg.size()) { this->reset_data_list = &elem->second; auto reset_data_list = this->reset_data_list->begin(); - CLOTHNode* i_begin = nodes.data() + root_count; - CLOTHNode* i_end = nodes.data() + nodes.size(); - for (CLOTHNode* i = i_begin; i != i_end; i++) + CLOTH_VERTEX* i_begin = vtxarg.data() + width; + CLOTH_VERTEX* i_end = vtxarg.data() + vtxarg.size(); + for (CLOTH_VERTEX* i = i_begin; i != i_end; i++) i->reset_data = *reset_data_list++; } } -// 0x14021EF50 -void RobCloth::SetMoveCancel(const float_t& value) { - move_cancel = value; -} - const float_t* RobCloth::SetOsagePlayDataInit(const float_t* opdi_data) { - CLOTHNode* i_begin = nodes.data() + root_count; - CLOTHNode* i_end = nodes.data() + nodes.size(); - for (CLOTHNode* i = i_begin; i != i_end; i++) { + CLOTH_VERTEX* i_begin = vtxarg.data() + width; + CLOTH_VERTEX* i_end = vtxarg.data() + vtxarg.size(); + for (CLOTH_VERTEX* i = i_begin; i != i_end; i++) { i->pos.x = *opdi_data++; i->pos.y = *opdi_data++; i->pos.z = *opdi_data++; - i->delta_pos.x = *opdi_data++; - i->delta_pos.y = *opdi_data++; - i->delta_pos.z = *opdi_data++; - i->prev_pos = i->pos; + i->vec.x = *opdi_data++; + i->vec.y = *opdi_data++; + i->vec.z = *opdi_data++; + i->old_pos = i->pos; } return opdi_data; } @@ -1943,350 +1446,749 @@ void RobCloth::SetSkinParam(skin_param_file_data* skp) { } void RobCloth::SetSkinParamOsageRoot(const skin_param_osage_root& skp_root) { - SetForceAirRes(skp_root.force, skp_root.force_gain, skp_root.air_res); - SetSkinParamFriction(skp_root.friction); - SetSkinParamWindAfc(skp_root.wind_afc); - SetSkinParamColiR(skp_root.coli_r); - SetSkinParamHinge(skp_root.hinge_y, skp_root.hinge_z); + set_param(skp_root.force, skp_root.force_gain, skp_root.air_res); + set_friction(skp_root.friction); + set_wind_affect(skp_root.wind_afc); + set_coli_r(skp_root.coli_r); + set_angle_limit(skp_root.hinge_y, skp_root.hinge_z); skin_param_ptr->coli.assign(skp_root.coli.begin(), skp_root.coli.end()); } -void RobCloth::UpdateDisp() { +// 0x14021DC60 +void RobCloth::calc(const float_t dt) { + if (dt <= 0.0f) + return; + + calc_root(); + calc_force(dt, true); + calc_stretch(); + calc_velocity(dt, true); +} + +// 0x1402187D0 +void RobCloth::calc_force(float_t time, bool init_flag) { + float_t fric = (1.0f - wet) * (1.0f - skin_param_ptr->air_res); + + float_t osage_gravity = get_gravity(); + + vec3 ex_force = wind_dir * skin_param_ptr->wind_afc; + if (use_ex_force) { + ex_force += this->ex_force; + osage_gravity = 0.0f; + } + + const size_t width = this->width; + const size_t height = this->height; + + float_t force = skin_param_ptr->force; + CLOTH_VERTEX* vtx = &vtxarg.data()[width]; + for (size_t i = 1; i < height; i++) { + CLOTH_WEIGHTED_ROOT* root = this->root.data(); + for (size_t j = 0; j < width; j++, root++, vtx++) { + mat4 mat = root->mat; + + vec3 localvec; + mat4_transform_vector(&mat, &vtx->localvec, &localvec); + + const float_t _fric = dbg_init_flag || init_flag ? (vtx->vec.y >= 0.0f ? 1.0f : 0.0f) : fric; + vec3 vel = localvec * force - vtx->vec * _fric + ex_force; + vel.y -= osage_gravity; + vtx->vec += vel; + + vtx->old_pos = vtx->pos; + vtx->pos += vtx->vec; + } + force *= skin_param_ptr->force_gain; + } +} + +// 0x140218B40 +void RobCloth::calc_normal() { + const ssize_t width = this->width; + CLOTH_VERTEX* vtx = &vtxarg.data()[width]; + if (calc_normal_flag) { + for (size_t i = 1; i < height - 1; i++) { + calc_tangent_basis_sub(vtx, vtx, vtx + 1, &vtx[-width], &vtx[width]); + vtx++; + for (ssize_t j = 1; j < width - 1; j++, vtx++) + calc_tangent_basis_sub(vtx, vtx - 1, vtx + 1, &vtx[-width], &vtx[width]); + calc_tangent_basis_sub(vtx, vtx - 1, vtx, &vtx[-width], &vtx[width]); + vtx++; + } + + calc_tangent_basis_sub(vtx, vtx, vtx + 1, &vtx[-width], vtx); + vtx++; + + for (ssize_t i = 1; i < width - 1; i++, vtx++) + calc_tangent_basis_sub(vtx, vtx - 1, vtx + 1, &vtx[-width], vtx); + calc_tangent_basis_sub(vtx, vtx - 1, vtx, &vtx[-width], vtx); + } + else + for (size_t i = 1; i < height; i++, vtx++) { + for (ssize_t j = 0; j < width - 1; j++, vtx++) { + vtx[0].m = calc_tangent_basis( + vtx[0].pos, vtx[-width].pos, vtx[1].pos, + vtx[0].uv, vtx[-width].uv, vtx[1].uv, + vtx[0].tangent, vtx[0].binormal, vtx[0].normal); + } + vtx[0].normal = vtx[-1].normal; + vtx[0].tangent = vtx[-1].tangent; + vtx[0].binormal = vtx[-1].binormal; + vtx[0].m = vtx[-1].m; + } +} + +// 0x140219940 +void RobCloth::calc_root() { + for (size_t i = 0; i < width; i++) { + CLOTH_WEIGHTED_ROOT& root = this->root.data()[i]; + CLOTH_VERTEX& root_node = vtxarg.data()[i]; + + mat4 m = mat4_null; + for (int32_t j = 0; j < 4; j++) { + if (!root.bone_mat[j] || !root.node_mat[j]) + continue; + + mat4 mat; + mat4_mul(root.bone_mat[j], root.node_mat[j], &mat); + + float_t weight = root.weight[j]; + mat4_mul_scale(&mat, weight, weight, weight, weight, &mat); + mat4_add(&m, &mat, &m); + } + root.mat = m; + + mat4_transform_point(&m, &root_node.org_pos, &root_node.pos); + mat4_transform_vector(&m, &root.normal, &root_node.normal); + mat4_transform_vector(&m, (vec3*)&root.tangent, &root_node.tangent); + root_node.m = root.tangent.w; + root_node.old_pos = root_node.pos; + + mat4_mul_translate(&m, &root_node.org_pos, &m); + root.mat_pos = m; + mat4_invert(&m, &m); + root.inv_mat_pos = m; + } +} + +// 0x140219D10 +void RobCloth::calc_stretch() { + CLOTH_VERTEX* vtx = vtxarg.data(); + const ssize_t width = this->width; + const size_t height = this->height; + + for (size_t i = height - 2; i; i--) { + CLOTH_VERTEX* v7 = &vtx[width * i]; + for (ssize_t j = 0; j < width; j++, v7++) + length_limit(v7->pos, v7[width].pos, v7->length_down); + } + + if (height <= 1) + return; + + vec3* v11 = (vec3*)operator new(sizeof(vec3) * width); + vec3* v12 = (vec3*)operator new(sizeof(vec3) * width); + memset(v11, 0, sizeof(vec3) * width); + memset(v12, 0, sizeof(vec3) * width); + + vec3* v13 = &v11[width - 2]; + vec3* v14 = v12 + 1; + CLOTH_VERTEX* v15 = &vtx[width]; + CLOTH_VERTEX* v16 = &vtx[2 * width - 1]; + for (size_t i = height - 1; i; i--) { + if (width) { + vec3* v17 = v12; + vec3* v17a = v11; + CLOTH_VERTEX* v18 = v15; + for (ssize_t j = width; j > 0; j--, v17++, v17a++, v18++) { + *v17 = v18->pos; + *v17a = v18->pos; + } + } + + if (width - 2 >= 0) { + vec3* v20 = v13; + CLOTH_VERTEX* v22 = v16 - 1; + for (ssize_t j = width - 1; j > 0; j--, v20--, v22--) + length_limit(v20[0], v20[1], v22->length_right); + v14 = v12 + 1; + } + + if (flag.ring) + length_limit(v11[width - 1], v11[0], v16->length_left); + + if (width > 1) { + vec3* v23 = v14; + CLOTH_VERTEX* v24 = v15 + 1; + for (ssize_t j = width - 1; j > 0; j--, v23++, v24++) + length_limit(v23[0], v23[-1], v24->length_left); + v14 = v12 + 1; + } + + if (flag.ring) + length_limit(v12[0], v12[width - 1], v15->length_right); + + if (width > 0) { + vec3* v27 = v11; + vec3* v28 = v12; + CLOTH_VERTEX* v36 = v15; + for (ssize_t j = width; j > 0; j--, v27++, v28++, v36++) + v36->pos = (*v27 + *v28) * 0.5f; + } + v16 += width; + v15 += width; + } + + operator delete(v11); + operator delete(v12); +} + +// 0x14021AA60 +void RobCloth::calc_velocity(const float_t dt, bool a3) { + const ssize_t width = this->width; + const size_t height = this->height; + + const float_t inv_dt = 1.0f / dt; + + const CLOTH_WEIGHTED_ROOT* root = this->root.data(); + CLOTH_VERTEX* vtx = &vtxarg.data()[width]; + const float_t floor_height = ring.get_floor_height(vtx->pos, skin_param_ptr->coli_r); + + for (size_t i = 1; i < height; i++) { + for (ssize_t j = 0; j < width; j++, vtx++) { + float_t fric = (1.0f - wet) * skin_param_ptr->friction; + if (dt != 1.0f) { + vec3 vec = vtx->pos - vtx->old_pos; + + float_t trans_length = vec3::length(vec); + if (trans_length * dt > 0.0f && trans_length != 0.0f) + vec *= 1.0f / trans_length; + + vtx->pos = vtx->old_pos + vec * (trans_length * dt); + } + + length_limit(vtx[0].pos, vtx[-width].pos, vtx[0].length_up); + + int32_t hit = OsageCollision::osage_cls_work_list(vtx->pos, + skin_param_ptr->coli_r, ring.coli_object, &fric); + hit += OsageCollision::osage_cls(coli_ring, vtx->pos, skin_param_ptr->coli_r); + hit += OsageCollision::osage_cls(coli_chara, vtx->pos, skin_param_ptr->coli_r); + + if (floor_height > vtx->pos.y && floor_height < 1001.0f) { + vtx->pos.y = floor_height; + vtx->vec = 0.0f; + } + + mat4 mat = root->mat; + mat4_set_translation(&mat, &vtx[-width].pos); + + ROTTYPE rottype = ROTTYPE_ZY; + make_axis_matrix(mat, vtx->localvec, 0, 0, rottype); + + vec3 localvec; + mat4_inverse_transform_point(&mat, &vtx->pos, &localvec); + + make_axis_matrix(mat, localvec, &skin_param_ptr->hinge, + &vtx->reset_data.rotation, rottype); + mat4_mul_translate(&mat, vtx->length_up, 0.0f, 0.0f, &mat); + mat4_get_translation(&mat, &vtx->pos); + + if (hit) + vtx->vec *= fric; + + vtx->vec = (vtx->pos - vtx->old_pos) * inv_dt; + + if (!a3) { + const mat4& inv_mat_pos = this->root.data()[j].inv_mat_pos; + mat4_transform_point(&inv_mat_pos, &vtx->pos, &vtx->reset_data.pos); + mat4_transform_vector(&inv_mat_pos, &vtx->vec, &vtx->reset_data.vec); + } + } + } +} + +// 0x140218560 +void RobCloth::ctrl(const float_t dt, bool init_flag) { + calc_root(); + + if (osage_reset) { + ApplyResetData(); + osage_reset = false; + } + + if (move_cancel > 0.0f) { + const size_t width = this->width; + const size_t height = this->height; + + float_t move_cancel = this->move_cancel; + for (size_t i = 0; i < width; i++) { + const mat4& mat_pos = root.data()[i].mat_pos; + CLOTH_VERTEX* vtx = &vtxarg.data()[i + width]; + for (size_t j = 1; j < height; j++, vtx += width) { + vec3 pos; + mat4_transform_point(&mat_pos, &vtx->reset_data.pos, &pos); + vtx->pos += (pos - vtx->pos) * move_cancel; + } + } + } + + if (dt > 0.0f && !get_pause()) { + calc_force(dt, init_flag); + calc_stretch(); + calc_velocity(dt, false); + + if (!init_flag) { + use_ex_force = false; + ex_force = 0.0f; + } + } +} + +// 0x14021B930 +void RobCloth::disp(const mat4& mat, render_context* rctx) { + obj* obj = objset_info_storage_get_obj(skin_disp->obj_info); + if (!obj) + return; + + std::vector* textures = objset_info_storage_get_obj_set_gentex(skin_disp->obj_info.set_id); + + vec3 center = (vtxarg.data()[0].pos + vtxarg.data()[width * height - 1].pos) * 0.5f; + + ::obj o = *obj; + o.num_mesh = ib[1].buffer != 0 ? 2 : 1; + o.mesh_array = mesh; + o.bounding_sphere.center = center; + o.bounding_sphere.radius *= 2.0f; + + for (int32_t i = 0; i < o.num_mesh; i++) { + obj_mesh& mesh = this->mesh[i]; + mesh.bounding_sphere.center = center; + for (int32_t j = 0; j < mesh.num_submesh; j++) { + obj_sub_mesh& submesh = mesh.submesh_array[j]; + submesh.bounding_sphere.center = center; + } + } + + rctx->disp_manager->set_texture_pattern((int32_t)skin_disp->texchg_vec.size(), skin_disp->texchg_vec.data()); + rctx->disp_manager->entry_obj_by_obj(mat, &o, textures, vb, ib, 0, skin_disp->alpha); + rctx->disp_manager->set_texture_pattern(); +} + +// 0x14021D330 +void RobCloth::modify_obj() { if (pv_osage_manager_array_get_disp()) return; - if (rob_cloth_update_vertices_flags & 0x01) - UpdateNormals(); + if (cloth_modify_flag & 0x01) + calc_normal(); - if (rob_cloth_update_vertices_flags & 0x02) { - obj_mesh* mesh = objset_info_storage_get_obj_mesh(itm_eq_obj->obj_info, cls_data->mesh_name); - obj_mesh* backface_mesh = objset_info_storage_get_obj_mesh(itm_eq_obj->obj_info, cls_data->backface_mesh_name); - if (cls_data->backface_mesh_name) { - UpdateVertexBuffer(mesh, &vertex_buffer[0], nodes.data(), - 1.0f, cls_data->num_mesh_index, cls_data->mesh_index_array, false); - UpdateVertexBuffer(backface_mesh, &vertex_buffer[1], nodes.data(), - -1.0f, cls_data->num_backface_mesh_index, cls_data->backface_mesh_index_array, false); + if (cloth_modify_flag & 0x02) { + obj_mesh* omote_mesh = objset_info_storage_get_obj_mesh(skin_disp->obj_info, data->omote_name); + obj_mesh* ura_mesh = objset_info_storage_get_obj_mesh(skin_disp->obj_info, data->ura_name); + if (data->ura_name) { + modify_cloth_object(omote_mesh, &vb[0], vtxarg.data(), + 1.0f, data->num_omote_index, data->omote_index_array, false); + modify_cloth_object(ura_mesh, &vb[1], vtxarg.data(), + -1.0f, data->num_ura_index, data->ura_index_array, false); } else - UpdateVertexBuffer(mesh, &vertex_buffer[0], nodes.data(), - 1.0, cls_data->num_mesh_index, cls_data->mesh_index_array, true); + modify_cloth_object(omote_mesh, &vb[0], vtxarg.data(), + 1.0, data->num_omote_index, data->omote_index_array, true); } } -void RobCloth::UpdateNormals() { - const ssize_t root_count = this->root_count; - CLOTHNode* node = &nodes.data()[root_count]; - if (rob_cloth_update_normals_select) { - for (size_t i = 1; i < nodes_count - 1; i++) { - node->CalculateTBN(node, node + 1, &node[-root_count], &node[root_count]); - node++; - for (ssize_t j = 1; j < root_count - 1; j++, node++) - node->CalculateTBN(node - 1, node + 1, &node[-root_count], &node[root_count]); - node->CalculateTBN(node - 1, node, &node[-root_count], &node[root_count]); - node++; - } +// 0x14021E460 +void RobCloth::set_data(size_t w, size_t h, const obj_skin_ex_node_cloth_root * rt_data, + const obj_skin_ex_node_cloth_point* move, const mat4* lcl_mat, uint32_t ring_flag, + const rob_chara_item_equip_object* skin, const bone_database* bone_data) { + skin_disp = skin; - node->CalculateTBN(node, node + 1, &node[-root_count], node); - node++; + obj* obj = objset_info_storage_get_obj(skin_disp->obj_info); + if (!obj) + return; - for (ssize_t i = 1; i < root_count - 1; i++, node++) - node->CalculateTBN(node - 1, node + 1, &node[-root_count], node); - node->CalculateTBN(node - 1, node, &node[-root_count], node); - } + obj_mesh_index_buffer* ib = objset_info_storage_get_obj_mesh_index_buffer(skin_disp->obj_info); + uint32_t omotea_mesh_index = obj->get_obj_mesh_index(data->omote_name); + uint32_t ura_mesh_index = obj->get_obj_mesh_index(data->ura_name); + + mesh[0] = obj->mesh_array[omotea_mesh_index]; + if (data->ura_name && ura_mesh_index != -1) + mesh[1] = obj->mesh_array[ura_mesh_index]; else - for (size_t i = 1; i < nodes_count; i++, node++) { - for (ssize_t j = 0; j < root_count - 1; j++, node++) { - node[0].tangent_sign = calculate_tbn( - node[0].pos, node[-root_count].pos, node[1].pos, - node[0].texcoord, node[-root_count].texcoord, node[1].texcoord, - node[0].tangent, node[0].binormal, node[0].normal); - } - node[0].normal = node[-1].normal; - node[0].tangent = node[-1].tangent; - node[0].binormal = node[-1].binormal; - node[0].tangent_sign = node[-1].tangent_sign; + mesh[1] = {}; + + for (int32_t i = 0; i < 2; i++) { + for (int32_t j = 0; j < mesh[i].num_submesh; j++) { + obj_sub_mesh& cloth_mesh = submesh[i][j]; + cloth_mesh = mesh[i].submesh_array[j]; + cloth_mesh.attrib.m.cloth = 0; + cloth_mesh.bounding_sphere.radius = 1000.0f; + cloth_mesh.axis_aligned_bounding_box.center = 0.0f; + cloth_mesh.axis_aligned_bounding_box.size = { 1000.0f, 1000.0f, 1000.0f }; + mesh[i].submesh_array[j].attrib.m.cloth = 1; } -} - -void RobCloth::UpdateVertexBuffer(obj_mesh* mesh, obj_mesh_vertex_buffer* vertex_buffer, - CLOTHNode* nodes, float_t facing, int32_t indices_count, uint16_t* indices, bool double_sided) { - if (!mesh || !vertex_buffer || (mesh->vertex_format - & (OBJ_VERTEX_NORMAL | OBJ_VERTEX_POSITION)) != (OBJ_VERTEX_NORMAL | OBJ_VERTEX_POSITION)) - return; - - vertex_buffer->cycle_index(); - GL::ArrayBuffer buffer = vertex_buffer->get_buffer(); - size_t data = (size_t)buffer.MapMemory(gl_state); - if (!data) - return; - - if (double_sided) - indices_count /= 2; - - bool tangent = !!(mesh->vertex_format & OBJ_VERTEX_TANGENT); - - switch (mesh->attrib.m.compression) { - case 0: - default: - if (tangent) - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; - - *(vec3*)data = node->pos; - *(vec3*)(data + 0x0C) = node->normal * facing; - *(vec3*)(data + 0x18) = node->tangent; - *(float_t*)(data + 0x24) = node->tangent_sign; - - data += mesh->size_vertex; - } - - if (!double_sided) - break; - } - else - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; - - *(vec3*)data = node->pos; - *(vec3*)(data + 0x0C) = node->normal * facing; - - data += mesh->size_vertex; - } - - if (!double_sided) - break; - } - break; - case 1: - if (tangent) - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; - - *(vec3*)data = node->pos; - - vec3_to_vec3i16(node->normal * (32767.0f * facing), *(vec3i16*)(data + 0x0C)); - *(int16_t*)(data + 0x12) = 0; - - vec4 tangent; - *(vec3*)&tangent = node->tangent; - tangent.w = node->tangent_sign; - vec4_to_vec4i16(tangent * 32767.0f, *(vec4i16*)(data + 0x14)); - - data += mesh->size_vertex; - } - - if (!double_sided) - break; - } - else - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; - - *(vec3*)data = node->pos; - - vec3_to_vec3i16(node->normal * (32767.0f * facing), *(vec3i16*)(data + 0x0C)); - *(int16_t*)(data + 0x12) = 0; - - data += mesh->size_vertex; - } - - if (!double_sided) - break; - } - case 2: - if (tangent) - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; - - *(vec3*)data = node->pos; - - vec3i16 normal_int; - vec3_to_vec3i16(node->normal * 511.0f, normal_int); - *(uint32_t*)(data + 0x0C) = (((uint32_t)0 & 0x03) << 30) - | (((uint32_t)normal_int.z & 0x3FF) << 20) - | (((uint32_t)normal_int.y & 0x3FF) << 10) - | ((uint32_t)normal_int.x & 0x3FF); - - vec4 tangent; - *(vec3*)&tangent = node->tangent; - tangent.w = node->tangent_sign; - - vec4i16 tangent_int; - vec4_to_vec4i16(tangent * 511.0f, tangent_int); - *(uint32_t*)(data + 0x10) = (((uint32_t)clamp_def(tangent_int.w, -1, 1) & 0x03) << 30) - | (((uint32_t)tangent_int.z & 0x3FF) << 20) - | (((uint32_t)tangent_int.y & 0x3FF) << 10) - | ((uint32_t)tangent_int.x & 0x3FF); - - data += mesh->size_vertex; - } - - if (!double_sided) - break; - } - else - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; - - *(vec3*)data = node->pos; - - vec3i16 normal_int; - vec3_to_vec3i16(node->normal * 511.0f, normal_int); - *(uint32_t*)(data + 0x0C) = (((uint32_t)0 & 0x03) << 30) - | (((uint32_t)normal_int.z & 0x3FF) << 20) - | (((uint32_t)normal_int.y & 0x3FF) << 10) - | ((uint32_t)normal_int.x & 0x3FF); - - data += mesh->size_vertex; - } - - if (!double_sided) - break; - } - break; + mesh[i].submesh_array = submesh[i]; + mesh[i].bounding_sphere.radius = 1000.0f; } - buffer.UnmapMemory(gl_state); + this->ib[0] = ib[omotea_mesh_index]; + if (!vb[0].load(mesh[0], GL::BUFFER_USAGE_STREAM)) + return; + + this->ib[1] = {}; + if (data->ura_name && ura_mesh_index != -1) + this->ib[1] = ib[ura_mesh_index]; + + if (data->ura_name && !vb[1].load(mesh[1], GL::BUFFER_USAGE_STREAM)) + return; + + flag.exec = 1; + flag.disp = 1; + flag.ring = ring_flag; + + this->width = w; + this->height = h; + this->root_data = rt_data; + this->local_mat = lcl_mat; + + this->root.clear(); + this->root.reserve(w); + + for (size_t i = 0; i < w; i++) { + this->root.push_back({}); + CLOTH_WEIGHTED_ROOT& root = this->root.back(); + root.pos = rt_data[i].pos; + root.normal = rt_data[i].normal; + for (int32_t j = 0; j < 4; j++) { + const obj_skin_ex_node_cloth_weight& weight = rt_data[i].weight[j]; + root.node[j] = 0; + root.node_mat[j] = 0; + root.bone_mat[j] = &lcl_mat[weight.mat_idx]; + if (weight.bone_name) { + root.node[j] = skin->get_node(weight.bone_name, bone_data); + if (root.node[j]) + root.node_mat[j] = root.node[j]->mat_ptr; + } + root.weight[j] = weight.weight; + } + } + + this->vtxarg.clear(); + this->vtxarg.reserve(w); + + for (size_t i = 0; i < w; i++) { + this->vtxarg.push_back({}); + CLOTH_VERTEX& vtx = this->vtxarg.back(); + vtx.pos = root[i].pos; + vtx.org_pos = root[i].pos; + } + + std::vector index_array(w * h, 0); + uint16_t* omote_index_array = data->omote_index_array; + for (size_t i = 0; i < data->num_omote_index; i++) + index_array.data()[omote_index_array[i]] = i; + + obj_mesh* mesh = objset_info_storage_get_obj_mesh(skin_disp->obj_info, data->omote_name); + obj_vertex_format vertex_format = (obj_vertex_format)0; + obj_vertex_data* vertex_array = 0; + if (mesh) { + vertex_format = mesh->vertex_format; + vertex_array = mesh->vertex_array; + } + + if (mesh && vertex_format + & (OBJ_VERTEX_TEXCOORD0 | OBJ_VERTEX_TANGENT | OBJ_VERTEX_NORMAL | OBJ_VERTEX_POSITION)) { + for (size_t i = 0; i < w; ++i) + this->root.data()[i].tangent = vertex_array[index_array.data()[i]].tangent; + } + + for (size_t i = 1; i < h; i++) + for (size_t j = 0; j < w; j++) { + this->vtxarg.push_back({}); + const obj_skin_ex_node_cloth_point& mv = move[(i - 1) * w + j]; + CLOTH_VERTEX& vtx = this->vtxarg.back(); + vtx.pos = mv.pos; + vtx.org_pos = mv.pos; + vtx.normal = { 0.0f, 0.0f, 1.0f }; + vtx.tangent = { 1.0f, 0.0f, 0.0f }; + vtx.vec = mv.vec; + vtx.localvec = vec3::normalize(mv.vec); + vtx.length_up = mv.length[0]; + vtx.length_down = mv.length[1]; + vtx.length_left = mv.length[2]; + vtx.length_right = mv.length[3]; + vtx.reset_data = {}; + + uint32_t flag = 0x00; + if (i) + flag |= 0x01; + if (i != h - 1) + flag |= 0x02; + if (j) + flag |= 0x04; + if (j != w - 1) + flag |= 0x08; + vtx.flag = flag; + + if (mesh && vertex_format & OBJ_VERTEX_TEXCOORD0) + vtx.uv = vertex_array[index_array.data()[i * w + j]].texcoord0; + } + + set_spring(); +} + +// 0x14021EEB0 +void RobCloth::set_data(const obj_skin_ex_node_cloth* cldata, + const rob_chara_item_equip_object* skin, const bone_database* bone_data) { + dest(); + data = cldata; + set_data(cldata->width, cldata->height, cldata->fix_point, + cldata->move_point, cldata->mat_array, cldata->ring_flag, skin, bone_data); + + obj* obj = objset_info_storage_get_obj(skin->obj_info); + if (!obj) + return; + + for (int32_t i = 0; i < 2; i++) { + if (!mesh[i].num_vertex || !mesh[i].vertex_array || !ib[i].buffer) + continue; + + obj_mesh_vertex_buffer* obj_vert_buf = &vb[i]; + obj_mesh_index_buffer* obj_index_buf = &ib[i]; + + obj_mesh* mesh = &this->mesh[i]; + for (int32_t j = 0; j < mesh->num_submesh; j++) { + obj_material_data* material = &obj->material_array[mesh->submesh_array[j].material_index]; + for (int32_t k = 0; k < (mesh->attrib.m.double_buffer ? 2 : 1); k++) { + extern render_context* rctx_ptr; + rctx_ptr->disp_manager->add_vertex_array(mesh, &mesh->submesh_array[j], material, + obj_vert_buf->get_buffer(), obj_vert_buf->get_offset(), obj_index_buf->buffer, 0, 0); + + obj_vert_buf->cycle_index(); + } + } + } +} + +// 0x14021EF20 +void RobCloth::set_ex_force(const vec3& f) { + use_ex_force = true; + ex_force = f; +} + +// 0x14021EF50 +void RobCloth::set_move_cancel(const float_t& mv_ccl) { + move_cancel = mv_ccl; +} + +// 0x14021FD00 +void RobCloth::make_osage_coli(const mat4* motmat) { + if (skin_param_ptr->coli.size()) + OsageCollision::Work::update_cls_work(coli_chara, skin_param_ptr->coli.data(), motmat); + OsageCollision::Work::update_cls_work(coli_ring, ring.skp_root_coli, motmat); +} + +// 0x14021D480 +void RobCloth::pos_init() { + calc_root(); + + const float_t gravity = get_gravity(); + + const ssize_t width = this->width; + const size_t height = this->height; + + CLOTH_VERTEX* vtx = &vtxarg.data()[width]; + const float_t floor_height = ring.get_floor_height(vtx->pos, skin_param_ptr->coli_r); + + for (size_t i = 1; i < height; i++) { + CLOTH_WEIGHTED_ROOT* root = this->root.data(); + for (ssize_t j = 0; j < width; j++, root++, vtx++) { + mat4 mat = root->mat; + + vec3 v38; + mat4_transform_vector(&mat, &vtx->localvec, &v38); + v38.y -= gravity; + + vtx[0].pos = vtx[-width].pos + vec3::normalize(v38) * vtx->length_up; + + OsageCollision::osage_cls_work_list(vtx->pos, skin_param_ptr->coli_r, ring.coli_object); + OsageCollision::osage_cls(coli_ring, vtx->pos, skin_param_ptr->coli_r); + OsageCollision::osage_cls(coli_chara, vtx->pos, skin_param_ptr->coli_r); + + if (floor_height > vtx->pos.y && floor_height < 1001.0f) + vtx->pos.y = floor_height; + + vtx->vec = 0.0f; + vtx->old_pos = vtx->pos; + } + } + + for (size_t i = 0; i < cloth_init_cnt; ++i) + calc(1.0f); + + vtx = &vtxarg.data()[width]; + for (size_t i = 1; i < height; i++) + for (ssize_t j = 0; j < width; j++, vtx++) + vtx->vec = 0.0f; +} + +// 0x14021D840 +void RobCloth::pos_init_cont() { + ctrl(1.0f, true); +} + +void RobCloth::reset_ex_force() { + use_ex_force = false; + ex_force = 0.0f; +} + +void RobCloth::set_param(float_t force, float_t force_gain, float_t air_res) { + skin_param_ptr->force = force; + skin_param_ptr->force_gain = force_gain; + skin_param_ptr->air_res = air_res; } ExClothBlock::ExClothBlock() { - Init(); + init(); } ExClothBlock::~ExClothBlock() { } -void ExClothBlock::Init() { - rob.Reset(); - cls_data = 0; - mats = 0; - index = 0; +void ExClothBlock::init() { + cloth_work.init(); + data = 0; + motion_matrix = 0; + block_idx = 0; } void ExClothBlock::CtrlBegin() { done = false; } -void ExClothBlock::CtrlStep(int32_t stage, bool disable_external_force) { +void ExClothBlock::CtrlStep(int32_t stage, bool disable_ex_force) { } -void ExClothBlock::CtrlMain() { - ColiSet(); +void ExClothBlock::ctrl() { + set_param(); - rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; + const rob_chara_item_equip* rob_disp = skin_disp->rob_disp; float_t delta_frame = get_delta_frame(); #if OPD_PLAY_GEN if (opd_play_gen_run) delta_frame = 1.0f; #endif - float_t step = delta_frame * rob_itm_equip->osage_step; - if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data.front().use_blend) + float_t step = delta_frame * rob_disp->osage_step; + if (rob_disp->opd_blend_data.size() && rob_disp->opd_blend_data.front().use_blend) step = 1.0f; - rob.CtrlMain(step, false); + cloth_work.ctrl(step, false); } void ExClothBlock::CtrlOsagePlayData() { - rob.CtrlOsagePlayData(item_equip_object->item_equip->opd_blend_data); + cloth_work.CtrlOsagePlayData(skin_disp->rob_disp->opd_blend_data); } -void ExClothBlock::Disp(const mat4& mat, render_context* rctx) { - rob.UpdateDisp(); - rob.Disp(mat, rctx); +void ExClothBlock::disp(const mat4& mat, render_context* rctx) { + cloth_work.modify_obj(); + cloth_work.disp(mat, rctx); } -void ExClothBlock::Reset() { - rob.ResetData(); - bone_node_ptr = 0; +void ExClothBlock::dest() { + cloth_work.dest(); + dst_node = 0; } -void ExClothBlock::Field_40() { +void ExClothBlock::disp_debug() { } -void ExClothBlock::CtrlInitBegin() { - ColiSet(); - rob.CtrlInitBegin(); +void ExClothBlock::pos_init() { + set_param(); + cloth_work.pos_init(); } -void ExClothBlock::CtrlInitMain() { - ColiSet(); - rob.CtrlInitMain(); +void ExClothBlock::pos_init_cont() { + set_param(); + cloth_work.pos_init_cont(); } void ExClothBlock::AddMotionResetData(uint32_t motion_id, float_t frame) { - rob.AddMotionResetData(motion_id, frame); -} - -void ExClothBlock::ColiSet() { - rob.ColiSet(mats); - rob.SetWindDirection(task_wind->ptr->wind_direction); -} - -void ExClothBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, - obj_skin_block_cloth* cls_data, skin_param_osage_root* skp_root, const bone_database* bone_data) { - type = EX_CLOTH; - bone_node_ptr = 0; - this->cls_data = cls_data; - name = skp_root ? skp_root->name : 0; - item_equip_object = itm_eq_obj; - - mats = itm_eq_obj->get_bone_node(0)->mat; - rob.ResetData(); - rob.InitDataParent(cls_data, itm_eq_obj, bone_data); - SetSkinParamOsageRoot(skp_root); + cloth_work.AddMotionResetData(motion_id, frame); } const float_t* ExClothBlock::LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count) { - return rob.LoadOpdData(node_index, opd_data, opd_count); + return cloth_work.LoadOpdData(node_index, opd_data, opd_count); } void ExClothBlock::SetMotionResetData(uint32_t motion_id, float_t frame) { - rob.SetMotionResetData(motion_id, frame); -} - -// 0x1405F9280 -void ExClothBlock::SetMoveCancel(const float_t& value) { - rob.SetMoveCancel(value); + cloth_work.SetMotionResetData(motion_id, frame); } const float_t* ExClothBlock::SetOsagePlayDataInit(const float_t* opdi_data) { - return rob.SetOsagePlayDataInit(opdi_data); + return cloth_work.SetOsagePlayDataInit(opdi_data); } void ExClothBlock::SetOsageReset() { - rob.SetOsageReset(); + cloth_work.SetOsageReset(); } void ExClothBlock::SetRing(const osage_ring_data& ring) { - rob.SetRing(ring); + cloth_work.SetRing(ring); } void ExClothBlock::SetSkinParam(skin_param_file_data* skp) { - rob.SetSkinParam(skp); + cloth_work.SetSkinParam(skp); } void ExClothBlock::SetSkinParamOsageRoot(const skin_param_osage_root* skp_root) { if (!skp_root) return; - rob.SetSkinParamOsageRoot(*skp_root); + cloth_work.SetSkinParamOsageRoot(*skp_root); - vec3 wind_direction = task_wind->ptr->wind_direction - * item_equip_object->item_equip->wind_strength; - rob.SetWindDirection(wind_direction); + vec3 wind_dir = task_wind->stage_wind.wind->val * skin_disp->rob_disp->wind_strength; + cloth_work.set_wind_dir(wind_dir); +} + +// 0x1405F5220 +void ExClothBlock::reset_ex_force() { + cloth_work.reset_ex_force(); +} + +void ExClothBlock::set_data(const rob_chara_item_equip_object* skin_disp, + const obj_skin_ex_node_cloth* data, const skin_param_osage_root* skp_root, const bone_database* bone_data) { + type = EX_NODE_TYPE_CLOTH; + dst_node = 0; + this->data = data; + name = skp_root ? skp_root->name : 0; + this->skin_disp = skin_disp; + + motion_matrix = skin_disp->get_node(0)->mat_ptr; + cloth_work.dest(); + cloth_work.set_data(data, skin_disp, bone_data); + SetSkinParamOsageRoot(skp_root); +} + +// 0x1405F7EF0 +void ExClothBlock::set_ex_force(const vec3& f) { + cloth_work.set_ex_force(f); +} + +// 0x1405F9280 +void ExClothBlock::set_move_cancel(const float_t& mv_ccl) { + cloth_work.set_move_cancel(mv_ccl); +} + +void ExClothBlock::set_param() { + cloth_work.make_osage_coli(motion_matrix); + cloth_work.set_wind_dir(task_wind->stage_wind.wind->val); } RobOsage::RobOsage() : skin_param_ptr(), apply_physics(), field_2A1(), field_2A4(), -inertia(), yz_order(), root_matrix_ptr(), move_cancel(), move_cancelled(), osage_reset(), -osage_reset_done(), disable_collision(), set_external_force(), reset_data_list() { +wet(), rottype(), root_matrix_ptr(), move_cancel(), move_cancelled(), osage_reset(), +osage_reset_done(), disable_collision(), use_ex_force(), reset_data_list() { } @@ -2301,10 +2203,10 @@ void RobOsage::AddMotionResetData(uint32_t motion_id, float_t frame) { if (elem != motion_reset_data.end()) motion_reset_data.erase(elem); - std::list reset_data_list; - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + std::list reset_data_list; + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) reset_data_list.push_back(i->reset_data); motion_reset_data.insert({ { motion_id, frame_int }, reset_data_list }); @@ -2315,16 +2217,16 @@ void RobOsage::ApplyBocRootColi(const float_t step) { if (get_pause() || step <= 0.0f || disable_collision) return; - const vec3 pos = nodes.data()[0].pos; + const vec3 pos = joint_node_vec.data()[0].pos; const OsageCollision::Work* coli_chara = this->coli_chara; const OsageCollision::Work* coli_ring = this->coli_ring; const SkinParam::RootCollisionType coli_type = skin_param_ptr->coli_type; - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { skin_param_osage_node* skp_osg_node = &i->data_ptr->skp_osg_node; - for (RobOsageNode*& j : i->data_ptr->boc) { + for (RobJointNode*& j : i->data_ptr->boc) { float_t hit = (float_t)( OsageCollision::osage_capsule_cls(coli_ring, i->pos, j->pos, skp_osg_node->coli_r) + OsageCollision::osage_capsule_cls(coli_chara, i->pos, j->pos, skp_osg_node->coli_r)); @@ -2341,34 +2243,179 @@ void RobOsage::ApplyBocRootColi(const float_t step) { i->GetPrevNode().hit += hit; } } - nodes.data()[0].pos = pos; + joint_node_vec.data()[0].pos = pos; +} + +// 0x14047C800 +void RobOsage::ApplyPhysics(const mat4& root_matrix, const vec3& hsc, + const float_t step, bool disable_ex_force, bool ring_coli, bool has_children_node) { + if (!joint_node_vec.size()) + return; + + const float_t gravity = get_gravity(); + BeginCalc(root_matrix, hsc, false); + + RobJointNode* node = &joint_node_vec.data()[0]; + node->old_pos = node->pos; + const vec3 v113 = transform.pos * hsc; + + mat4 v130 = root_matrix; + mat4_transform_point(&v130, &v113, &node->pos); + node->vec = node->pos - node->old_pos; + + RotateMat(v130, hsc); + *joint_node_vec.data()[0].dst_node_mat = v130; + *joint_node_vec.data()[0].dst_node->no_scale_mat = v130; + + vec3 direction = { 1.0f, 0.0f, 0.0f }; + mat4_transform_vector(&v130, &direction, &direction); + + if (!osage_reset && (get_pause() || step <= 0.0f)) + return; + + const bool stiffness = skin_param_ptr->stiffness > 0.0f; + + RobJointNode* v26_begin = joint_node_vec.data() + 1; + RobJointNode* v26_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* v26 = v26_begin; v26 != v26_end; v26++) { + float_t weight = v26->data_ptr->skp_osg_node.weight; + vec3 force; + if (!use_ex_force) { + apply_gravity(force, v26->pos, v26->GetPrevNode().pos, gravity, weight); + + if (v26 != v26_end - 1) { + vec3 _force; + apply_gravity(_force, v26->pos, v26->GetNextNode().pos, gravity, weight); + force = (force + _force) * 0.5f; + } + } + else + force = ex_force * (1.0f / weight); + + const vec3 _direction = direction * (v26->data_ptr->force * v26->force); + const float_t fric = (1.0f - wet) * (1.0f - skin_param_ptr->air_res); + + vec3 vel = force + _direction - v26->vec * fric + v26->ex_force * weight; + + if (!disable_ex_force) + vel += wind_dir * skin_param_ptr->wind_afc; + + if (stiffness) + vel -= (v26->vec - v26->GetPrevNode().vec) * (1.0f - skin_param_ptr->air_res); + + v26->vel = vel * (1.0f / (weight - (weight - 1.0f) * v26->data_ptr->skp_osg_node.inertial_cancel)); + } + + if (stiffness) { + mat4 v131 = v130; + vec3 v111; + mat4_get_translation(&v131, &v111); + + RobJointNode* v55_begin = joint_node_vec.data() + 1; + RobJointNode* v55_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* v55 = v55_begin; v55 != v55_end; v55++) { + vec3 v128; + mat4_transform_point(&v131, &v55->rel_pos, &v128); + + const vec3 vec = v55->vec + v55->vel; + vec3 v126 = v55->pos + vec; + length_limit(v126, v111, v55->length_back * hsc.x); + + vec3 v117 = (v128 - v126) * skin_param_ptr->stiffness; + const float_t weight = v55->data_ptr->skp_osg_node.weight; + v117 *= 1.0f / (weight - (weight - 1.0f) * v55->data_ptr->skp_osg_node.inertial_cancel); + v55->vel += v117; + + v126 = v55->pos + vec + v117; + + vec3 direction; + mat4_inverse_transform_point(&v131, &v126, &direction); + + make_axis_matrix(v131, direction, 0, 0, rottype); + + mat4_mul_translate(&v131, vec3::distance(v111, v126), 0.0f, 0.0f, &v131); + + v111 = v126; + } + } + + RobJointNode* v82_begin = joint_node_vec.data() + 1; + RobJointNode* v82_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* v82 = v82_begin; v82 != v82_end; v82++) { + v82->old_pos = v82->pos; + v82->vec += v82->vel; + v82->pos += v82->vec; + } + + if (joint_node_vec.size() > 1) { + RobJointNode* v90_begin = joint_node_vec.data() + joint_node_vec.size() - 2; + RobJointNode* v90_end = joint_node_vec.data(); + for (RobJointNode* v90 = v90_begin; v90 != v90_end; v90--) + length_limit(v90[0].pos, v90[1].pos, v90->length_next * hsc.x); + } + + if (ring_coli) { + RobJointNode* node = &joint_node_vec.data()[0]; + const float_t floor_height = ring.get_floor_height( + node->pos, node->data_ptr->skp_osg_node.coli_r); + + RobJointNode* v98_begin = joint_node_vec.data() + 1; + RobJointNode* v98_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* v98 = v98_begin; v98 != v98_end; v98++) { + v98->CheckNodeDistance(step, hsc.x); + v98->CheckFloorCollision(floor_height); + } + } + + if (has_children_node) { + RobJointNode* v99_begin = joint_node_vec.data() + 1; + RobJointNode* v99_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* v99 = v99_begin; v99 != v99_end; v99++) { + vec3 direction; + mat4_inverse_transform_point(&v130, &v99->pos, &direction); + + bool rot_clamped = make_axis_matrix(v130, direction, + &v99->data_ptr->skp_osg_node.hinge, + &v99->reset_data.rotation, rottype); + *v99->dst_node->no_scale_mat = v130; + + v99->TranslateMat(v130, rot_clamped, hsc.x); + } + + if (joint_node_vec.size() && effector.dst_node_mat) { + mat4 mat = *joint_node_vec.back().dst_node->no_scale_mat; + mat4_mul_translate_x(&mat, effector.length_back* hsc.x, &mat); + *effector.dst_node->no_scale_mat = mat; + } + } + apply_physics = false; } // 0x14047EE90 void RobOsage::ApplyResetData(const mat4& mat) { if (reset_data_list) { auto reset_data = reset_data_list->begin(); - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->reset_data = *reset_data++; reset_data_list = 0; } - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { - mat4_transform_vector(&mat, &i->reset_data.delta_pos, &i->delta_pos); + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { + mat4_transform_vector(&mat, &i->reset_data.vec, &i->vec); mat4_transform_point(&mat, &i->reset_data.pos, &i->pos); } root_matrix_prev = *root_matrix_ptr; } // 0x1404803B0 -void RobOsage::BeginCalc(const mat4& root_matrix, const vec3& parent_scale, bool has_children_node) { +void RobOsage::BeginCalc(const mat4& root_matrix, const vec3& hsc, bool has_children_node) { mat4 mat = root_matrix; - const vec3 pos = exp_data.position * parent_scale; - mat4_transform_point(&mat, &pos, &nodes.data()[0].pos); + const vec3 pos = transform.pos * hsc; + mat4_transform_point(&mat, &pos, &joint_node_vec.data()[0].pos); if (osage_reset && !osage_reset_done) { osage_reset_done = true; @@ -2383,9 +2430,9 @@ void RobOsage::BeginCalc(const mat4& root_matrix, const vec3& parent_scale, bool move_cancel = this->move_cancel; if (move_cancel > 0.0f) { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { vec3 pos; mat4_inverse_transform_point(&root_matrix_prev, &i->pos, &pos); mat4_transform_point(root_matrix_ptr, &pos, &pos); @@ -2397,27 +2444,27 @@ void RobOsage::BeginCalc(const mat4& root_matrix, const vec3& parent_scale, bool if (!has_children_node) return; - RotateMat(mat, parent_scale); - *nodes.data()[0].bone_node_mat = mat; + RotateMat(mat, hsc); + *joint_node_vec.data()[0].dst_node_mat = mat; - RobOsageNode* v30_begin = nodes.data() + 1; - RobOsageNode* v30_end = nodes.data() + nodes.size(); - for (RobOsageNode* v30 = v30_begin; v30 != v30_end; v30++) { + RobJointNode* v30_begin = joint_node_vec.data() + 1; + RobJointNode* v30_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* v30 = v30_begin; v30 != v30_end; v30++) { vec3 direction; mat4_inverse_transform_point(&mat, &v30->pos, &direction); - bool rot_clamped = rotate_matrix_to_direction(mat, direction, + bool rot_clamped = make_axis_matrix(mat, direction, &v30->data_ptr->skp_osg_node.hinge, - &v30->reset_data.rotation, yz_order); - *v30->bone_node_ptr->ex_data_mat = mat; + &v30->reset_data.rotation, rottype); + *v30->dst_node->no_scale_mat = mat; - v30->TranslateMat(mat, rot_clamped, parent_scale.x); + v30->TranslateMat(mat, rot_clamped, hsc.x); } - if (nodes.size() && end_node.bone_node_mat) { - mat4 mat = *nodes.back().bone_node_ptr->ex_data_mat; - mat4_mul_translate_x(&mat, end_node.length * parent_scale.x, &mat); - *end_node.bone_node_ptr->ex_data_mat = mat; + if (joint_node_vec.size() && effector.dst_node_mat) { + mat4 mat = *joint_node_vec.back().dst_node->no_scale_mat; + mat4_mul_translate_x(&mat, effector.length_back * hsc.x, &mat); + *effector.dst_node->no_scale_mat = mat; } } @@ -2427,12 +2474,6 @@ bool RobOsage::CheckPartsBits(const rob_osage_parts_bit& parts_bits) { return false; } -void RobOsage::ColiSet(const mat4* transform) { - if (skin_param_ptr->coli.size()) - OsageCollision::Work::update_cls_work(coli_chara, skin_param_ptr->coli.data(), transform); - OsageCollision::Work::update_cls_work(coli_ring, ring.skp_root_coli, transform); -} - // 0x14047ECA0 void RobOsage::CollideNodes(const float_t step) { if (get_pause() || step <= 0.0f) @@ -2442,16 +2483,16 @@ void RobOsage::CollideNodes(const float_t step) { const OsageCollision::Work* coli_ring = this->coli_ring; const OsageCollision& coli_object = ring.coli_object; - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { skin_param_osage_node* skp_osg_node = &i->data_ptr->skp_osg_node; i->hit += (float_t)OsageCollision::osage_cls_work_list(i->pos, skp_osg_node->coli_r, coli_object, &i->friction); if (disable_collision) continue; - for (RobOsageNode*& j : i->data_ptr->boc) { + for (RobJointNode*& j : i->data_ptr->boc) { j->hit += (float_t)OsageCollision::osage_cls(coli_ring, j->pos, skp_osg_node->coli_r); j->hit += (float_t)OsageCollision::osage_cls(coli_chara, j->pos, skp_osg_node->coli_r); } @@ -2463,7 +2504,7 @@ void RobOsage::CollideNodes(const float_t step) { // 0x14047D8C0 void RobOsage::CollideNodesTargetOsage(const mat4& root_matrix, - const vec3& parent_scale, const float_t step, bool collide_nodes) { + const vec3& hsc, const float_t step, bool collide_nodes) { if (!osage_reset && (get_pause() || step <= 0.0f)) return; @@ -2475,18 +2516,18 @@ void RobOsage::CollideNodesTargetOsage(const mat4& root_matrix, mat4 v64; if (collide_nodes) - v64 = *nodes.data()[0].bone_node_mat; + v64 = *joint_node_vec.data()[0].dst_node_mat; else { v64 = root_matrix; - const vec3 pos = exp_data.position * parent_scale; - mat4_transform_point(&v64, &pos, &nodes.data()[0].pos); - RotateMat(v64, parent_scale); + const vec3 pos = transform.pos * hsc; + mat4_transform_point(&v64, &pos, &joint_node_vec.data()[0].pos); + RotateMat(v64, hsc); } float_t floor_height = -1000.0f; if (collide_nodes) { - RobOsageNode* node = &nodes.data()[0]; + RobJointNode* node = &joint_node_vec.data()[0]; floor_height = ring.get_floor_height( node->pos, node->data_ptr->skp_osg_node.coli_r); } @@ -2494,27 +2535,27 @@ void RobOsage::CollideNodesTargetOsage(const mat4& root_matrix, const float_t v23 = step < 1.0f ? 0.2f / (2.0f - step) : 0.2f; if (skin_param_ptr->colli_tgt_osg) { - std::vector* colli_tgt_osg = skin_param_ptr->colli_tgt_osg; - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { + std::vector* colli_tgt_osg = skin_param_ptr->colli_tgt_osg; + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { vec3 v62 = 0.0f; - RobOsageNode* j_begin = colli_tgt_osg->data() + 1; - RobOsageNode* j_end = colli_tgt_osg->data() + colli_tgt_osg->size(); - for (RobOsageNode* j = j_begin; j != j_end; j++) + RobJointNode* j_begin = colli_tgt_osg->data() + 1; + RobJointNode* j_end = colli_tgt_osg->data() + colli_tgt_osg->size(); + for (RobJointNode* j = j_begin; j != j_end; j++) OsageCollision::cls_ball_oidashi(v62, i->pos, j->pos, i->data_ptr->skp_osg_node.coli_r + j->data_ptr->skp_osg_node.coli_r); i->pos += v62; } } - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { - const float_t fric = (1.0f - inertia) * skin_param_ptr->friction; + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { + const float_t fric = (1.0f - wet) * skin_param_ptr->friction; if (collide_nodes) { - i->CheckNodeDistance(step, parent_scale.x); + i->CheckNodeDistance(step, hsc.x); i->hit += (float_t)OsageCollision::osage_cls_work_list(i->pos, i->data_ptr->skp_osg_node.coli_r, coli_object, &i->friction); if (!disable_collision) { @@ -2526,160 +2567,75 @@ void RobOsage::CollideNodesTargetOsage(const mat4& root_matrix, i->CheckFloorCollision(floor_height); } else - segment_limit_distance(i->pos, i->GetPrevNode().pos, i->length * parent_scale.x); + length_limit(i->pos, i->GetPrevNode().pos, i->length_back * hsc.x); vec3 direction; mat4_inverse_transform_point(&v64, &i->pos, &direction); - bool rot_clamped = rotate_matrix_to_direction(v64, direction, + bool rot_clamped = make_axis_matrix(v64, direction, &i->data_ptr->skp_osg_node.hinge, - &i->reset_data.rotation, yz_order); - i->bone_node_ptr->exp_data.parent_scale = parent_scale; - *i->bone_node_ptr->ex_data_mat = v64; + &i->reset_data.rotation, rottype); + i->dst_node->transform.hsc = hsc; + *i->dst_node->no_scale_mat = v64; - if (i->bone_node_mat) - mat4_scale_rot(&v64, &parent_scale, i->bone_node_mat); + if (i->dst_node_mat) + mat4_scale_rot(&v64, &hsc, i->dst_node_mat); - i->reset_data.length = i->TranslateMat(v64, rot_clamped, parent_scale.x); + i->reset_data.length = i->TranslateMat(v64, rot_clamped, hsc.x); - i->delta_pos = (i->pos - i->fixed_pos) * inv_step; + i->vec = (i->pos - i->old_pos) * inv_step; if (i->hit > 0.0f) - i->delta_pos *= min_def(fric, i->friction); + i->vec *= min_def(fric, i->friction); - const float_t v55 = vec3::length_squared(i->delta_pos); + const float_t v55 = vec3::length_squared(i->vec); if (v55 > v23 * v23) - i->delta_pos *= v23 / sqrtf(v55); + i->vec *= v23 / sqrtf(v55); mat4_inverse_transform_point(&root_matrix, &i->pos, &i->reset_data.pos); - mat4_inverse_transform_vector(&root_matrix, &i->delta_pos, &i->reset_data.delta_pos); + mat4_inverse_transform_vector(&root_matrix, &i->vec, &i->reset_data.vec); } - if (nodes.size() && end_node.bone_node_mat) { - mat4 mat = *nodes.back().bone_node_ptr->ex_data_mat; - mat4_mul_translate_x(&mat, end_node.length * parent_scale.x, &mat); - *end_node.bone_node_ptr->ex_data_mat = mat; + if (joint_node_vec.size() && effector.dst_node_mat) { + mat4 mat = *joint_node_vec.back().dst_node->no_scale_mat; + mat4_mul_translate_x(&mat, effector.length_back * hsc.x, &mat); + *effector.dst_node->no_scale_mat = mat; - mat4_scale_rot(&mat, &parent_scale, &mat); - *end_node.bone_node_mat = mat; - end_node.bone_node_ptr->exp_data.parent_scale = parent_scale; + mat4_scale_rot(&mat, &hsc, &mat); + *effector.dst_node_mat = mat; + effector.dst_node->transform.hsc = hsc; } } // 0x14047E1C0 -void RobOsage::CtrlEnd(const vec3& parent_scale) { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) +void RobOsage::CtrlEnd(const vec3& hsc) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) if (i->data_ptr->normal_ref.set) { - i->data_ptr->normal_ref.GetMat(i->bone_node_mat); - mat4_scale_rot(i->bone_node_mat, &parent_scale, i->bone_node_mat); + i->data_ptr->normal_ref.GetMat(i->dst_node_mat); + mat4_scale_rot(i->dst_node_mat, &hsc, i->dst_node_mat); } } -// 0x14047F990 -void RobOsage::CtrlInitBegin(const mat4& root_matrix, const vec3& parent_scale, bool sibling_node) { - if (!nodes.size()) - return; - - vec3 root_pos = exp_data.position * parent_scale; - mat4_transform_point(&root_matrix, &root_pos, &root_pos); - RobOsageNode* v12 = &nodes.data()[0]; - v12->pos = root_pos; - v12->fixed_pos = root_pos; - v12->delta_pos = 0.0f; - - RobOsageNode* node = &nodes.data()[0]; - const float_t floor_height = ring.get_floor_height( - node->pos, node->data_ptr->skp_osg_node.coli_r); - - mat4 v78 = root_matrix; - RotateMat(v78, parent_scale, true); - - vec3 v60 = { 1.0f, 0.0f, 0.0f }; - mat4_transform_vector(&v78, &v60, &v60); - - RobOsageNode* i_begin = this->nodes.data() + 1; - RobOsageNode* i_end = this->nodes.data() + this->nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { - vec3 v74 = i->GetPrevNode().pos + vec3::normalize(v60) * (i->length * parent_scale.x); - if (sibling_node && i->sibling_node) - segment_limit_distance(v74, i->sibling_node->pos, i->max_distance); - - skin_param_osage_node* v38 = &i->data_ptr->skp_osg_node; - OsageCollision::osage_cls(coli_ring, v74, v38->coli_r); - OsageCollision::osage_cls(coli_chara, v74, v38->coli_r); - - const float_t v39 = floor_height + v38->coli_r; - if (v74.y < v39 && v39 < 1001.0f) { - v74.y = v39; - v74 = vec3::normalize(v74 - i->GetPrevNode().pos) * (i->length * parent_scale.x) + i->GetPrevNode().pos; - } - i->pos = v74; - i->delta_pos = 0.0f; - - vec3 direction; - mat4_inverse_transform_point(&v78, &i->pos, &direction); - - rotate_matrix_to_direction(v78, direction, &i->data_ptr->skp_osg_node.hinge, - &i->reset_data.rotation, yz_order); - i->bone_node_ptr->exp_data.parent_scale = parent_scale; - *i->bone_node_ptr->ex_data_mat = v78; - - if (i->bone_node_mat) - mat4_scale_rot(&v78, &parent_scale, i->bone_node_mat); - - float_t v55 = vec3::distance(i->pos, i->GetPrevNode().pos); - float_t v56 = i->length * parent_scale.x; - if (v55 >= fabsf(v56)) - v56 = v55; - mat4_mul_translate(&v78, v56, 0.0f, 0.0f, &v78); - mat4_get_translation(&v78, &i->pos); - v60 = i->pos - i->GetPrevNode().pos; - } - - if (nodes.size() && end_node.bone_node_mat) { - mat4 mat = *nodes.back().bone_node_ptr->ex_data_mat; - mat4_mul_translate_x(&mat, end_node.length * parent_scale.x, &mat); - *end_node.bone_node_ptr->ex_data_mat = mat; - - mat4_scale_rot(&mat, &parent_scale, &mat); - *end_node.bone_node_mat = mat; - end_node.bone_node_ptr->exp_data.parent_scale = parent_scale; - } -} - -// 0x14047C770 -void RobOsage::CtrlInitMain(const mat4& root_matrix, const vec3& parent_scale, - const float_t step, bool disable_external_force) { - ApplyPhysics(root_matrix, parent_scale, step, disable_external_force, false, false); - CollideNodesTargetOsage(root_matrix, parent_scale, step, true); - EndCalc(root_matrix, parent_scale, step, disable_external_force); -} - -// 0x14047C750 -void RobOsage::CtrlMain(const mat4& root_matrix, const vec3& parent_scale, const float_t step) { - CtrlInitMain(root_matrix, parent_scale, step, false); -} - // 0x14047E240 void RobOsage::CtrlOsagePlayData(const mat4& root_matrix, - const vec3& parent_scale, std::vector& opd_blend_data) { + const vec3& hsc, const std::vector& opd_blend_data) { if (!opd_blend_data.size()) return; - const vec3 v63 = exp_data.position * parent_scale; + const vec3 v63 = transform.pos * hsc; mat4 v85 = root_matrix; - mat4_transform_point(&v85, &v63, &nodes.data()[0].pos); + mat4_transform_point(&v85, &v63, &joint_node_vec.data()[0].pos); - RotateMat(v85, parent_scale); - *nodes.data()[0].bone_node_mat = v85; - *nodes.data()[0].bone_node_ptr->ex_data_mat = v85; + RotateMat(v85, hsc); + *joint_node_vec.data()[0].dst_node_mat = v85; + *joint_node_vec.data()[0].dst_node->no_scale_mat = v85; - ::opd_blend_data* i_begin = opd_blend_data.data() + opd_blend_data.size(); - ::opd_blend_data* i_end = opd_blend_data.data(); - for (::opd_blend_data* i = i_begin; i != i_end; ) { + const ::opd_blend_data* i_begin = opd_blend_data.data() + opd_blend_data.size(); + const ::opd_blend_data* i_end = opd_blend_data.data(); + for (const ::opd_blend_data* i = i_begin; i != i_end; ) { i--; float_t frame = i->frame; @@ -2705,12 +2661,12 @@ void RobOsage::CtrlOsagePlayData(const mat4& root_matrix, float_t inv_blend = 1.0f - blend; mat4 v87 = v85; - vec3 parent_curr_trans = nodes.data()[0].pos; - vec3 parent_next_trans = nodes.data()[0].pos; + vec3 parent_curr_trans = joint_node_vec.data()[0].pos; + vec3 parent_next_trans = joint_node_vec.data()[0].pos; - RobOsageNode* j_begin = nodes.data() + 1; - RobOsageNode* j_end = nodes.data() + nodes.size(); - for (RobOsageNode* j = j_begin; j != j_end; j++) { + RobJointNode* j_begin = joint_node_vec.data() + 1; + RobJointNode* j_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* j = j_begin; j != j_end; j++) { opd_vec3_data* opd = &j->opd_data[i - i_end]; const float_t* opd_x = opd->x; const float_t* opd_y = opd->y; @@ -2735,7 +2691,7 @@ void RobOsage::CtrlOsagePlayData(const mat4& root_matrix, mat4_inverse_transform_point(&v87, &_trans, &direction); vec3 rotation = 0.0f; - rotate_matrix_to_direction(v87, direction, 0, &rotation, yz_order); + make_axis_matrix(v87, direction, 0, &rotation, rottype); mat4_set_translation(&v87, &_trans); float_t length = vec3::distance(curr_trans, parent_curr_trans) * inv_blend @@ -2747,45 +2703,45 @@ void RobOsage::CtrlOsagePlayData(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++) { + RobJointNode* j_begin = joint_node_vec.data() + 1; + RobJointNode* j_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* j = j_begin; j != j_end; j++) { 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_mul_rotate_z(&v85, rot_z, &v85); mat4_mul_rotate_y(&v85, rot_y, &v85); - j->bone_node_ptr->exp_data.parent_scale = parent_scale; - *j->bone_node_ptr->ex_data_mat = v85; + j->dst_node->transform.hsc = hsc; + *j->dst_node->no_scale_mat = v85; - if (j->bone_node_mat) - mat4_scale_rot(&v85, &parent_scale, j->bone_node_mat); + if (j->dst_node_mat) + mat4_scale_rot(&v85, &hsc, j->dst_node_mat); mat4_mul_translate(&v85, j->opd_node_data.curr.length, 0.0f, 0.0f, &v85); - j->fixed_pos = j->pos; + j->old_pos = j->pos; mat4_get_translation(&v85, &j->pos); } - if (nodes.size() && end_node.bone_node_mat) { - mat4 mat = *nodes.back().bone_node_ptr->ex_data_mat; - mat4_mul_translate_x(&mat, end_node.length * parent_scale.x, &mat); - *end_node.bone_node_ptr->ex_data_mat = mat; + if (joint_node_vec.size() && effector.dst_node_mat) { + mat4 mat = *joint_node_vec.back().dst_node->no_scale_mat; + mat4_mul_translate_x(&mat, effector.length_back * hsc.x, &mat); + *effector.dst_node->no_scale_mat = mat; - mat4_scale_rot(&mat, &parent_scale, &mat); - *end_node.bone_node_mat = mat; - end_node.bone_node_ptr->exp_data.parent_scale = parent_scale; + mat4_scale_rot(&mat, &hsc, &mat); + *effector.dst_node_mat = mat; + effector.dst_node->transform.hsc = hsc; } } // 0x140480260 -void RobOsage::EndCalc(const mat4& root_matrix, const vec3& parent_scale, - const float_t step, bool disable_external_force) { - if (!disable_external_force) { +void RobOsage::EndCalc(const mat4& root_matrix, const vec3& hsc, + const float_t step, bool disable_ex_force) { + if (!disable_ex_force) { SetNodesExternalForce(0, 1.0f); SetNodesForce(1.0f); - set_external_force = false; - external_force = 0.0f; + use_ex_force = false; + ex_force = 0.0f; } apply_physics = true; @@ -2795,7 +2751,7 @@ void RobOsage::EndCalc(const mat4& root_matrix, const vec3& parent_scale, osage_reset = false; osage_reset_done = false; - for (RobOsageNode& i : nodes) { + for (RobJointNode& i : joint_node_vec) { i.hit = 0.0f; i.friction = 1.0f; } @@ -2803,95 +2759,10 @@ void RobOsage::EndCalc(const mat4& root_matrix, const vec3& parent_scale, root_matrix_prev = *root_matrix_ptr; } -RobOsageNode* RobOsage::GetNode(size_t index) { - if (index < nodes.size()) - return &nodes.data()[index]; - else - return &end_node; -} - -void RobOsage::InitData(obj_skin_block_osage* osg_data, obj_skin_osage_node* osg_nodes, - bone_node* ex_data_bone_nodes, obj_skin* skin) { - Reset(); - exp_data.set_position_rotation(osg_data->node.position, osg_data->node.rotation); - nodes.clear(); - nodes.resize(osg_data->count + 1ULL); - - RobOsageNode* node = nodes.data(); - node->Reset(); - node->child_length = osg_nodes->length; - bone_node* node_ptr = &ex_data_bone_nodes[osg_data->name_index & 0x7FFF]; - node->bone_node_ptr = node_ptr; - node->bone_node_mat = node_ptr->mat; - *node_ptr->ex_data_mat = mat4_identity; - node->sibling_node = 0; - - bone_node* parent_node_ptr = node->bone_node_ptr; - for (int32_t i = 0; i < osg_data->count; i++) { - obj_skin_osage_node* osg_node = &osg_nodes[i]; - RobOsageNode* node = &nodes.data()[i + 1LL]; - node->Reset(); - node->length = osg_node[0].length; - if (i != osg_data->count - 1) - node->child_length = osg_node[1].length; - bone_node* node_ptr = &ex_data_bone_nodes[osg_node->name_index & 0x7FFF]; - node->bone_node_ptr = node_ptr; - node->bone_node_mat = node_ptr->mat; - node_ptr->parent = parent_node_ptr; - parent_node_ptr = node->bone_node_ptr; - } - - end_node.Reset(); - end_node.length = osg_nodes[osg_data->count - 1].length; - bone_node* end_node_ptr = &ex_data_bone_nodes[osg_data->end_name_index & 0x7FFF]; - end_node.bone_node_ptr = end_node_ptr; - end_node.bone_node_mat = end_node_ptr->mat; - end_node_ptr->parent = parent_node_ptr; - *end_node.bone_node_ptr->ex_data_mat = mat4_identity; - - if (osg_data->count) { - obj_skin_osage_node* node_array = osg_data->node_array; - size_t v24 = 0; - RobOsageNode* node = &nodes.data()[1]; - if (node_array) - for (size_t i = 0; i < osg_data->count; i++, node++) { - mat3 mat; - mat3_rotate_zyx(&node_array[i].rotation, &mat); - - vec3 v49 = { node->length, 0.0f, 0.0f }; - mat3_transform_vector(&mat, &v49, &node->rel_pos); - } - else - for (size_t i = 0; i < osg_data->count; i++, node++) - node->rel_pos = { node->length, 0.0f, 0.0f }; - } - - if (osg_data->count) { - RobOsageNode* node = &nodes.data()[1]; - size_t v33 = 0; - for (int32_t i = 0; i < osg_data->count; i++, node++) { - node->mat = mat4_null; - - obj_skin_bone* bone = skin->bone_array; - for (int32_t j = 0; j < skin->num_bone; j++, bone++) - if (bone->id == osg_nodes->name_index) { - mat4_invert_fast(&bone->inv_bind_pose_mat, &node->mat); - break; - } - - osg_nodes++; - } - } - - RobOsageNode* last_node = &nodes.back(); - if (memcmp(&last_node->mat, &mat4_null, sizeof(mat4))) - mat4_mul_translate(&last_node->mat, end_node.length, 0.0f, 0.0f, &end_node.mat); -} - const float_t* RobOsage::LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count) { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { if (node_index >= i->opd_data.size()) i->opd_data.resize(node_index + 1); @@ -2910,7 +2781,7 @@ void RobOsage::LoadSkinParam(void* kv, const char* name, skin_param_osage_root& skp_root, object_info* obj_info, const bone_database* bone_data) { key_val* _kv = (key_val*)kv; skin_param_ptr = &skin_param; - for (RobOsageNode& i : nodes) + for (RobJointNode& i : joint_node_vec) i.data_ptr = &i.data; skin_param_osage_root_parse(_kv, name, skp_root, bone_data); @@ -2921,17 +2792,158 @@ void RobOsage::LoadSkinParam(void* kv, const char* name, this->osage_setting = *osage_setting; std::vector vec; - vec.resize(nodes.size() - 1); + vec.resize(joint_node_vec.size() - 1); skin_param_osage_node_parse(_kv, name, &vec, skp_root); SetSkpOsgNodes(&vec); } -void RobOsage::Reset() { - nodes.clear(); - end_node.Reset(); - wind_direction = 0.0f; - inertia = 0.0f; - yz_order = 0; +// 0x14047F110 +void RobOsage::RotateMat(mat4& mat, const vec3& hsc, bool init_rot) { + const vec3 position = transform.pos * hsc; + mat4_mul_translate(&mat, &position, &mat); + mat4_mul_rotate_zyx(&mat, &transform.rot, &mat); + + const vec3 rot = init_rot ? skin_param_ptr->init_rot + skin_param_ptr->rot : skin_param_ptr->rot; + mat4_mul_rotate_zyx(&mat, &rot, &mat); +} + +// 0x140481090 +void RobOsage::SetDisableCollision(const bool& value) { + disable_collision = value; +} + +void RobOsage::SetMotionResetData(uint32_t motion_id, float_t frame) { + osage_reset = true; + auto elem = motion_reset_data.find({ motion_id, (int32_t)prj::roundf(frame * 1000.0f) }); + if (elem != motion_reset_data.end() && elem->second.size() + 1 == joint_node_vec.size()) + reset_data_list = &elem->second; +} + +// 0x140480F40 +void RobOsage::SetNodesExternalForce(const vec3* ex_force, const float_t& gain) { + if (!ex_force) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) + i->ex_force = 0.0f; + return; + } + + vec3 _ex_force = *ex_force; + for (size_t i = osage_setting.exf; i; i--) + _ex_force *= gain; + + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { + i->ex_force = _ex_force; + _ex_force *= gain; + } +} + +// 0x140481540 +void RobOsage::SetNodesForce(const float_t& force) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) + i->force = force; +} + +const float_t* RobOsage::SetOsagePlayDataInit(const float_t* opdi_data) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { + i->pos.x = *opdi_data++; + i->pos.y = *opdi_data++; + i->pos.z = *opdi_data++; + i->vec.x = *opdi_data++; + i->vec.y = *opdi_data++; + i->vec.z = *opdi_data++; + i->old_pos = i->pos; + } + return opdi_data; +} + +// 0x1405F9A90, but it's combined with ExOsageBlock::SetOsageReset +void RobOsage::SetOsageReset() { + osage_reset = true; +} + +void RobOsage::SetRing(const osage_ring_data& ring) { + this->ring = ring; +} + +void RobOsage::SetSkinParam(skin_param_file_data* skp) { + if (skp->nodes_data.size() == joint_node_vec.size() - 1) { + skin_param_ptr = &skp->skin_param; + + size_t node_index = 0; + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) + i->data_ptr = &skp->nodes_data[node_index++]; + } + else { + skin_param_ptr = &skin_param; + for (RobJointNode& i : joint_node_vec) + i.data_ptr = &i.data; + } +} + +void RobOsage::SetSkinParamOsageRoot(const skin_param_osage_root& skp_root) { + skin_param_ptr->reset(); + set_force(skp_root.force, skp_root.force_gain); + set_air_res(skp_root.air_res); + set_angle(skp_root.rot_y, skp_root.rot_z); + set_init_angle(skp_root.init_rot_y, skp_root.init_rot_z); + set_rot_type(skp_root.rottype); + skin_param_ptr->friction = skp_root.friction; + skin_param_ptr->wind_afc = skp_root.wind_afc; + set_coli_r(skp_root.coli_r); + set_limit_angle(skp_root.hinge_y, skp_root.hinge_z); + skin_param_ptr->coli.assign(skp_root.coli.begin(), skp_root.coli.end()); + skin_param_ptr->coli_type = skp_root.coli_type; + skin_param_ptr->stiffness = skp_root.stiffness; + skin_param_ptr->move_cancel = skp_root.move_cancel; +} + +void RobOsage::SetSkpOsgNodes(const std::vector* skp_osg_nodes) { + if (!skp_osg_nodes) + return; + + if (joint_node_vec.size() - 1 != skp_osg_nodes->size()) + return; + + RobJointNode* i = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + const skin_param_osage_node* j = skp_osg_nodes->data(); + const skin_param_osage_node* j_end = skp_osg_nodes->data() + skp_osg_nodes->size(); + while (i != i_end && j != j_end) { + i->data_ptr->skp_osg_node = *j++; + i->data_ptr->skp_osg_node.hinge.limit(); + i++; + } +} + +void RobOsage::SetWindDirection(const vec3* value) { + if (value) + wind_dir = *value; + else + wind_dir = 0.0f; +} + +// 0x14047C750 +void RobOsage::ctrl(const mat4& root_matrix, const vec3& hsc, const float_t step) { + pos_init_cont(root_matrix, hsc, step, false); +} + +// 0x14047F200 +void RobOsage::dest() { + joint_node_vec.clear(); + effector.reset(); + wind_dir = 0.0f; + wet = 0.0f; + rottype = ROTTYPE_YZ; apply_physics = true; motion_reset_data.clear(); move_cancel = 0.0f; @@ -2946,336 +2958,389 @@ void RobOsage::Reset() { reset_data_list = 0; field_2A4 = 0.0f; field_2A1 = false; - set_external_force = false; - external_force = 0.0f; + use_ex_force = false; + ex_force = 0.0f; root_matrix_ptr = 0; root_matrix_prev = mat4_null; } -void RobOsage::ResetBoc() { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) +// 0x1404808C0 +void RobOsage::dest_boc() { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->boc.clear(); } -void RobOsage::ResetExtrenalForce() { - set_external_force = false; - external_force = 0.0f; +// 0x140482AA0 +RobJointNode* RobOsage::get_joint_node(size_t index) { + if (index < joint_node_vec.size()) + return &joint_node_vec.data()[index]; + else + return &effector; } -// 0x14047F110 -void RobOsage::RotateMat(mat4& mat, const vec3& parent_scale, bool init_rot) { - const vec3 position = exp_data.position * parent_scale; - mat4_mul_translate(&mat, &position, &mat); - mat4_mul_rotate_zyx(&mat, &exp_data.rotation, &mat); +// 0x14047F370 +void RobOsage::init(const obj_skin_ex_node_osage* osg_data, const obj_skin_osage_joint* joint, + bone_node* ex_node, const obj_skin* skin) { + dest(); - const vec3 rot = init_rot ? skin_param_ptr->init_rot + skin_param_ptr->rot : skin_param_ptr->rot; - mat4_mul_rotate_zyx(&mat, &rot, &mat); + transform.init(osg_data->transform.position, osg_data->transform.rotation); + joint_node_vec.clear(); + joint_node_vec.resize(osg_data->nb_joint + 1ULL); + + RobJointNode* node = joint_node_vec.data(); + node->reset(); + node->length_next = joint->length; + bone_node* root_node = &ex_node[osg_data->root_idx & 0x7FFF]; + node->dst_node = root_node; + node->dst_node_mat = root_node->mat_ptr; + *root_node->no_scale_mat = mat4_identity; + node->distance = 0; + + bone_node* parent_node_ptr = node->dst_node; + for (uint32_t i = 0; i < osg_data->nb_joint; i++) { + const obj_skin_osage_joint* osg_node = &joint[i]; + RobJointNode* node = &joint_node_vec.data()[i + 1LL]; + node->reset(); + node->length_back = osg_node[0].length; + if (i + 1 < osg_data->nb_joint) + node->length_next = osg_node[1].length; + bone_node* node_ptr = &ex_node[osg_node->nid & 0x7FFF]; + node->dst_node = node_ptr; + node->dst_node_mat = node_ptr->mat_ptr; + node_ptr->parent = parent_node_ptr; + parent_node_ptr = node->dst_node; + } + + effector.reset(); + effector.length_back = joint[osg_data->nb_joint - 1].length; + bone_node* effector_node = &ex_node[osg_data->efc_idx & 0x7FFF]; + effector.dst_node = effector_node; + effector.dst_node_mat = effector_node->mat_ptr; + effector_node->parent = parent_node_ptr; + *effector.dst_node->no_scale_mat = mat4_identity; + + if (osg_data->nb_joint) { + obj_skin_osage_joint_rotation* joint_rotation = osg_data->joint_rotation_array; + RobJointNode* node = &joint_node_vec.data()[1]; + if (joint_rotation) + for (uint32_t i = 0; i < osg_data->nb_joint; i++, joint_rotation++, node++) { + mat3 mat; + mat3_rotate_zyx(&joint_rotation->rotation, &mat); + + const vec3 rel_pos = { node->length_back, 0.0f, 0.0f }; + mat3_transform_vector(&mat, &rel_pos, &node->rel_pos); + } + else + for (uint32_t i = 0; i < osg_data->nb_joint; i++, node++) + node->rel_pos = { node->length_back, 0.0f, 0.0f }; + } + + if (osg_data->nb_joint) { + RobJointNode* node = &joint_node_vec.data()[1]; + size_t v33 = 0; + for (uint32_t i = 0; i < osg_data->nb_joint; i++, node++) { + node->mat = mat4_null; + + obj_skin_bone* bone = skin->bone_array; + for (int32_t j = 0; j < skin->num_bone; j++, bone++) + if (bone->id == joint->nid) { + mat4_invert_fast(&bone->inv_bind_pose_mat, &node->mat); + break; + } + + joint++; + } + } + + RobJointNode* last_node = &joint_node_vec.back(); + if (memcmp(&last_node->mat, &mat4_null, sizeof(mat4))) + mat4_mul_translate(&last_node->mat, effector.length_back, 0.0f, 0.0f, &effector.mat); } -void RobOsage::SetAirRes(float_t air_res) { - skin_param_ptr->air_res = air_res; +// 0x1404816B0 +void RobOsage::make_osage_coli(const mat4* motmat) { + if (skin_param_ptr->coli.size()) + OsageCollision::Work::update_cls_work(coli_chara, skin_param_ptr->coli.data(), motmat); + OsageCollision::Work::update_cls_work(coli_ring, ring.skp_root_coli, motmat); } -void RobOsage::SetColiR(float_t coli_r) { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) +// 0x14047F990 +void RobOsage::pos_init(const mat4& root_matrix, const vec3& hsc, bool dist_flag) { + if (!joint_node_vec.size()) + return; + + vec3 root_pos = transform.pos * hsc; + mat4_transform_point(&root_matrix, &root_pos, &root_pos); + RobJointNode* v12 = &joint_node_vec.data()[0]; + v12->pos = root_pos; + v12->old_pos = root_pos; + v12->vec = 0.0f; + + RobJointNode* node = &joint_node_vec.data()[0]; + const float_t floor_height = ring.get_floor_height( + node->pos, node->data_ptr->skp_osg_node.coli_r); + + mat4 v78 = root_matrix; + RotateMat(v78, hsc, true); + + vec3 v60 = { 1.0f, 0.0f, 0.0f }; + mat4_transform_vector(&v78, &v60, &v60); + + RobJointNode* i_begin = this->joint_node_vec.data() + 1; + RobJointNode* i_end = this->joint_node_vec.data() + this->joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { + vec3 v74 = i->GetPrevNode().pos + vec3::normalize(v60) * (i->length_back * hsc.x); + if (dist_flag && i->distance) + length_limit(v74, i->distance->pos, i->length_dist); + + skin_param_osage_node* v38 = &i->data_ptr->skp_osg_node; + OsageCollision::osage_cls(coli_ring, v74, v38->coli_r); + OsageCollision::osage_cls(coli_chara, v74, v38->coli_r); + + const float_t v39 = floor_height + v38->coli_r; + if (v74.y < v39 && v39 < 1001.0f) { + v74.y = v39; + v74 = vec3::normalize(v74 - i->GetPrevNode().pos) * (i->length_back * hsc.x) + i->GetPrevNode().pos; + } + i->pos = v74; + i->vec = 0.0f; + + vec3 direction; + mat4_inverse_transform_point(&v78, &i->pos, &direction); + + make_axis_matrix(v78, direction, &i->data_ptr->skp_osg_node.hinge, + &i->reset_data.rotation, rottype); + i->dst_node->transform.hsc = hsc; + *i->dst_node->no_scale_mat = v78; + + if (i->dst_node_mat) + mat4_scale_rot(&v78, &hsc, i->dst_node_mat); + + float_t v55 = vec3::distance(i->pos, i->GetPrevNode().pos); + float_t v56 = i->length_back * hsc.x; + if (v55 >= fabsf(v56)) + v56 = v55; + mat4_mul_translate(&v78, v56, 0.0f, 0.0f, &v78); + mat4_get_translation(&v78, &i->pos); + v60 = i->pos - i->GetPrevNode().pos; + } + + if (joint_node_vec.size() && effector.dst_node_mat) { + mat4 mat = *joint_node_vec.back().dst_node->no_scale_mat; + mat4_mul_translate_x(&mat, effector.length_back * hsc.x, &mat); + *effector.dst_node->no_scale_mat = mat; + + mat4_scale_rot(&mat, &hsc, &mat); + *effector.dst_node_mat = mat; + effector.dst_node->transform.hsc = hsc; + } +} + +// 0x14047C770 +void RobOsage::pos_init_cont(const mat4& root_matrix, const vec3& hsc, + const float_t step, bool disable_ex_force) { + ApplyPhysics(root_matrix, hsc, step, disable_ex_force, false, false); + CollideNodesTargetOsage(root_matrix, hsc, step, true); + EndCalc(root_matrix, hsc, step, disable_ex_force); +} + +// 0x1404808F0 +void RobOsage::reset_ex_force() { + use_ex_force = false; + ex_force = 0.0f; +} + +// 0x140480C60 +void RobOsage::set_air_res(float_t air) { + skin_param_ptr->air_res = air; +} + +// 0x140480C70 +void RobOsage::set_angle(float_t angle_y, float_t angle_z) { + skin_param_ptr->rot.y = angle_y * DEG_TO_RAD_FLOAT; + skin_param_ptr->rot.z = angle_z * DEG_TO_RAD_FLOAT; +} + +// 0x140480D30 +void RobOsage::set_coli_r(float_t coli_r) { + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.coli_r = coli_r; } -// 0x140481090 -void RobOsage::SetDisableCollision(const bool& value) { - disable_collision = value; +// 0x140480F10 +void RobOsage::set_ex_force(const vec3& f) { + use_ex_force = true; + ex_force = f; } -void RobOsage::SetForce(float_t force, float_t force_gain) { +// 0x140481040 +void RobOsage::set_force(float_t force, float_t gain) { skin_param_ptr->force = force; - skin_param_ptr->force_gain = force_gain; - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { + skin_param_ptr->force_gain = gain; + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { i->data_ptr->force = force; - force = force * force_gain; + force = force * gain; } } -void RobOsage::SetHinge(float_t hinge_y, float_t hinge_z) { - hinge_y = min_def(hinge_y, 179.0f); - hinge_z = min_def(hinge_z, 179.0f); - hinge_y = hinge_y * DEG_TO_RAD_FLOAT; - hinge_z = hinge_z * DEG_TO_RAD_FLOAT; - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { +// 0x1404810A0 +void RobOsage::set_init_angle(float_t angle_y, float_t angle_z) { + skin_param_ptr->init_rot.y = angle_y * DEG_TO_RAD_FLOAT; + skin_param_ptr->init_rot.z = angle_z * DEG_TO_RAD_FLOAT; +} + +// 0x140480CA0 +void RobOsage::set_limit_angle(float_t angle_y, float_t angle_z) { + angle_y = min_def(angle_y, 179.0f) * DEG_TO_RAD_FLOAT; + angle_z = min_def(angle_z, 179.0f) * DEG_TO_RAD_FLOAT; + RobJointNode* i_begin = joint_node_vec.data() + 1; + RobJointNode* i_end = joint_node_vec.data() + joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) { skin_param_osage_node* skp_osg_node = &i->data_ptr->skp_osg_node; - skp_osg_node->hinge.ymin = -hinge_y; - skp_osg_node->hinge.ymax = hinge_y; - skp_osg_node->hinge.zmin = -hinge_z; - skp_osg_node->hinge.zmax = hinge_z; + skp_osg_node->hinge.ymin = -angle_y; + skp_osg_node->hinge.ymax = angle_y; + skp_osg_node->hinge.zmin = -angle_z; + skp_osg_node->hinge.zmax = angle_z; } } -void RobOsage::SetInitRot(float_t init_rot_y, float_t init_rot_z) { - skin_param_ptr->init_rot.y = init_rot_y * DEG_TO_RAD_FLOAT; - skin_param_ptr->init_rot.z = init_rot_z * DEG_TO_RAD_FLOAT; -} - -void RobOsage::SetMotionResetData(uint32_t motion_id, float_t frame) { - osage_reset = true; - auto elem = motion_reset_data.find({ motion_id, (int32_t)prj::roundf(frame * 1000.0f) }); - if (elem != motion_reset_data.end() && elem->second.size() + 1 == nodes.size()) - reset_data_list = &elem->second; -} - // 0x1404810D0 -void RobOsage::SetMoveCancel(const float_t& value) { - move_cancel = value; +void RobOsage::set_move_cancel(const float_t& mv_ccl) { + move_cancel = mv_ccl; } -// 0x140480F40 -void RobOsage::SetNodesExternalForce(const vec3* external_force, const float_t& strength) { - if (!external_force) { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) - i->external_force = 0.0f; - return; - } - - vec3 _external_force = *external_force; - for (size_t i = osage_setting.exf; i; i--) - _external_force *= strength; - - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { - i->external_force = _external_force; - _external_force *= strength; - } +// 0x1404814C0 +void RobOsage::set_rot_type(ROTTYPE rot_type) { + rottype = rot_type; } -// 0x140481540 -void RobOsage::SetNodesForce(const float_t& force) { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) - i->force = force; -} - -const float_t* RobOsage::SetOsagePlayDataInit(const float_t* opdi_data) { - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) { - i->pos.x = *opdi_data++; - i->pos.y = *opdi_data++; - i->pos.z = *opdi_data++; - i->delta_pos.x = *opdi_data++; - i->delta_pos.y = *opdi_data++; - i->delta_pos.z = *opdi_data++; - i->fixed_pos = i->pos; - } - return opdi_data; -} - -// 0x1405F9A90, but it's combined with ExOsageBlock::SetOsageReset -void RobOsage::SetOsageReset() { - osage_reset = true; -} - -void RobOsage::SetRing(const osage_ring_data& ring) { - this->ring = ring; -} - -void RobOsage::SetRot(float_t rot_y, float_t rot_z) { - skin_param_ptr->rot.y = rot_y * DEG_TO_RAD_FLOAT; - skin_param_ptr->rot.z = rot_z * DEG_TO_RAD_FLOAT; -} - -void RobOsage::SetSkinParam(skin_param_file_data* skp) { - if (skp->nodes_data.size() == nodes.size() - 1) { - skin_param_ptr = &skp->skin_param; - - size_t node_index = 0; - RobOsageNode* i_begin = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) - i->data_ptr = &skp->nodes_data[node_index++]; - } - else { - skin_param_ptr = &skin_param; - for (RobOsageNode& i : nodes) - i.data_ptr = &i.data; - } -} - -void RobOsage::SetSkinParamOsageRoot(const skin_param_osage_root& skp_root) { - skin_param_ptr->reset(); - SetForce(skp_root.force, skp_root.force_gain); - SetAirRes(skp_root.air_res); - SetRot(skp_root.rot_y, skp_root.rot_z); - SetInitRot(skp_root.init_rot_y, skp_root.init_rot_z); - SetYZOrder(skp_root.yz_order); - skin_param_ptr->friction = skp_root.friction; - skin_param_ptr->wind_afc = skp_root.wind_afc; - SetColiR(skp_root.coli_r); - SetHinge(skp_root.hinge_y, skp_root.hinge_z); - skin_param_ptr->coli.assign(skp_root.coli.begin(), skp_root.coli.end()); - skin_param_ptr->coli_type = skp_root.coli_type; - skin_param_ptr->stiffness = skp_root.stiffness; - skin_param_ptr->move_cancel = skp_root.move_cancel; -} - -void RobOsage::SetSkpOsgNodes(std::vector* skp_osg_nodes) { - if (!skp_osg_nodes) - return; - - if (nodes.size() - 1 != skp_osg_nodes->size()) - return; - - RobOsageNode* i = nodes.data() + 1; - RobOsageNode* i_end = nodes.data() + nodes.size(); - skin_param_osage_node* j = skp_osg_nodes->data(); - skin_param_osage_node* j_end = skp_osg_nodes->data() + skp_osg_nodes->size(); - while (i != i_end && j != j_end) { - i->data_ptr->skp_osg_node = *j++; - i->data_ptr->skp_osg_node.hinge.limit(); - i++; - } -} - -void RobOsage::SetWindDirection(const vec3* value) { - if (value) - wind_direction = *value; - else - wind_direction = 0.0f; -} - -void RobOsage::SetYZOrder(int32_t yz_order) { - this->yz_order = yz_order; -} - -ExOsageBlock::ExOsageBlock() : rob(), mats(), field_1FF8() { - step = 1.0f; - Reset(); +ExOsageBlock::ExOsageBlock() : motion_matrix(), flag() { + init_coma_step = 1.0f; + dest(); } ExOsageBlock::~ExOsageBlock() { - Reset(); + dest(); } -void ExOsageBlock::Init() { - Reset(); +void ExOsageBlock::init() { + dest(); } void ExOsageBlock::CtrlBegin() { done = false; } -void ExOsageBlock::CtrlStep(int32_t stage, bool disable_external_force) { - rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; +void ExOsageBlock::CtrlStep(int32_t stage, bool disable_ex_force) { + const rob_chara_item_equip* rob_disp = skin_disp->rob_disp; float_t delta_frame = get_delta_frame(); #if OPD_PLAY_GEN if (opd_play_gen_run) delta_frame = 1.0f; #endif - float_t step = delta_frame * rob_itm_equip->osage_step; - if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data.front().use_blend) + float_t step = delta_frame * rob_disp->osage_step; + if (rob_disp->opd_blend_data.size() && rob_disp->opd_blend_data.front().use_blend) step = 1.0f; - const mat4& root_matrix = *parent_bone_node->ex_data_mat; - const vec3 parent_scale = parent_bone_node->exp_data.parent_scale; + const mat4& root_matrix = *parent->no_scale_mat; + const vec3 hsc = parent->transform.hsc; switch (stage) { case 0: - rob.BeginCalc(root_matrix, parent_scale, has_children_node); + osage_work.BeginCalc(root_matrix, hsc, has_children_node); break; case 1: case 2: - if ((stage == 1 && is_parent) || (stage == 2 && rob.apply_physics)) { + if ((stage == 1 && is_parent) || (stage == 2 && osage_work.apply_physics)) { SetWindDirection(); - rob.ApplyPhysics(root_matrix, parent_scale, step, - disable_external_force, true, has_children_node); + osage_work.ApplyPhysics(root_matrix, hsc, step, + disable_ex_force, true, has_children_node); } break; case 3: - rob.ColiSet(mats); - rob.CollideNodes(step); + osage_work.make_osage_coli(motion_matrix); + osage_work.CollideNodes(step); break; case 4: - rob.ApplyBocRootColi(step); + osage_work.ApplyBocRootColi(step); break; case 5: { - rob.CollideNodesTargetOsage(root_matrix, parent_scale, step, false); - rob.EndCalc(root_matrix, parent_scale, step, disable_external_force); + osage_work.CollideNodesTargetOsage(root_matrix, hsc, step, false); + osage_work.EndCalc(root_matrix, hsc, step, disable_ex_force); done = true; } break; } } -void ExOsageBlock::CtrlMain() { - field_1FF8 &= ~2; +void ExOsageBlock::ctrl() { + flag.pos_init = 0; if (done) { done = false; return; } - rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; + const rob_chara_item_equip* rob_disp = skin_disp->rob_disp; float_t delta_frame = get_delta_frame(); #if OPD_PLAY_GEN if (opd_play_gen_run) delta_frame = 1.0f; #endif - float_t step = delta_frame * rob_itm_equip->osage_step; - if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data.front().use_blend) + float_t step = delta_frame * rob_disp->osage_step; + if (rob_disp->opd_blend_data.size() && rob_disp->opd_blend_data.front().use_blend) step = 1.0f; - const vec3 parent_scale = parent_bone_node->exp_data.parent_scale; - vec3 scale = parent_bone_node->exp_data.scale; + const vec3 hsc = parent->transform.hsc; + vec3 scale = parent->transform.scale; - mat4 root_matrix = *parent_bone_node->ex_data_mat; + mat4 root_matrix = *parent->no_scale_mat; if (scale.x != 1.0f || scale.y != 1.0f || scale.z != 1.0f) { scale = 1.0f / scale; mat4_scale_rot(&root_matrix, &scale, &root_matrix); } SetWindDirection(); - rob.ColiSet(mats); - rob.CtrlMain(root_matrix, parent_scale, step); + osage_work.make_osage_coli(motion_matrix); + osage_work.ctrl(root_matrix, hsc, step); } void ExOsageBlock::CtrlOsagePlayData() { - rob.CtrlOsagePlayData(*parent_bone_node->ex_data_mat, - parent_bone_node->exp_data.parent_scale, item_equip_object->item_equip->opd_blend_data); + osage_work.CtrlOsagePlayData(*parent->no_scale_mat, + parent->transform.hsc, skin_disp->rob_disp->opd_blend_data); } -void ExOsageBlock::Disp(const mat4& mat, render_context* rctx) { +void ExOsageBlock::disp(const mat4& mat, render_context* rctx) { } -void ExOsageBlock::Reset() { - index = 0; - rob.Reset(); - field_1FF8 &= ~3; - mats = 0; - step = 1.0f; - ExNodeBlock::Reset(); +void ExOsageBlock::dest() { + block_idx = 0; + osage_work.dest(); + flag.alive = 0; + flag.pos_init = 0; + motion_matrix = 0; + init_coma_step = 1.0f; + ExNodeBlock::dest(); } -void ExOsageBlock::Field_40() { +void ExOsageBlock::disp_debug() { } -void ExOsageBlock::CtrlInitBegin() { - step = 4.0f; +void ExOsageBlock::pos_init() { + init_coma_step = 4.0f; SetWindDirection(); - rob.ColiSet(mats); - const vec3 parent_scale = parent_bone_node->exp_data.parent_scale; - rob.CtrlInitBegin(*parent_bone_node->ex_data_mat, parent_scale, false); - field_1FF8 &= ~2; + osage_work.make_osage_coli(motion_matrix); + const vec3 hsc = parent->transform.hsc; + osage_work.pos_init(*parent->no_scale_mat, hsc, false); + flag.pos_init = 0; } -void ExOsageBlock::CtrlInitMain() { +void ExOsageBlock::pos_init_cont() { if (done) { done = false; return; @@ -3283,143 +3348,152 @@ void ExOsageBlock::CtrlInitMain() { SetWindDirection(); - const vec3 parent_scale = parent_bone_node->exp_data.parent_scale; - rob.ColiSet(mats); - rob.CtrlInitMain(*parent_bone_node->ex_data_mat, parent_scale, step, true); - step = max_def(step * 0.5f, 1.0f); + const vec3 hsc = parent->transform.hsc; + osage_work.make_osage_coli(motion_matrix); + osage_work.pos_init_cont(*parent->no_scale_mat, hsc, init_coma_step, true); + init_coma_step = max_def(init_coma_step * 0.5f, 1.0f); } void ExOsageBlock::CtrlEnd() { - const vec3 parent_scale = parent_bone_node->exp_data.parent_scale; - rob.CtrlEnd(parent_scale); + const vec3 hsc = parent->transform.hsc; + osage_work.CtrlEnd(hsc); done = false; } void ExOsageBlock::AddMotionResetData(uint32_t motion_id, float_t frame) { - rob.AddMotionResetData(motion_id, frame); -} - -// 0x1405F3E10 -void ExOsageBlock::GetNodeList(obj_skin_block_osage* osg_data, obj_skin_osage_node* osg_nodes, - prj::vector_pair& osage_node_list, - std::map& node_list) { - RobOsageNode* node = rob.GetNode(0); - osage_node_list.push_back(osg_data->name_index, node); - - for (int32_t i = 0; i < osg_data->count; i++) { - node = rob.GetNode(i + 1ULL); - osage_node_list.push_back(osg_nodes[i].name_index, node); - - if (node->bone_node_ptr && node->bone_node_ptr->name) - node_list.insert({ node->bone_node_ptr->name, this }); - } - - node = rob.GetNode(osg_data->count + 1ULL); - osage_node_list.push_back(osg_data->end_name_index, node); - - if (node->bone_node_ptr && node->bone_node_ptr->name) - node_list.insert({ node->bone_node_ptr->name, this }); -} - -void ExOsageBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, - obj_skin_block_osage* osg_data, const char* osg_data_name, obj_skin_osage_node* osg_nodes, - bone_node* bone_nodes, bone_node* ex_data_bone_nodes, obj_skin* skin) { - ExNodeBlock::InitData(&ex_data_bone_nodes[osg_data->name_index & 0x7FFF], - EX_OSAGE, osg_data_name, itm_eq_obj); - rob.InitData(osg_data, osg_nodes, ex_data_bone_nodes, skin); - field_1FF8 &= ~2; - mats = bone_nodes->mat; + osage_work.AddMotionResetData(motion_id, frame); } const float_t* ExOsageBlock::LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count) { - return rob.LoadOpdData(node_index, opd_data, opd_count); + return osage_work.LoadOpdData(node_index, opd_data, opd_count); } // 0x1405F9510 void ExOsageBlock::SetDisableCollision(const bool& value) { - rob.SetDisableCollision(value); + osage_work.SetDisableCollision(value); } void ExOsageBlock::SetMotionResetData(uint32_t motion_id, float_t frame) { - rob.SetMotionResetData(motion_id, frame); + osage_work.SetMotionResetData(motion_id, frame); } const float_t* ExOsageBlock::SetOsagePlayDataInit(const float_t* opdi_data) { - return rob.SetOsagePlayDataInit(opdi_data); -} - -// 0x1405F9290 -void ExOsageBlock::SetMoveCancel(const float_t& value) { - rob.SetMoveCancel(value); + return osage_work.SetOsagePlayDataInit(opdi_data); } // 0x1405F9A90, but it's combined with RobOsage::SetOsageReset void ExOsageBlock::SetOsageReset() { - rob.SetOsageReset(); + osage_work.SetOsageReset(); } void ExOsageBlock::SetRing(const osage_ring_data& ring) { - rob.SetRing(ring); + osage_work.SetRing(ring); } void ExOsageBlock::SetSkinParam(skin_param_file_data* skp) { - rob.SetSkinParam(skp); + osage_work.SetSkinParam(skp); } void ExOsageBlock::SetWindDirection() { - vec3 wind_direction = task_wind->ptr->wind_direction - * item_equip_object->item_equip->wind_strength; - rob.SetWindDirection(&wind_direction); + vec3 wind_dir = task_wind->stage_wind.wind->val * skin_disp->rob_disp->wind_strength; + osage_work.SetWindDirection(&wind_dir); } -ExConstraintBlock::ExConstraintBlock() : constraint_type(), -source_node_ref(), up_vector_ref(), cns_data() { - Init(); +// 0x1405F3E10 +void ExOsageBlock::get_node_list( + const obj_skin_ex_node_osage* osg_data, const obj_skin_osage_joint* joint, + prj::vector_pair& joint_node_list, + std::map& ex_node_list) { + RobJointNode* root_node = osage_work.get_joint_node(0); + joint_node_list.push_back(osg_data->root_idx, root_node); + + for (uint32_t i = 0; i < osg_data->nb_joint; i++) { + RobJointNode* node = osage_work.get_joint_node(i + 1ULL); + joint_node_list.push_back(joint[i].nid, node); + + if (node->dst_node && node->dst_node->name) + ex_node_list.insert({ node->dst_node->name, this }); + } + + RobJointNode* effector_node = osage_work.get_joint_node(osg_data->nb_joint + 1ULL); + joint_node_list.push_back(osg_data->efc_idx, effector_node); + + if (effector_node->dst_node && effector_node->dst_node->name) + ex_node_list.insert({ effector_node->dst_node->name, this }); +} + +void ExOsageBlock::reset_ex_force() { + osage_work.reset_ex_force(); +} + +// 0x140 +void ExOsageBlock::set_data(const rob_chara_item_equip_object* skp, + const obj_skin_ex_node_osage* root, const char* name, const obj_skin_osage_joint* joint, + const bone_node* mot_node, bone_node* ex_node, const obj_skin* skin) { + ExNodeBlock::set_data(&ex_node[root->root_idx & 0x7FFF], EX_NODE_TYPE_OSAGE, name, skp); + osage_work.init(root, joint, ex_node, skin); + flag.pos_init = 0; + motion_matrix = mot_node->mat_ptr; +} + +void ExOsageBlock::set_ex_force(const vec3& f) { + osage_work.set_ex_force(f); +} + +// 0x1405F9290 +void ExOsageBlock::set_move_cancel(const float_t& mv_ccl) { + osage_work.set_move_cancel(mv_ccl); +} + +ExConstraintBlock::ExConstraintBlock() : cns_type(), src_node(), +upvector_node(), data(), dst_node_id(), src_node_id() { + init(); } ExConstraintBlock::~ExConstraintBlock() { } -void ExConstraintBlock::Init() { - constraint_type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; - source_node_ref = 0; - up_vector_ref = 0; - cns_data = 0; - field_80 = 0; +void ExConstraintBlock::init() { + cns_type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; + src_node = 0; + upvector_node = 0; + data = 0; + dst_node_id = 0; + src_node_id = 0; } void ExConstraintBlock::CtrlBegin() { - if (bone_node_ptr) { - bone_node_expression_data* node_exp_data = &bone_node_ptr->exp_data; - node_exp_data->position = cns_data->node.position; - node_exp_data->rotation = cns_data->node.rotation; - node_exp_data->scale = cns_data->node.scale; + if (dst_node) { + RobTransform& transform = dst_node->transform; + transform.pos = data->transform.position; + transform.rot = data->transform.rotation; + transform.scale = data->transform.scale; } done = false; } -void ExConstraintBlock::CtrlStep(int32_t stage, bool disable_external_force) { +void ExConstraintBlock::CtrlStep(int32_t stage, bool disable_ex_force) { if (done) return; switch (stage) { case 0: if (is_parent) - CtrlMain(); + ctrl(); break; case 2: if (has_children_node) - DataSet(); + CalcMatrixHS(); break; case 5: - CtrlMain(); + ctrl(); break; } } -void ExConstraintBlock::CtrlMain() { - if (!parent_bone_node) +void ExConstraintBlock::ctrl() { + if (!parent) return; if (done) { @@ -3428,67 +3502,67 @@ void ExConstraintBlock::CtrlMain() { } Calc(); - DataSet(); + CalcMatrixHS(); done = true; } void ExConstraintBlock::CtrlOsagePlayData() { - CtrlMain(); + ctrl(); } -void ExConstraintBlock::Disp(const mat4& mat, render_context* rctx) { +void ExConstraintBlock::disp(const mat4& mat, render_context* rctx) { } -void ExConstraintBlock::Field_40() { +void ExConstraintBlock::disp_debug() { } -void ExConstraintBlock::CtrlInitBegin() { - CtrlMain(); +void ExConstraintBlock::pos_init() { + ctrl(); } -void ExConstraintBlock::CtrlInitMain() { - CtrlMain(); +void ExConstraintBlock::pos_init_cont() { + ctrl(); } void ExConstraintBlock::Calc() { - bone_node* node = bone_node_ptr; + bone_node* node = dst_node; if (!node) return; - vec3 pos = parent_bone_node->exp_data.parent_scale * node->exp_data.position; + vec3 pos = parent->transform.hsc * node->transform.pos; mat4 mat; - mat4_mul_translate(parent_bone_node->ex_data_mat, &pos, &mat); + mat4_mul_translate(parent->no_scale_mat, &pos, &mat); - switch (constraint_type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + switch (cns_type) { + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: CalcConstraintOrientation(mat); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: CalcConstraintDirection(mat); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: CalcConstraintPosition(mat); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: CalcConstraintDistance(mat); break; default: - *node->mat = mat; + *node->mat_ptr = mat; break; } } inline void ExConstraintBlock::CalcConstraintDirection(mat4 mat) { - obj_skin_block_constraint_direction* direction = cns_data->direction; + obj_skin_ex_node_constraint_direction* direction = data->direction; vec3 align_axis = direction->align_axis; vec3 target_offset = direction->target_offset; vec3 world_offset; - mat4_transform_point(source_node_ref->mat, &target_offset, &world_offset); + mat4_transform_point(src_node->mat_ptr, &target_offset, &world_offset); vec3 v51; mat4_inverse_transform_point(&mat, &world_offset, &v51); @@ -3499,7 +3573,7 @@ inline void ExConstraintBlock::CalcConstraintDirection(mat4 mat) { mat4 rot_mat; bone_data::orient_to_target(rot_mat, align_axis, v51); - if (up_vector_ref) { + if (upvector_node) { vec3 affected_axis = direction->up_vector.affected_axis; mat4 dir_mat; @@ -3508,7 +3582,7 @@ inline void ExConstraintBlock::CalcConstraintDirection(mat4 mat) { vec3 dir_axis; mat4_transform_vector(&dir_mat, &affected_axis, &dir_axis); - mat4* up_mat = up_vector_ref->mat; + mat4* up_mat = upvector_node->mat_ptr; vec3 up_vector_trans; vec3 post_dir_trans; @@ -3537,39 +3611,39 @@ inline void ExConstraintBlock::CalcConstraintDirection(mat4 mat) { mat4_mul(&rot_mat, &up_corr_mat, &rot_mat); } - mat4_mul(&rot_mat, &mat, bone_node_ptr->mat); + mat4_mul(&rot_mat, &mat, dst_node->mat_ptr); } void ExConstraintBlock::CalcConstraintDistance(mat4 mat) { - *bone_node_ptr->mat = mat; + *dst_node->mat_ptr = mat; } void ExConstraintBlock::CalcConstraintOrientation(mat4 mat) { - obj_skin_block_constraint_orientation* orientation = cns_data->orientation; + obj_skin_ex_node_constraint_orientation* orientation = data->orientation; mat3 rot; - mat4_to_mat3(source_node_ref->mat, &rot); + mat4_to_mat3(src_node->mat_ptr, &rot); mat3_normalize_rotation(&rot, &rot); mat3_mul_rotate_zyx(&rot, &orientation->offset, &rot); - mat4_replace_rotation(&mat, &rot, bone_node_ptr->mat); + mat4_replace_rotation(&mat, &rot, dst_node->mat_ptr); } void ExConstraintBlock::CalcConstraintPosition(mat4 mat) { - obj_skin_block_constraint_position* position = cns_data->position; + obj_skin_ex_node_constraint_position* position = data->position; vec3 constraining_offset = position->constraining_object.offset; vec3 constrained_offset = position->constrained_object.offset; if (position->constraining_object.affected_by_orientation) - mat4_transform_vector(source_node_ref->mat, &constraining_offset, &constraining_offset); + mat4_transform_vector(src_node->mat_ptr, &constraining_offset, &constraining_offset); vec3 source_node_trans; - mat4_get_translation(source_node_ref->mat, &source_node_trans); + mat4_get_translation(src_node->mat_ptr, &source_node_trans); source_node_trans = constraining_offset + source_node_trans; mat4_set_translation(&mat, &source_node_trans); - if (up_vector_ref) { + if (upvector_node) { vec3 up_vector_trans; - mat4_get_translation(up_vector_ref->mat, &up_vector_trans); + mat4_get_translation(upvector_node->mat_ptr, &up_vector_trans); mat4_inverse_transform_point(&mat, &up_vector_trans, &up_vector_trans); mat4 rot_mat; @@ -3582,72 +3656,107 @@ void ExConstraintBlock::CalcConstraintPosition(mat4 mat) { mat4 constrained_offset_mat; mat4_translate(&constrained_offset, &constrained_offset_mat); - mat4_mul(&mat, &constrained_offset_mat, bone_node_ptr->mat); + mat4_mul(&mat, &constrained_offset_mat, dst_node->mat_ptr); } -void ExConstraintBlock::DataSet() { - if (!bone_node_ptr) +void ExConstraintBlock::CalcMatrixHS() { + if (!dst_node) return; - bone_node_expression_data* exp_data = &bone_node_ptr->exp_data; - const vec3 parent_scale = parent_bone_node->exp_data.parent_scale; + RobTransform& transform = dst_node->transform; + const vec3 hsc = parent->transform.hsc; mat4 mat; - mat4_invert_fast(parent_bone_node->ex_data_mat, &mat); - mat4_mul(bone_node_ptr->mat, &mat, &mat); - mat4_get_rotation_zyx(&mat, &exp_data->rotation); - mat4_get_translation(&mat, &exp_data->position); - if (fabsf(parent_scale.x) > 0.000001f) - exp_data->position.x /= parent_scale.x; - if (fabsf(parent_scale.y) > 0.000001f) - exp_data->position.y /= parent_scale.z; - if (fabsf(parent_scale.z) > 0.000001f) - exp_data->position.z /= parent_scale.z; - *bone_node_ptr->ex_data_mat = *bone_node_ptr->mat; - mat4_scale_rot(bone_node_ptr->mat, &parent_scale, bone_node_ptr->mat); - exp_data->parent_scale = exp_data->scale * parent_scale; + mat4_invert_fast(parent->no_scale_mat, &mat); + mat4_mul(dst_node->mat_ptr, &mat, &mat); + mat4_get_rotation_zyx(&mat, &transform.rot); + mat4_get_translation(&mat, &transform.pos); + if (fabsf(hsc.x) > 0.000001f) + transform.pos.x /= hsc.x; + if (fabsf(hsc.y) > 0.000001f) + transform.pos.y /= hsc.z; + if (fabsf(hsc.z) > 0.000001f) + transform.pos.z /= hsc.z; + *dst_node->no_scale_mat = *dst_node->mat_ptr; + mat4_scale_rot(dst_node->mat_ptr, &hsc, dst_node->mat_ptr); + transform.hsc = transform.scale * hsc; } -void ExConstraintBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, - obj_skin_block_constraint* cns_data, const char* cns_data_name, const bone_database* bone_data) { - bone_node* node = itm_eq_obj->get_bone_node(cns_data_name, bone_data); - type = EX_CONSTRAINT; - bone_node_ptr = node; - this->cns_data = cns_data; - name = node->name; - item_equip_object = itm_eq_obj; - source_node_ref = itm_eq_obj->get_bone_node(cns_data->source_node_name, bone_data); +void ExConstraintBlock::set_data(const rob_chara_item_equip_object* skin_disp, + const obj_skin_ex_node_constraint* data, const char* name, const bone_database* bone_data) { + bone_node* node = (bone_node*)skin_disp->get_node(name, bone_data); + type = EX_NODE_TYPE_CONSTRAINT; + dst_node = node; + this->data = data; + this->name = node->name; + this->skin_disp = skin_disp; - obj_skin_block_constraint_type type = cns_data->type; + src_node = skin_disp->get_node(data->src_name, bone_data); + + obj_skin_ex_node_constraint_type type = data->type; const char* up_vector_name; - if (type == OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION) { - constraint_type = OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION; - up_vector_name = cns_data->direction->up_vector.name; + if (type == OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION) { + cns_type = OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION; + up_vector_name = data->direction->up_vector.name; } - else if (type == OBJ_SKIN_BLOCK_CONSTRAINT_POSITION) { - constraint_type = OBJ_SKIN_BLOCK_CONSTRAINT_POSITION; - up_vector_name = cns_data->position->up_vector.name; + else if (type == OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION) { + cns_type = OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION; + up_vector_name = data->position->up_vector.name; } - else if (type == OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE) { - constraint_type = OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE; - up_vector_name = cns_data->distance->up_vector.name; + else if (type == OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE) { + cns_type = OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE; + up_vector_name = data->distance->up_vector.name; } - else if (type == OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION) { - constraint_type = OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION; + else if (type == OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION) { + cns_type = OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION; return; } else { - constraint_type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns_type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; return; } if (up_vector_name) - up_vector_ref = itm_eq_obj->get_bone_node(up_vector_name, bone_data); + upvector_node = skin_disp->get_node(up_vector_name, bone_data); } -ExExpressionBlock::ExExpressionBlock() : values(), types(), expressions(), -stack_data(), exp_data(), field_3D20(), field_3D28(), frame(), step(true) { +float_t Expr_node::eval() { + float_t value = 0.0f; + switch (type) { + case Expr_constant: + value = data.constant; + break; + case Expr_variable: + value = *data.variable; + break; + case Expr_variable_rad: + value = *data.variable * RAD_TO_DEG_FLOAT; + break; + case Expr_func1: { + float_t v1 = operand[0]->eval(); + if (data.func1) + value = data.func1(v1); + } break; + case Expr_func2: { + float_t v1 = operand[0]->eval(); + float_t v2 = operand[1]->eval(); + if (data.func1) + value = data.func2(v1, v2); + } break; + case Expr_func3: { + float_t v1 = operand[0]->eval(); + float_t v2 = operand[1]->eval(); + float_t v3 = operand[2]->eval(); + if (data.func3) + value = data.func3(v1, v2, v3); + } break; + } + return value; +} + +ExExpressionBlock::ExExpressionBlock() : result(), result_type(), expr_node(), +expr_work(), data(), field_3D20(), hard_coded_func(), timer(), step(true) { } @@ -3655,39 +3764,39 @@ ExExpressionBlock::~ExExpressionBlock() { } -void ExExpressionBlock::Init() { - frame = 0.0f; +void ExExpressionBlock::init() { + timer = 0.0f; } void ExExpressionBlock::CtrlBegin() { - bone_node_expression_data* node_exp_data = &bone_node_ptr->exp_data; - node_exp_data->position = exp_data->node.position; - node_exp_data->rotation = exp_data->node.rotation; - node_exp_data->scale = exp_data->node.scale; + RobTransform& transform = dst_node->transform; + transform.pos = data->transform.position; + transform.rot = data->transform.rotation; + transform.scale = data->transform.scale; done = false; } -void ExExpressionBlock::CtrlStep(int32_t stage, bool disable_external_force) { +void ExExpressionBlock::CtrlStep(int32_t stage, bool disable_ex_force) { if (done) return; switch (stage) { case 0: if (is_parent) - CtrlMain(); + ctrl(); break; case 2: if (has_children_node) - DataSet(); + CalcMatrixHS(); break; case 5: - CtrlMain(); + ctrl(); break; } } -void ExExpressionBlock::CtrlMain() { - if (!parent_bone_node) +void ExExpressionBlock::ctrl() { + if (!parent) return; if (done) { @@ -3696,28 +3805,28 @@ void ExExpressionBlock::CtrlMain() { } Calc(); - DataSet(); + CalcMatrixHS(); done = true; } void ExExpressionBlock::CtrlOsagePlayData() { - CtrlMain(); + ctrl(); } -void ExExpressionBlock::Disp(const mat4& mat, render_context* rctx) { +void ExExpressionBlock::disp(const mat4& mat, render_context* rctx) { } -void ExExpressionBlock::Field_40() { +void ExExpressionBlock::disp_debug() { } -void ExExpressionBlock::CtrlInitBegin() { - CtrlMain(); +void ExExpressionBlock::pos_init() { + ctrl(); } -void ExExpressionBlock::CtrlInitMain() { - CtrlMain(); +void ExExpressionBlock::pos_init_cont() { + ctrl(); } void ExExpressionBlock::Calc() { @@ -3727,74 +3836,74 @@ void ExExpressionBlock::Calc() { delta_frame = 1.0f; #endif if (step) - delta_frame *= item_equip_object->item_equip->osage_step; - float_t frame = this->frame + delta_frame; - this->frame = frame >= 65535.0f ? frame - 65535.0f : frame; + delta_frame *= skin_disp->rob_disp->osage_step; + float_t timer = this->timer + delta_frame; + this->timer = timer >= 65535.0f ? timer - 65535.0f : timer; - if (field_3D28) { - field_3D28(&bone_node_ptr->exp_data); + if (hard_coded_func) { + hard_coded_func(&dst_node->transform); return; } for (int32_t i = 0; i < 9; i++) { - if (!expressions[i]) + if (!expr_node[i]) break; - float_t value = ex_expression_block_stack_get_value(expressions[i]); - if (types[i] == EX_EXPRESSION_BLOCK_STACK_VARIABLE_RADIAN) + float_t value = expr_node[i]->eval(); + if (result_type[i] == Expr_variable_rad) value *= DEG_TO_RAD_FLOAT; - *values[i] = value; + *result[i] = value; } } -void ExExpressionBlock::DataSet() { - bone_node_expression_data* data = &bone_node_ptr->exp_data; - const vec3 parent_scale = parent_bone_node->exp_data.parent_scale; - mat4 ex_data_mat = *parent_bone_node->ex_data_mat; - mat4 mat = mat4_identity; - data->mat_set(parent_scale, ex_data_mat, mat); - *bone_node_ptr->mat = mat; - *bone_node_ptr->ex_data_mat = ex_data_mat; +void ExExpressionBlock::CalcMatrixHS() { + RobTransform* data = &dst_node->transform; + const vec3 hsc = parent->transform.hsc; + mat4 mat = *parent->no_scale_mat; + mat4 dsp_mat = mat4_identity; + data->CalcMatrixHS(hsc, mat, dsp_mat); + *dst_node->mat_ptr = dsp_mat; + *dst_node->no_scale_mat = mat; } -void ExExpressionBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, - obj_skin_block_expression* exp_data, const char* exp_data_name, object_info a4, +void ExExpressionBlock::set_data(const rob_chara_item_equip_object* skin_disp, + const obj_skin_ex_node_expression* data, const char* node_name, object_info a4, size_t index, const bone_database* bone_data) { - ex_expression_block_stack* stack_buf[28]; - ex_expression_block_stack** stack_buf_val = stack_buf; + Expr_node* stack_buf[28]; + Expr_node** stack_buf_val = stack_buf; - bone_node* node = itm_eq_obj->get_bone_node(exp_data_name, bone_data); - type = EX_EXPRESSION; - bone_node_ptr = node; - this->exp_data = exp_data; - name = node->name; - item_equip_object = itm_eq_obj; + bone_node* node = (bone_node*)skin_disp->get_node(node_name, bone_data); + type = EX_NODE_TYPE_EXPRESSION; + dst_node = node; + this->data = data; + this->name = node->name; + this->skin_disp = skin_disp; - node->exp_data.position = exp_data->node.position; - node->exp_data.rotation = exp_data->node.rotation; - node->exp_data.scale = exp_data->node.scale; - field_3D28 = 0; + node->transform.pos = data->transform.position; + node->transform.rot = data->transform.rotation; + node->transform.scale = data->transform.scale; + hard_coded_func = 0; - ex_expression_block_stack* stack_val = stack_data; + Expr_node* expr = expr_work; for (int32_t i = 0; i < 9; i++) { - values[i] = 0; - expressions[i] = 0; + result[i] = 0; + expr_node[i] = 0; } for (int32_t i = 0; i < 9; i++) { - const char* expression = exp_data->expression_array[i]; - if (!expression || str_utils_compare_length(expression, utf8_length(expression), "= ", 2)) + const char* script = data->script[i]; + if (!script || str_utils_compare_length(script, utf8_length(script), "= ", 2)) break; - expression += 2; + script += 2; int32_t index = 0; - expression = str_utils_get_next_int32_t(expression, index, ' '); - values[i] = bone_node_ptr->get_exp_data_component(index, types[i]); + script = str_utils_get_next_int32_t(script, index, ' '); + result[i] = dst_node->get_transform_component(index, result_type[i]); - while (expression) { + while (script) { std::string value_type; - expression = str_utils_get_next_string(expression, value_type, ' '); + script = str_utils_get_next_string(script, value_type, ' '); if (!value_type.size() || !memcmp(value_type.c_str(), "error", min_def(value_type.size(), 5)) && value_type.size() == 5) { printf_debug_info("Expression error: %s.", this->name); @@ -3806,97 +3915,93 @@ void ExExpressionBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, } if (value_type[0] == 'n') { - stack_val->type = EX_EXPRESSION_BLOCK_STACK_NUMBER; - expression = str_utils_get_next_float_t(expression, stack_val->number.value, ' '); - *stack_buf_val++ = stack_val; + expr->type = Expr_constant; + script = str_utils_get_next_float_t(script, expr->data.constant, ' '); + *stack_buf_val++ = expr; } else if (value_type[0] == 'v') { std::string func_str; - expression = str_utils_get_next_string(expression, func_str, ' '); - stack_val->type = EX_EXPRESSION_BLOCK_STACK_VARIABLE; + script = str_utils_get_next_string(script, func_str, ' '); + expr->type = Expr_variable; int32_t index = func_str[0] - '0'; if (index >= 0 && index < 9) { - bone_node* node = itm_eq_obj->get_bone_node(func_str.c_str() + 2, bone_data); + const bone_node* node = skin_disp->get_node(func_str.c_str() + 2, bone_data); if (node) - stack_val->var.value = node->get_exp_data_component(index, stack_val->type); + expr->data.variable = node->get_transform_component(index, expr->type); else { - stack_val->type = EX_EXPRESSION_BLOCK_STACK_NUMBER; - stack_val->number.value = 0.0f; + expr->type = Expr_constant; + expr->data.constant = 0.0f; } } else - stack_val->var.value = &frame; - *stack_buf_val++ = stack_val; + expr->data.variable = &timer; + *stack_buf_val++ = expr; } else if (value_type[0] == 'f') { std::string func_str; - expression = str_utils_get_next_string(expression, func_str, ' '); - stack_val->type = EX_EXPRESSION_BLOCK_STACK_OP1; - stack_val->op1.v1 = stack_buf_val[-1]; - stack_val->op1.func = exp_func_op1_find_func(func_str, exp_func_op1_array)->func; - stack_buf_val[-1] = stack_val; + script = str_utils_get_next_string(script, func_str, ' '); + expr->type = Expr_func1; + expr->operand[0] = stack_buf_val[-1]; + expr->data.func1 = ExpFuncUnaryTblFindFunc(func_str, exp_func_unary_tbl)->func; + stack_buf_val[-1] = expr; } else if (value_type[0] == 'g') { std::string func_str; - expression = str_utils_get_next_string(expression, func_str, ' '); - stack_val->type = EX_EXPRESSION_BLOCK_STACK_OP2; - stack_val->op2.v1 = stack_buf_val[-2]; - stack_val->op2.v2 = stack_buf_val[-1]; - stack_val->op2.func = exp_func_op2_find_func(func_str, exp_func_op2_array)->func; - stack_buf_val[-2] = stack_val; + script = str_utils_get_next_string(script, func_str, ' '); + expr->type = Expr_func2; + expr->operand[0] = stack_buf_val[-2]; + expr->operand[1] = stack_buf_val[-1]; + expr->data.func2 = ExpFuncBinaryTblFindFunc(func_str, exp_func_binary_tbl)->func; + stack_buf_val[-2] = expr; stack_buf_val--; } else if (value_type[0] == 'h') { std::string func_str; - expression = str_utils_get_next_string(expression, func_str, ' '); - stack_val->type = EX_EXPRESSION_BLOCK_STACK_OP3; - stack_val->op3.v1 = stack_buf_val[-3]; - stack_val->op3.v2 = stack_buf_val[-2]; - stack_val->op3.v3 = stack_buf_val[-1]; - stack_val->op3.func = exp_func_op3_find_func(func_str, exp_func_op3_array)->func; - stack_buf_val[-3] = stack_val; + script = str_utils_get_next_string(script, func_str, ' '); + expr->type = Expr_func3; + expr->operand[0] = stack_buf_val[-3]; + expr->operand[1] = stack_buf_val[-2]; + expr->operand[2] = stack_buf_val[-1]; + expr->data.func3 = ExpFuncTernaryTblFindFunc(func_str, exp_func_ternary_tbl)->func; + stack_buf_val[-3] = expr; stack_buf_val -= 2; } - expressions[i] = stack_buf_val[-1]; - stack_val++; + expr_node[i] = stack_buf_val[-1]; + expr++; } } step = !((ssize_t)index - ITEM_TE_R <= 1); } -static float_t ex_expression_block_stack_get_value(ex_expression_block_stack* stack) { - float_t value = 0.0f; - switch (stack->type) { - case EX_EXPRESSION_BLOCK_STACK_NUMBER: - value = stack->number.value; - break; - case EX_EXPRESSION_BLOCK_STACK_VARIABLE: - value = *stack->var.value; - break; - case EX_EXPRESSION_BLOCK_STACK_VARIABLE_RADIAN: - value = *stack->var_rad.value * RAD_TO_DEG_FLOAT; - break; - case EX_EXPRESSION_BLOCK_STACK_OP1: { - float_t v1 = ex_expression_block_stack_get_value(stack->op1.v1); - if (stack->op1.func) - value = stack->op1.func(v1); - } break; - case EX_EXPRESSION_BLOCK_STACK_OP2: { - float_t v1 = ex_expression_block_stack_get_value(stack->op2.v1); - float_t v2 = ex_expression_block_stack_get_value(stack->op2.v2); - if (stack->op2.func) - value = stack->op2.func(v1, v2); - } break; - case EX_EXPRESSION_BLOCK_STACK_OP3: { - float_t v1 = ex_expression_block_stack_get_value(stack->op1.v1); - float_t v2 = ex_expression_block_stack_get_value(stack->op2.v2); - float_t v3 = ex_expression_block_stack_get_value(stack->op3.v3); - if (stack->op3.func) - value = stack->op3.func(v1, v2, v3); - } break; +static const ExpFuncUnaryTbl* ExpFuncUnaryTblFindFunc(std::string& name, const ExpFuncUnaryTbl* array) { + const char* name_str = name.c_str(); + while (array->name) { + if (!str_utils_compare(name_str, array->name)) + return array; + array++; } - return value; + return 0; +} + +static const ExpFuncBinaryTbl* ExpFuncBinaryTblFindFunc(std::string& name, const ExpFuncBinaryTbl* array) { + const char* name_str = name.c_str(); + while (array->name) { + if (!str_utils_compare(name_str, array->name)) + return array; + array++; + } + return 0; +} + +static const ExpFuncTernaryTbl* ExpFuncTernaryTblFindFunc(std::string& name, const ExpFuncTernaryTbl* array) { + const char* name_str = name.c_str(); + while (array->name) { + if (!str_utils_compare(name_str, array->name)) + return array; + array++; + } + return 0; } static float_t exp_abs(float_t v1) { @@ -3959,36 +4064,6 @@ static float_t exp_fmod(float_t v1, float_t v2) { return fmodf(v1, v2); } -static const exp_func_op1* exp_func_op1_find_func(std::string& name, const exp_func_op1* array) { - const char* name_str = name.c_str(); - while (array->name) { - if (!str_utils_compare(name_str, array->name)) - return array; - array++; - } - return 0; -} - -static const exp_func_op2* exp_func_op2_find_func(std::string& name, const exp_func_op2* array) { - const char* name_str = name.c_str(); - while (array->name) { - if (!str_utils_compare(name_str, array->name)) - return array; - array++; - } - return 0; -} - -static const exp_func_op3* exp_func_op3_find_func(std::string& name, const exp_func_op3* array) { - const char* name_str = name.c_str(); - while (array->name) { - if (!str_utils_compare(name_str, array->name)) - return array; - array++; - } - return 0; -} - static float_t exp_ge(float_t v1, float_t v2) { return v1 >= v2 ? 1.0f : 0.0f; } @@ -4078,13 +4153,26 @@ static void apply_gravity(vec3& vec, const vec3& p0, const vec3& p1, vec = vec3(0.0f, -(gravity * weight), 0.0f) - (diff * diff.y * (gravity * weight)); } -// 0x14021A5E0 -static float_t calculate_tbn(const vec3& pos_a, const vec3& pos_b, - const float_t uv_a_y, const float_t uv_b_y, - vec3& tangent, vec3& binormal, vec3& normal) { - normal = vec3::normalize(vec3::cross(pos_a, pos_b)); +// 0x14021A290 +static float_t calc_tangent_basis(const vec3& p0, const vec3& p1, const vec3& p2, + const vec2& uv0, const vec2& uv1, const vec2& uv2, vec3& tangent, vec3& binormal, vec3& normal) { + vec3 v1 = p1 - p0; + vec3 v2 = p2 - p0; - vec3 _tangent = vec3::normalize(pos_a * uv_b_y - pos_b * uv_a_y); + normal = vec3::cross(v1, v2); + + float_t normal_length = vec3::length(normal); + if (normal_length <= 0.000001f) + return 1.0f; + + normal *= 1.0f / normal_length; + + vec2 t1 = uv1 - uv0; + vec2 t2 = uv2 - uv0; + + float_t r = 1.0f / (t2.y * t1.x - t1.y * t2.x); + + vec3 _tangent = vec3::normalize((v1 * t2.y - v2 * t1.y) * r); binormal = vec3::cross(_tangent, normal); tangent = vec3::cross(normal, binormal); @@ -4093,27 +4181,12 @@ static float_t calculate_tbn(const vec3& pos_a, const vec3& pos_b, return mat3_determinant(&mat); } -// 0x14021A290 -static float_t calculate_tbn(const vec3& trans_a, const vec3& trans_b, const vec3& trans_c, - const vec2& texcoord_a, const vec2& texcoord_b, const vec2& texcoord_c, - vec3& tangent, vec3& binormal, vec3& normal) { - vec3 pos_a = trans_b - trans_a; - vec3 pos_b = trans_c - trans_a; +// 0x14021A5E0 +static float_t calc_tangent_basis(const vec3& v1, const vec3& v2, + const float_t t1, const float_t t2, vec3& tangent, vec3& binormal, vec3& normal) { + normal = vec3::normalize(vec3::cross(v1, v2)); - normal = vec3::cross(pos_a, pos_b); - - float_t normal_length = vec3::length(normal); - if (normal_length <= 0.000001f) - return 1.0f; - - normal *= 1.0f / normal_length; - - vec2 uv_a = texcoord_b - texcoord_a; - vec2 uv_b = texcoord_c - texcoord_a; - - float_t r = 1.0f / (uv_b.y * uv_a.x - uv_a.y * uv_b.x); - - vec3 _tangent = vec3::normalize((pos_a * uv_b.y - pos_b * uv_a.y) * r); + vec3 _tangent = vec3::normalize(v1 * t2 - v2 * t1); binormal = vec3::cross(_tangent, normal); tangent = vec3::cross(normal, binormal); @@ -4122,6 +4195,27 @@ static float_t calculate_tbn(const vec3& trans_a, const vec3& trans_b, const vec return mat3_determinant(&mat); } +// 0x14021A890 +static void calc_tangent_basis_sub(CLOTH_VERTEX* vtx, const CLOTH_VERTEX* vtxL, const CLOTH_VERTEX* vtxR, + const CLOTH_VERTEX* vtxU, const CLOTH_VERTEX* vtxD) { + const vec3 v1 = vtxU->pos - vtxD->pos; + const vec3 v2 = vtxR->pos - vtxL->pos; + + const float_t v2_length = vec3::length(v1); + const float_t v1_length = vec3::length(v2); + if (v2_length <= 0.000001f || v1_length <= 0.000001f) + return; + + const vec2 uv_a = vtxU->uv - vtxD->uv; + const vec2 uv_b = vtxR->uv - vtxL->uv; + + float_t r = uv_b.y * uv_a.x - uv_a.y * uv_b.x; + if (fabsf(r) > 0.000001f) { + r = 1.0f / r; + vtx->m = calc_tangent_basis(v1, v2, uv_a.y * r, uv_b.y * r, vtx->tangent, vtx->binormal, vtx->normal); + } +} + // 0x140484850 static void closest_pt_segment_segment(vec3& vec, const vec3& p0, const vec3& q0, const OsageCollision::Work* cls) { const vec3& p1 = cls->pos[0]; @@ -4182,23 +4276,31 @@ static void closest_pt_segment_segment(vec3& vec, const vec3& p0, const vec3& q0 } } +// 0x140482F30 +static void length_limit(vec3& p, const vec3& r, float_t rr) { + const vec3 d = p - r; + const float_t dist = vec3::length_squared(d); + if (dist > rr * rr) + p = r + d * (rr / sqrtf(dist)); +} + // 0x140482FF0 -static bool rotate_matrix_to_direction(mat4& mat, const vec3& direction, - const skin_param_hinge* hinge, vec3* rot, const int32_t& yz_order) { +static bool make_axis_matrix(mat4& mat, const vec3& axis, + const skin_param_hinge* hinge, vec3* rot, const ROTTYPE& rottype) { bool rot_clamped = false; float_t z_rot; float_t y_rot; - if (yz_order == 1) { - y_rot = atan2f(-direction.z, direction.x); - z_rot = atan2f(direction.y, sqrtf(direction.x * direction.x + direction.z * direction.z)); + if (rottype == ROTTYPE_ZY) { + y_rot = atan2f(-axis.z, axis.x); + z_rot = atan2f(axis.y, sqrtf(axis.x * axis.x + axis.z * axis.z)); if (hinge) rot_clamped = hinge->clamp(y_rot, z_rot); mat4_mul_rotate_y(&mat, y_rot, &mat); mat4_mul_rotate_z(&mat, z_rot, &mat); } else { - z_rot = atan2f(direction.y, direction.x); - y_rot = atan2f(-direction.z, sqrtf(direction.x * direction.x + direction.y * direction.y)); + z_rot = atan2f(axis.y, axis.x); + y_rot = atan2f(-axis.z, sqrtf(axis.x * axis.x + axis.y * axis.y)); if (hinge) rot_clamped = hinge->clamp(y_rot, z_rot); mat4_mul_rotate_z(&mat, z_rot, &mat); @@ -4212,155 +4314,149 @@ static bool rotate_matrix_to_direction(mat4& mat, const vec3& direction, return rot_clamped; } -// 0x140482F30 -static void segment_limit_distance(vec3& p0, const vec3& p1, float_t max_distance) { - const vec3 d = p0 - p1; - const float_t dist = vec3::length_squared(d); - if (dist > max_distance * max_distance) - p0 = p1 + d * (max_distance / sqrtf(dist)); -} - -// 0x14047C800 -void RobOsage::ApplyPhysics(const mat4& root_matrix, const vec3& parent_scale, - const float_t step, bool disable_external_force, bool ring_coli, bool has_children_node) { - if (!nodes.size()) +static void modify_cloth_object(obj_mesh* mesh, obj_mesh_vertex_buffer* vb, + CLOTH_VERTEX* vtxarg, float_t sgn, int32_t num_idx, uint16_t* idxtbl, bool do_ura) { + if (!mesh || !vb || (mesh->vertex_format + & (OBJ_VERTEX_NORMAL | OBJ_VERTEX_POSITION)) != (OBJ_VERTEX_NORMAL | OBJ_VERTEX_POSITION)) return; - const float_t osage_gravity_const = get_osage_gravity_const(); - BeginCalc(root_matrix, parent_scale, false); - - RobOsageNode* node = &nodes.data()[0]; - node->fixed_pos = node->pos; - const vec3 v113 = exp_data.position * parent_scale; - - mat4 v130 = root_matrix; - mat4_transform_point(&v130, &v113, &node->pos); - node->delta_pos = node->pos - node->fixed_pos; - - RotateMat(v130, parent_scale); - *nodes.data()[0].bone_node_mat = v130; - *nodes.data()[0].bone_node_ptr->ex_data_mat = v130; - - vec3 direction = { 1.0f, 0.0f, 0.0f }; - mat4_transform_vector(&v130, &direction, &direction); - - if (!osage_reset && (get_pause() || step <= 0.0f)) + vb->cycle_index(); + GL::ArrayBuffer buffer = vb->get_buffer(); + size_t data = (size_t)buffer.MapMemory(gl_state); + if (!data) return; - const bool stiffness = skin_param_ptr->stiffness > 0.0f; + if (do_ura) + num_idx /= 2; - RobOsageNode* v26_begin = nodes.data() + 1; - RobOsageNode* v26_end = nodes.data() + nodes.size(); - for (RobOsageNode* v26 = v26_begin; v26 != v26_end; v26++) { - float_t weight = v26->data_ptr->skp_osg_node.weight; - vec3 force; - if (!set_external_force) { - apply_gravity(force, v26->pos, v26->GetPrevNode().pos, osage_gravity_const, weight); + bool tangent = !!(mesh->vertex_format & OBJ_VERTEX_TANGENT); - if (v26 != v26_end - 1) { - vec3 _force; - apply_gravity(_force, v26->pos, v26->GetNextNode().pos, osage_gravity_const, weight); - force = (force + _force) * 0.5f; + switch (mesh->attrib.m.compression) { + case 0: + default: + if (tangent) + for (int32_t i = 2; i; i--, sgn = -1.0f) { + for (int32_t j = num_idx; j; j--, idxtbl++) { + CLOTH_VERTEX* vtx = &vtxarg[*idxtbl]; + + *(vec3*)data = vtx->pos; + *(vec3*)(data + 0x0C) = vtx->normal * sgn; + *(vec3*)(data + 0x18) = vtx->tangent; + *(float_t*)(data + 0x24) = vtx->m; + + data += mesh->size_vertex; + } + + if (!do_ura) + break; } - } else - force = external_force * (1.0f / weight); + for (int32_t i = 2; i; i--, sgn = -1.0f) { + for (int32_t j = num_idx; j; j--, idxtbl++) { + CLOTH_VERTEX* vtx = &vtxarg[*idxtbl]; - const vec3 _direction = direction * (v26->data_ptr->force * v26->force); - const float_t fric = (1.0f - inertia) * (1.0f - skin_param_ptr->air_res); + *(vec3*)data = vtx->pos; + *(vec3*)(data + 0x0C) = vtx->normal * sgn; - vec3 vel = force + _direction - v26->delta_pos * fric + v26->external_force * weight; + data += mesh->size_vertex; + } - if (!disable_external_force) - vel += wind_direction * skin_param_ptr->wind_afc; + if (!do_ura) + break; + } + break; + case 1: + if (tangent) + for (int32_t i = 2; i; i--, sgn = -1.0f) { + for (int32_t j = num_idx; j; j--, idxtbl++) { + CLOTH_VERTEX* vtx = &vtxarg[*idxtbl]; - if (stiffness) - vel -= (v26->delta_pos - v26->GetPrevNode().delta_pos) * (1.0f - skin_param_ptr->air_res); + *(vec3*)data = vtx->pos; - v26->vel = vel * (1.0f / (weight - (weight - 1.0f) * v26->data_ptr->skp_osg_node.inertial_cancel)); + vec3_to_vec3i16(vtx->normal * (32767.0f * sgn), *(vec3i16*)(data + 0x0C)); + *(int16_t*)(data + 0x12) = 0; + + vec4 tangent; + *(vec3*)&tangent = vtx->tangent; + tangent.w = vtx->m; + vec4_to_vec4i16(tangent * 32767.0f, *(vec4i16*)(data + 0x14)); + + data += mesh->size_vertex; + } + + if (!do_ura) + break; + } + else + for (int32_t i = 2; i; i--, sgn = -1.0f) { + for (int32_t j = num_idx; j; j--, idxtbl++) { + CLOTH_VERTEX* vtx = &vtxarg[*idxtbl]; + + *(vec3*)data = vtx->pos; + + vec3_to_vec3i16(vtx->normal * (32767.0f * sgn), *(vec3i16*)(data + 0x0C)); + *(int16_t*)(data + 0x12) = 0; + + data += mesh->size_vertex; + } + + if (!do_ura) + break; + } + case 2: + if (tangent) + for (int32_t i = 2; i; i--, sgn = -1.0f) { + for (int32_t j = num_idx; j; j--, idxtbl++) { + CLOTH_VERTEX* vtx = &vtxarg[*idxtbl]; + + *(vec3*)data = vtx->pos; + + vec3i16 normal_int; + vec3_to_vec3i16(vtx->normal * 511.0f, normal_int); + *(uint32_t*)(data + 0x0C) = (((uint32_t)0 & 0x03) << 30) + | (((uint32_t)normal_int.z & 0x3FF) << 20) + | (((uint32_t)normal_int.y & 0x3FF) << 10) + | ((uint32_t)normal_int.x & 0x3FF); + + vec4 tangent; + *(vec3*)&tangent = vtx->tangent; + tangent.w = vtx->m; + + vec4i16 tangent_int; + vec4_to_vec4i16(tangent * 511.0f, tangent_int); + *(uint32_t*)(data + 0x10) = (((uint32_t)clamp_def(tangent_int.w, -1, 1) & 0x03) << 30) + | (((uint32_t)tangent_int.z & 0x3FF) << 20) + | (((uint32_t)tangent_int.y & 0x3FF) << 10) + | ((uint32_t)tangent_int.x & 0x3FF); + + data += mesh->size_vertex; + } + + if (!do_ura) + break; + } + else + for (int32_t i = 2; i; i--, sgn = -1.0f) { + for (int32_t j = num_idx; j; j--, idxtbl++) { + CLOTH_VERTEX* vtx = &vtxarg[*idxtbl]; + + *(vec3*)data = vtx->pos; + + vec3i16 normal_int; + vec3_to_vec3i16(vtx->normal * 511.0f, normal_int); + *(uint32_t*)(data + 0x0C) = (((uint32_t)0 & 0x03) << 30) + | (((uint32_t)normal_int.z & 0x3FF) << 20) + | (((uint32_t)normal_int.y & 0x3FF) << 10) + | ((uint32_t)normal_int.x & 0x3FF); + + data += mesh->size_vertex; + } + + if (!do_ura) + break; + } + break; } - if (stiffness) { - mat4 v131 = v130; - vec3 v111; - mat4_get_translation(&v131, &v111); - - RobOsageNode* v55_begin = nodes.data() + 1; - RobOsageNode* v55_end = nodes.data() + nodes.size(); - for (RobOsageNode* v55 = v55_begin; v55 != v55_end; v55++) { - vec3 v128; - mat4_transform_point(&v131, &v55->rel_pos, &v128); - - const vec3 delta_pos = v55->delta_pos + v55->vel; - vec3 v126 = v55->pos + delta_pos; - segment_limit_distance(v126, v111, v55->length * parent_scale.x); - - vec3 v117 = (v128 - v126) * skin_param_ptr->stiffness; - const float_t weight = v55->data_ptr->skp_osg_node.weight; - v117 *= 1.0f / (weight - (weight - 1.0f) * v55->data_ptr->skp_osg_node.inertial_cancel); - v55->vel += v117; - - v126 = v55->pos + delta_pos + v117; - - vec3 direction; - mat4_inverse_transform_point(&v131, &v126, &direction); - - rotate_matrix_to_direction(v131, direction, 0, 0, yz_order); - - mat4_mul_translate(&v131, vec3::distance(v111, v126), 0.0f, 0.0f, &v131); - - v111 = v126; - } - } - - RobOsageNode* v82_begin = nodes.data() + 1; - RobOsageNode* v82_end = nodes.data() + nodes.size(); - for (RobOsageNode* v82 = v82_begin; v82 != v82_end; v82++) { - v82->fixed_pos = v82->pos; - v82->delta_pos += v82->vel; - v82->pos += v82->delta_pos; - } - - if (nodes.size() > 1) { - RobOsageNode* v90_begin = nodes.data() + nodes.size() - 2; - RobOsageNode* v90_end = nodes.data(); - for (RobOsageNode* v90 = v90_begin; v90 != v90_end; v90--) - segment_limit_distance(v90[0].pos, v90[1].pos, v90->child_length * parent_scale.x); - } - - if (ring_coli) { - RobOsageNode* node = &nodes.data()[0]; - const float_t floor_height = ring.get_floor_height( - node->pos, node->data_ptr->skp_osg_node.coli_r); - - RobOsageNode* v98_begin = nodes.data() + 1; - RobOsageNode* v98_end = nodes.data() + nodes.size(); - for (RobOsageNode* v98 = v98_begin; v98 != v98_end; v98++) { - v98->CheckNodeDistance(step, parent_scale.x); - v98->CheckFloorCollision(floor_height); - } - } - - if (has_children_node) { - RobOsageNode* v99_begin = nodes.data() + 1; - RobOsageNode* v99_end = nodes.data() + nodes.size(); - for (RobOsageNode* v99 = v99_begin; v99 != v99_end; v99++) { - vec3 direction; - mat4_inverse_transform_point(&v130, &v99->pos, &direction); - - bool rot_clamped = rotate_matrix_to_direction(v130, direction, - &v99->data_ptr->skp_osg_node.hinge, - &v99->reset_data.rotation, yz_order); - *v99->bone_node_ptr->ex_data_mat = v130; - - v99->TranslateMat(v130, rot_clamped, parent_scale.x); - } - - if (nodes.size() && end_node.bone_node_mat) { - mat4 mat = *nodes.back().bone_node_ptr->ex_data_mat; - mat4_mul_translate_x(&mat, end_node.length * parent_scale.x, &mat); - *end_node.bone_node_ptr->ex_data_mat = mat; - } - } - apply_physics = false; + buffer.UnmapMemory(gl_state); } diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index a1a7cce1..ceac3865 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -2481,7 +2481,7 @@ const uint32_t* get_opd_motion_set_ids() { return opd_motion_set_ids; } -const float_t get_osage_gravity_const() { +const float_t get_gravity() { return 0.00299444468691945f; } @@ -2755,32 +2755,25 @@ void rob_free() { } } -static void rob_chara_item_equip_object_ctrl_init_iterate( - rob_chara_item_equip_object* itm_eq_obj, int32_t iterations) { - if (!itm_eq_obj->node_blocks.size()) - return; - - for (ExNodeBlock*& i : itm_eq_obj->node_blocks) - i->CtrlInitBegin(); - - for (; iterations; iterations--) { - if (itm_eq_obj->osage_depends_on_others && itm_eq_obj->node_blocks.size()) - for (int32_t i = 0; i < 6; i++) - for (ExNodeBlock*& j : itm_eq_obj->node_blocks) - j->CtrlStep(i, true); - - for (ExNodeBlock*& i : itm_eq_obj->node_blocks) - i->CtrlInitMain(); - } +static void rob_chara_item_equip_object_ctrl_step(rob_chara_item_equip_object* itm_eq_obj, bool disable_ex_force) { + for (int32_t i = 0; i < 6; i++) + for (ExNodeBlock*& j : itm_eq_obj->ex_node_block) + j->CtrlStep(i, disable_ex_force); } static void rob_chara_item_equip_object_load_opd_data(rob_chara_item_equip_object* itm_eq_obj) { - if (!itm_eq_obj->osage_blocks.size() && !itm_eq_obj->cloth_blocks.size()) + if (!itm_eq_obj->osage_blk.size() && !itm_eq_obj->cloth.size()) return; - rob_chara_item_equip* rob_itm_equip = itm_eq_obj->item_equip; +#if OPD_PLAY_GEN + rob_chara_item_equip* rob_disp = (rob_chara_item_equip*)itm_eq_obj->rob_disp; size_t index = 0; - for (opd_blend_data& i : rob_itm_equip->opd_blend_data) { + for (opd_blend_data& i : rob_disp->opd_blend_data) { +#else + const rob_chara_item_equip* rob_disp = itm_eq_obj->rob_disp; + size_t index = 0; + for (const opd_blend_data& i : rob_disp->opd_blend_data) { +#endif const float_t* opd_data = 0; uint32_t opd_count = 0; osage_play_data_manager_get_opd_file_data(itm_eq_obj->obj_info, i.motion_id, opd_data, opd_count); @@ -2794,52 +2787,45 @@ static void rob_chara_item_equip_object_load_opd_data(rob_chara_item_equip_objec i.no_loop = no_loop; #endif - for (ExOsageBlock*& j : itm_eq_obj->osage_blocks) + for (ExOsageBlock*& j : itm_eq_obj->osage_blk) opd_data = j->LoadOpdData(index, opd_data, opd_count); - for (ExClothBlock*& j : itm_eq_obj->cloth_blocks) + for (ExClothBlock*& j : itm_eq_obj->cloth) opd_data = j->LoadOpdData(index, opd_data, opd_count); index++; } } -static void rob_chara_item_equip_ctrl_iterate_nodes(rob_chara_item_equip* rob_itm_equip, uint8_t iterations = 0) { - for (int32_t i = ITEM_BODY; i < ITEM_MAX; i++) - rob_chara_item_equip_object_ctrl_init_iterate(&rob_itm_equip->item_equip_object[i], iterations); -} - static void rob_chara_item_equip_object_ctrl(rob_chara_item_equip_object* itm_eq_obj) { if (rob_chara_item_equip_object_disable_node_blocks) return; - if (itm_eq_obj->init_iterations > 0) { - rob_chara_item_equip_object_ctrl_init_iterate(itm_eq_obj, itm_eq_obj->init_iterations); - itm_eq_obj->init_iterations = 0; + if (itm_eq_obj->init_cnt > 0) { + itm_eq_obj->pos_reset(itm_eq_obj->init_cnt); + itm_eq_obj->init_cnt = 0; } - if (!itm_eq_obj->node_blocks.size()) // Added + if (!itm_eq_obj->ex_node_block.size()) // Added return; - for (ExNodeBlock*& i : itm_eq_obj->node_blocks) + for (ExNodeBlock*& i : itm_eq_obj->ex_node_block) i->CtrlBegin(); if (itm_eq_obj->use_opd) { itm_eq_obj->use_opd = false; rob_chara_item_equip_object_load_opd_data(itm_eq_obj); - for (ExNodeBlock*& i : itm_eq_obj->node_blocks) + for (ExNodeBlock*& i : itm_eq_obj->ex_node_block) i->CtrlOsagePlayData(); } else { - if (itm_eq_obj->osage_depends_on_others && itm_eq_obj->node_blocks.size()) - for (int32_t i = 0; i < 6; i++) - for (ExNodeBlock*& j : itm_eq_obj->node_blocks) - j->CtrlStep(i, false); + if (itm_eq_obj->osage_depends_on_others) + rob_chara_item_equip_object_ctrl_step(itm_eq_obj, false); - for (ExNodeBlock*& i : itm_eq_obj->node_blocks) - i->CtrlMain(); + for (ExNodeBlock*& i : itm_eq_obj->ex_node_block) + i->ctrl(); } - for (ExNodeBlock*& i : itm_eq_obj->node_blocks) + for (ExNodeBlock*& i : itm_eq_obj->ex_node_block) i->CtrlEnd(); } @@ -2867,42 +2853,42 @@ static void rob_chara_data_adjust_ctrl(rob_chara* rob_chr, break; } - adjust->curr_external_force = (adjust->external_force_cycle + cycle_val) - * (adjust->external_force * adjust->external_force_cycle_strength) + adjust->external_force; + adjust->curr_ex_force = (adjust->ex_force_cycle + cycle_val) + * (adjust->ex_force * adjust->ex_force_cycle_strength) + adjust->ex_force; switch (adjust->type) { case 1: { mat4 mat = mat4_identity; mat4_mul_rotate_y(&mat, (float_t)((double_t)rob_chr->data.miku_rot.rot_y_int16 * M_PI * (1.0 / 32768.0)), &mat); - mat4_transform_vector(&mat, &adjust->curr_external_force, &adjust->curr_external_force); + mat4_transform_vector(&mat, &adjust->curr_ex_force, &adjust->curr_ex_force); } case 2: { - mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_KL_MUNE_B_WJ)->ex_data_mat; + mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_KL_MUNE_B_WJ)->no_scale_mat; if (mat) - mat4_transform_vector(mat, &adjust->curr_external_force, &adjust->curr_external_force); + mat4_transform_vector(mat, &adjust->curr_ex_force, &adjust->curr_ex_force); } break; case 3: { - mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_KL_KUBI)->ex_data_mat; + mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_KL_KUBI)->no_scale_mat; if (mat) - mat4_transform_vector(mat, &adjust->curr_external_force, &adjust->curr_external_force); + mat4_transform_vector(mat, &adjust->curr_ex_force, &adjust->curr_ex_force); } break; case 4: { - mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_FACE_ROOT)->ex_data_mat; + mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_FACE_ROOT)->no_scale_mat; if (mat) - mat4_transform_vector(mat, &adjust->curr_external_force, &adjust->curr_external_force); + mat4_transform_vector(mat, &adjust->curr_ex_force, &adjust->curr_ex_force); } break; case 5: { - mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_KL_KOSI_ETC_WJ)->ex_data_mat; + mat4* mat = rob_chara_bone_data_get_node(rob_chr->bone_data, MOT_BONE_KL_KOSI_ETC_WJ)->no_scale_mat; if (mat) { - adjust->curr_external_force.z = -adjust->curr_external_force.z; - mat4_transform_vector(mat, &adjust->curr_external_force, &adjust->curr_external_force); + adjust->curr_ex_force.z = -adjust->curr_ex_force.z; + mat4_transform_vector(mat, &adjust->curr_ex_force, &adjust->curr_ex_force); } } break; } if (adjust->ignore_gravity) - adjust->curr_external_force.y = get_osage_gravity_const() + adjust->curr_external_force.y; + adjust->curr_ex_force.y = get_gravity() + adjust->curr_ex_force.y; adjust->curr_force = adjust->force; adjust->curr_strength = adjust->strength; @@ -2912,8 +2898,8 @@ static void rob_chara_data_adjust_ctrl(rob_chara* rob_chr, && fabsf(adjust->transition_duration - adjust->transition_frame) > 0.000001f) { transition_frame_step = true; float_t blend = (adjust->transition_frame + 1.0f) / (adjust->transition_duration + 1.0f); - adjust->curr_external_force = vec3::lerp(adjust_prev->curr_external_force, - adjust->curr_external_force, blend); + adjust->curr_ex_force = vec3::lerp(adjust_prev->curr_ex_force, + adjust->curr_ex_force, blend); adjust->curr_force = lerp_def(adjust_prev->curr_force, adjust->curr_force, blend); } @@ -2928,20 +2914,18 @@ static void rob_chara_data_adjust_ctrl(rob_chara* rob_chr, adjust->transition_frame += rob_chr->data.motion.step_data.frame; } -static void rob_chara_item_equip_object_set_parts_external_force( +static void rob_chara_item_equip_object_set_parts_ex_force( rob_chara_item_equip_object* itm_eq_obj, const rob_osage_parts_bit& parts_bits, - const vec3* external_force, const float_t& force, const float_t& strength) { - for (ExOsageBlock*& i : itm_eq_obj->osage_blocks) { - RobOsage* rob_osg = &i->rob; - if (rob_osg->CheckPartsBits(parts_bits)) { - rob_osg->SetNodesExternalForce(external_force, strength); - rob_osg->SetNodesForce(force); + const vec3* ex_force, const float_t& force, const float_t& gain) { + for (ExOsageBlock*& i : itm_eq_obj->osage_blk) + if (i->osage_work.CheckPartsBits(parts_bits)) { + i->osage_work.SetNodesExternalForce(ex_force, gain); + i->osage_work.SetNodesForce(force); } - } } -static void rob_chara_item_equip_set_parts_external_force(rob_chara_item_equip* rob_itm_eq, - const rob_osage_parts& parts, const vec3* external_force, const float_t& force, const float_t& strength) { +static void rob_chara_item_equip_set_parts_ex_force(rob_chara_item_equip* rob_itm_eq, + const rob_osage_parts& parts, const vec3* ex_force, const float_t& force, const float_t& strength) { item_id id = (item_id)(parts == ROB_OSAGE_PARTS_MUFFLER ? ITEM_OUTER : ITEM_KAMI); if (!osage_setting_data_obj_has_key(rob_itm_eq->item_equip_object[id].obj_info)) return; @@ -2978,27 +2962,23 @@ static void rob_chara_item_equip_set_parts_external_force(rob_chara_item_equip* if (!rob_itm_eq->parts_white_one_l && parts == ROB_OSAGE_PARTS_LONG_C) enum_or(parts_bits, ROB_OSAGE_PARTS_WHITE_ONE_L_BIT); - rob_chara_item_equip_object_set_parts_external_force( - &rob_itm_eq->item_equip_object[id], parts_bits, external_force, force, strength); + rob_chara_item_equip_object_set_parts_ex_force( + &rob_itm_eq->item_equip_object[id], parts_bits, ex_force, force, strength); } -static void rob_chara_item_equip_object_set_external_force( - rob_chara_item_equip_object* itm_eq_obj, const vec3* external_force) { - for (ExOsageBlock*& i : itm_eq_obj->osage_blocks) { - i->rob.set_external_force = true; - i->rob.external_force = *external_force; - } +static void rob_chara_item_equip_object_set_ex_force( + rob_chara_item_equip_object* itm_eq_obj, const vec3& f) { + for (ExOsageBlock*& i : itm_eq_obj->osage_blk) + i->set_ex_force(f); - for (ExClothBlock*& i : itm_eq_obj->cloth_blocks) { - i->rob.set_external_force = true; - i->rob.external_force = *external_force; - } + for (ExClothBlock*& i : itm_eq_obj->cloth) + i->set_ex_force(f); } -static void rob_chara_item_equip_set_external_force( - rob_chara_item_equip* rob_itm_eq, const vec3* external_force) { +static void rob_chara_item_equip_set_ex_force( + rob_chara_item_equip* rob_itm_eq, const vec3& f) { for (int32_t i = rob_itm_eq->first_item_equip_object; i < rob_itm_eq->max_item_equip_object; i++) - rob_chara_item_equip_object_set_external_force(&rob_itm_eq->item_equip_object[i], external_force); + rob_chara_item_equip_object_set_ex_force(&rob_itm_eq->item_equip_object[i], f); } void rob_chara::adjust_ctrl() { @@ -3009,15 +2989,15 @@ void rob_chara::adjust_ctrl() { if (parts_adjust->enable) { rob_chara_data_adjust_ctrl(this, parts_adjust, &data.motion.parts_adjust_prev[i]); rob_osage_parts parts = (rob_osage_parts)i; - rob_chara_item_equip_set_parts_external_force(rob_itm_equip, parts, - &parts_adjust->curr_external_force, parts_adjust->curr_force, parts_adjust->curr_strength); + rob_chara_item_equip_set_parts_ex_force(rob_itm_equip, parts, + &parts_adjust->curr_ex_force, parts_adjust->curr_force, parts_adjust->curr_strength); } } rob_chara_data_adjust* adjust_global = &data.motion.adjust_global; if (adjust_global->enable) { rob_chara_data_adjust_ctrl(this, adjust_global, &data.motion.adjust_global_prev); - rob_chara_item_equip_set_external_force(rob_itm_equip, &adjust_global->curr_external_force); + rob_chara_item_equip_set_ex_force(rob_itm_equip, adjust_global->curr_ex_force); } rob_itm_equip->parts_short = false; @@ -3588,7 +3568,7 @@ static void rob_chara_bone_data_set_left_hand_scale(rob_chara_bone_data* rob_bon for (int32_t i = MOT_BONE_KL_TE_L_WJ; i <= MOT_BONE_NL_OYA_C_L_WJ; i++) { bone_node* node = rob_chara_bone_data_get_node(rob_bone_data, i); if (node) - node->exp_data.scale = { scale, scale, scale }; + node->transform.scale = scale; } } @@ -3614,10 +3594,15 @@ static void rob_chara_bone_data_set_right_hand_scale(rob_chara_bone_data* rob_bo for (int32_t i = MOT_BONE_KL_TE_R_WJ; i <= MOT_BONE_NL_OYA_C_R_WJ; i++) { bone_node* node = rob_chara_bone_data_get_node(rob_bone_data, i); if (node) - node->exp_data.scale = { scale, scale, scale }; + node->transform.scale = scale; } } +// 0x140550400 +void rob_chara::pos_reset() { + item_equip->pos_reset(0); +} + void rob_chara::rob_info_ctrl() { data.field_3DA0 = data.field_3D9C; if (data.field_1E68.field_64 > 0.01f) @@ -3854,12 +3839,12 @@ void rob_chara::reset_osage() { i.reset(); for (int32_t i = 0; i < ROB_OSAGE_PARTS_MAX; i++) - item_equip->reset_nodes_external_force((rob_osage_parts)i); + item_equip->reset_nodes_ex_force((rob_osage_parts)i); data.motion.adjust_global.reset(); data.motion.adjust_global_prev.reset(); - item_equip->reset_external_force(); + item_equip->reset_ex_force(); item_equip->parts_short = false; item_equip->parts_append = false; item_equip->parts_white_one_l = false; @@ -4659,8 +4644,8 @@ bool rob_chara::set_motion_id(uint32_t motion_id, if (set_motion_reset_data) rob_chara::set_motion_reset_data(motion_id, frame); - item_equip->item_equip_object[ITEM_TE_L].init_iterations = 60; - item_equip->item_equip_object[ITEM_TE_R].init_iterations = 60; + item_equip->item_equip_object[ITEM_TE_L].init_cnt = 60; + item_equip->item_equip_object[ITEM_TE_R].init_cnt = 60; if (check_for_ageageagain_module()) { rob_chara_age_age_array_set_skip(chara_id, 1); @@ -4715,11 +4700,11 @@ void rob_chara::set_mouth_mottbl_motion(int32_t type, rob_chara_set_mouth_motion(this, &motion, type, mot_db); } -void rob_chara::set_osage_move_cancel(uint8_t id, float_t value) { - item_equip->set_osage_move_cancel(id, value); +void rob_chara::set_osage_move_cancel(uint8_t id, float_t mv_ccl) { + item_equip->set_osage_move_cancel(id, mv_ccl); if (id < 2) { - rob_chara_age_age_array_set_move_cancel(chara_id, 1, value); - rob_chara_age_age_array_set_move_cancel(chara_id, 2, value); + rob_chara_age_age_array_set_move_cancel(chara_id, 1, mv_ccl); + rob_chara_age_age_array_set_move_cancel(chara_id, 2, mv_ccl); } } @@ -4764,10 +4749,10 @@ void rob_chara::set_shadow_cast(bool value) { static void rob_chara_item_equip_object_set_ring( rob_chara_item_equip_object* itm_eq_obj, const osage_ring_data& ring) { - for (ExOsageBlock*& i : itm_eq_obj->osage_blocks) + for (ExOsageBlock*& i : itm_eq_obj->osage_blk) i->SetRing(ring); - for (ExClothBlock*& i : itm_eq_obj->cloth_blocks) + for (ExClothBlock*& i : itm_eq_obj->cloth) i->SetRing(ring); } @@ -5865,7 +5850,7 @@ static void mothead_func_7(mothead_func_data* func_data, float_t v8 = (float_t)((double_t)(int16_t)(v4 + rob_chr_data->field_1588.field_0.field_2B8 + rob_chr_data->miku_rot.rot_y_int16) * M_PI * (1.0 / 32768.0)); float_t v9 = sinf(v8) * ((float_t*)data)[1]; - float_t v10 = get_osage_gravity_const() * ((float_t*)data)[2]; + float_t v10 = get_gravity() * ((float_t*)data)[2]; float_t v11 = cosf(v8) * ((float_t*)data)[1]; rob_chr_data->miku_rot.field_30.x = v9; rob_chr_data->miku_rot.field_30.y = v10; @@ -6104,7 +6089,7 @@ LABEL_27: v36->miku_rot.field_30.x = (float_t)(*v11 - v36->miku_rot.n_hara_pos.x) * (float_t)(1.0 / v37); v36->miku_rot.field_30.z = (float_t)(v5->field_1588.field_330.field_20.z - v36->miku_rot.n_hara_pos.z) * (float_t)(1.0 / v37); - v36->miku_rot.field_30.y = get_osage_gravity_const() * ((float_t*)data)[6]; + v36->miku_rot.field_30.y = get_gravity() * ((float_t*)data)[6]; func_data->rob_chr_data->field_8.field_B8.field_10.y = 0.0f; sub_140551AF0(func_data->rob_chr); }*/ @@ -6555,15 +6540,15 @@ static void mothead_func_62_rob_parts_adjust(mothead_func_data* func_data, v16.type = type; v16.cycle_type = ((int8_t*)data)[7]; v16.ignore_gravity = !!((uint8_t*)data)[6]; - v16.external_force.x = ((float_t*)data)[2]; - v16.external_force.y = ((float_t*)data)[3]; - v16.external_force.z = ((float_t*)data)[4]; - v16.external_force_cycle_strength.x = ((float_t*)data)[5]; - v16.external_force_cycle_strength.y = ((float_t*)data)[6]; - v16.external_force_cycle_strength.z = ((float_t*)data)[7]; - v16.external_force_cycle.x = ((float_t*)data)[8]; - v16.external_force_cycle.y = ((float_t*)data)[9]; - v16.external_force_cycle.z = ((float_t*)data)[10]; + v16.ex_force.x = ((float_t*)data)[2]; + v16.ex_force.y = ((float_t*)data)[3]; + v16.ex_force.z = ((float_t*)data)[4]; + v16.ex_force_cycle_strength.x = ((float_t*)data)[5]; + v16.ex_force_cycle_strength.y = ((float_t*)data)[6]; + v16.ex_force_cycle_strength.z = ((float_t*)data)[7]; + v16.ex_force_cycle.x = ((float_t*)data)[8]; + v16.ex_force_cycle.y = ((float_t*)data)[9]; + v16.ex_force_cycle.z = ((float_t*)data)[10]; v16.cycle = ((float_t*)data)[11]; v16.force = ((float_t*)data)[13]; v16.phase = ((float_t*)data)[12]; @@ -6743,15 +6728,15 @@ static void mothead_func_75_rob_adjust_global(mothead_func_data* func_data, v14.transition_duration = (float_t)((int32_t*)data)[0]; v14.type = type; v14.cycle_type = ((int8_t*)data)[5]; - v14.external_force.x = ((float_t*)data)[2]; - v14.external_force.y = ((float_t*)data)[3]; - v14.external_force.z = ((float_t*)data)[4]; - v14.external_force_cycle_strength.x = ((float_t*)data)[5]; - v14.external_force_cycle_strength.y = ((float_t*)data)[6]; - v14.external_force_cycle_strength.z = ((float_t*)data)[7]; - v14.external_force_cycle.x = ((float_t*)data)[8]; - v14.external_force_cycle.y = ((float_t*)data)[9]; - v14.external_force_cycle.z = ((float_t*)data)[10]; + v14.ex_force.x = ((float_t*)data)[2]; + v14.ex_force.y = ((float_t*)data)[3]; + v14.ex_force.z = ((float_t*)data)[4]; + v14.ex_force_cycle_strength.x = ((float_t*)data)[5]; + v14.ex_force_cycle_strength.y = ((float_t*)data)[6]; + v14.ex_force_cycle_strength.z = ((float_t*)data)[7]; + v14.ex_force_cycle.x = ((float_t*)data)[8]; + v14.ex_force_cycle.y = ((float_t*)data)[9]; + v14.ex_force_cycle.z = ((float_t*)data)[10]; v14.cycle = ((float_t*)data)[11]; v14.phase = ((float_t*)data)[12]; } @@ -6945,7 +6930,7 @@ static void mothead_mot_func_2(mothead_mot_func_data* func_data, func_data->field_10->field_0.field_1F8 = (float_t)((int16_t*)data)[5]; func_data->field_10->field_0.field_1FC = ((float_t*)data)[3]; func_data->field_10->field_0.field_200 += ((float_t*)data)[4]; - func_data->rob_chara_data->field_8.field_B8.field_10.y = -(get_osage_gravity_const() * ((float_t*)data)[4]); + func_data->rob_chara_data->field_8.field_B8.field_10.y = -(get_gravity() * ((float_t*)data)[4]); if (func_data->field_10->field_0.field_1F4 < func_data->field_10->field_0.field_1F0) func_data->field_10->field_0.field_1F4 = func_data->field_10->field_0.field_1F0; @@ -7144,7 +7129,7 @@ static void mothead_mot_func_40(mothead_mot_func_data* func_data, else func_data->field_10->field_0.field_23C = ((float_t*)data)[1]; func_data->field_10->field_0.field_240 = ((int32_t*)data)[2]; - func_data->rob_chara_data->field_8.field_B8.field_10.y = -(get_osage_gravity_const() * ((float_t*)data)[3]); + func_data->rob_chara_data->field_8.field_B8.field_10.y = -(get_gravity() * ((float_t*)data)[3]); } static void mothead_mot_func_41(mothead_mot_func_data* func_data, @@ -7620,7 +7605,7 @@ static void sub_140414900(struc_308* a1, const mat4* mat) { static void sub_14041DA50(rob_chara_bone_data* rob_bone_data, mat4* mat) { for (bone_node& i : rob_bone_data->nodes) - mat4_mul(i.mat, mat, i.mat); + mat4_mul(i.mat_ptr, mat, i.mat_ptr); sub_140414900(&rob_bone_data->motion_loaded.front()->field_4F8, mat); } @@ -8255,7 +8240,7 @@ static void sub_140504AC0(rob_chara* rob_chr) { if (rob_chr->data.field_0 & 0x02) { v20 = v4 + rob_chr->data.miku_rot.field_3C + rob_chr->data.field_8.field_B8.field_10; v4.y = rob_chr->data.field_8.field_B8.field_10.y - - get_osage_gravity_const() * rob_chr->data.field_1588.field_0.field_200; + - get_gravity() * rob_chr->data.field_1588.field_0.field_200; } else if (!(rob_chr->data.field_1 & 0x80)) { v20 = rob_chr->data.miku_rot.field_3C; @@ -8381,7 +8366,7 @@ static void rob_disp_rob_chara_ctrl(rob_chara* rob_chr) { return; } - rob_chara_item_equip_ctrl_iterate_nodes(rob_chr->item_equip); + rob_chr->pos_reset(); effect_fog_ring_data_reset(); effect_splash_data_reset(); @@ -8513,16 +8498,16 @@ static float_t sub_14040ADE0(float_t a1, float_t a2) { static void sub_140407280(rob_chara_look_anim* look_anim, prj::sys_vector& bones, const mat4& parent_mat, float_t step) { vec3 v69; - mat4_get_translation(bones[MOTION_BONE_CL_KAO].node[2].mat, &v69); + mat4_get_translation(bones[MOTION_BONE_CL_KAO].node[2].mat_ptr, &v69); if (!look_anim->field_190 && !look_anim->field_191) return; float_t v14 = step * 0.25f; float_t v15 = look_anim->field_15C.field_8; float_t v16 = look_anim->field_15C.field_C; - mat4* c_kata_r_mat = bones[MOTION_BONE_C_KATA_R].node->mat; - mat4* c_kata_l_mat = bones[MOTION_BONE_C_KATA_L].node->mat; - mat4* n_kao_mat = bones[MOTION_BONE_N_KAO].node->mat; + mat4* c_kata_r_mat = bones[MOTION_BONE_C_KATA_R].node[0].mat_ptr; + mat4* c_kata_l_mat = bones[MOTION_BONE_C_KATA_L].node[0].mat_ptr; + mat4* n_kao_mat = bones[MOTION_BONE_N_KAO].node[0].mat_ptr; float_t v23 = atan2f(n_kao_mat->row0.x, n_kao_mat->row2.x); float_t v24 = atan2f(c_kata_r_mat->row3.x - c_kata_l_mat->row3.x, c_kata_r_mat->row3.z - c_kata_l_mat->row3.z); @@ -8672,7 +8657,7 @@ static void sub_140407280(rob_chara_look_anim* look_anim, v48 = look_anim->field_1AC.field_0; } - mat4 cl_kao_mat = *bones[MOTION_BONE_CL_KAO].node[1].mat; + mat4 cl_kao_mat = *bones[MOTION_BONE_CL_KAO].node[1].mat_ptr; float_t head_rot_angle = (v48 - atan2f(-v68.x, v68.y)) * look_anim->head_rot_blend; vec3 head_rot_axis; head_rot_axis.x = n_kao_mat->row2.x * 0.5f; @@ -8723,7 +8708,7 @@ static void sub_140407280(rob_chara_look_anim* look_anim, mat4 cl_kao_mat_backup = bones[MOTION_BONE_CL_KAO].rot_mat[1]; mat4 v74; - mat4_invert(bones[MOTION_BONE_CL_KAO].node->mat, &v74); + mat4_invert(bones[MOTION_BONE_CL_KAO].node[0].mat_ptr, &v74); mat4_clear_trans(&v74, &v74); mat4_clear_trans(&cl_kao_mat, &cl_kao_mat); mat4_mul(&cl_kao_mat, &v74, &bones[MOTION_BONE_CL_KAO].rot_mat[1]); @@ -9060,11 +9045,11 @@ static void sub_140406A70(struc_936* a1, prj::sys_vector& bones, cons vec3 v36; mat4_get_translation(v14->pole_target_mat, &v36); - mat4 v38 = *v14->node->mat; + mat4 v38 = *v14->node->mat_ptr; sub_14040AE10(&v38, v14->ik_target); mat4_inverse_transform_point(&v38, &v36, &v36); - v38 = *v14->node->mat; + v38 = *v14->node->mat_ptr; sub_14040AE10(&v38, target); vec3 v37; @@ -9085,7 +9070,7 @@ static void sub_140406A70(struc_936* a1, prj::sys_vector& bones, cons mat4 v38; mat4 v39; mat4_clear_trans(v25->parent_mat, &v38); - mat4_clear_trans(v25->node->mat, &v39); + mat4_clear_trans(v25->node->mat_ptr, &v39); mat4_transpose(&v38, &v38); mat4_mul(&v39, &v38, &v38); if (rotation_blend < 1.0f) @@ -9192,11 +9177,11 @@ static void sub_140412860(motion_blend_mot* mot, motion_bone_index index, mat4* switch (v4->type) { case BONE_DATABASE_BONE_HEAD_IK_ROTATION: - *mat = *v4->node[2].mat; + *mat = *v4->node[2].mat_ptr; break; case BONE_DATABASE_BONE_ARM_IK_ROTATION: case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - *mat = *v4->node[3].mat; + *mat = *v4->node[3].mat_ptr; break; } } @@ -9518,8 +9503,8 @@ LABEL_66: } static void sub_1403FA770(rob_chara_sleeve_adjust* a1) { - mat4* v4 = a1->bones->data()[MOTION_BONE_C_KATA_L].node[3].mat; - mat4* v5 = a1->bones->data()[MOTION_BONE_C_KATA_R].node[3].mat; + mat4* v4 = a1->bones->data()[MOTION_BONE_C_KATA_L].node[3].mat_ptr; + mat4* v5 = a1->bones->data()[MOTION_BONE_C_KATA_R].node[3].mat_ptr; vec3 v42; mat4_get_translation(v4, &v42); @@ -9581,15 +9566,15 @@ static void sub_1403FA770(rob_chara_sleeve_adjust* a1) { a1->sleeve_r.zmin, a1->sleeve_r.zmax, &a1->field_68, a1->step); if (v16 || v17) { - mat4 mat = *a1->bones->data()[MOTION_BONE_C_KATA_L].node[2].mat; + mat4 mat = *a1->bones->data()[MOTION_BONE_C_KATA_L].node[2].mat_ptr; sub_14040AE10(&mat, v42 + v45); - *a1->bones->data()[MOTION_BONE_C_KATA_L].node[2].mat = mat; + *a1->bones->data()[MOTION_BONE_C_KATA_L].node[2].mat_ptr = mat; } if (v19 || v18) { - mat4 mat = *a1->bones->data()[MOTION_BONE_C_KATA_R].node[2].mat; + mat4 mat = *a1->bones->data()[MOTION_BONE_C_KATA_R].node[2].mat_ptr; sub_14040AE10(&mat, v43 + v44); - *a1->bones->data()[MOTION_BONE_C_KATA_R].node[2].mat = mat; + *a1->bones->data()[MOTION_BONE_C_KATA_R].node[2].mat_ptr = mat; } } @@ -9637,7 +9622,7 @@ static void sub_1403F9B20(rob_chara_sleeve_adjust* a1, motion_bone_index motion_ bone_data* v15 = a1->bones->data(); bone_node* v18 = v15[motion_bone_index].node; - mat4* v19 = v18[MOTION_BONE_KL_HARA_ETC].mat; + mat4* v19 = v18[MOTION_BONE_KL_HARA_ETC].mat_ptr; vec3 v39; mat4_get_translation(v19, &v39); @@ -9646,7 +9631,7 @@ static void sub_1403F9B20(rob_chara_sleeve_adjust* a1, motion_bone_index motion_ sub_1403F9A40(&v37, &v39, v19, sleeve_cyofs, sleeve_czofs); vec3 v40; - mat4* v23 = v15[MOTION_BONE_KL_MUNE_B_WJ].node->mat; + mat4* v23 = v15[MOTION_BONE_KL_MUNE_B_WJ].node->mat_ptr; mat4_transform_point(v23, &sleeve_mune_ofs, &v40); vec3 v41 = v37 - v40; @@ -9665,7 +9650,7 @@ static void sub_1403F9B20(rob_chara_sleeve_adjust* a1, motion_bone_index motion_ mat4_transform_vector(v19, v6, &v41); } - mat4* v42 = v15[motion_bone_index].node[2].mat; + mat4* v42 = v15[motion_bone_index].node[2].mat_ptr; sub_14040AE10(v42, v39 + v41); } @@ -9699,14 +9684,14 @@ static bool rob_chara_hands_adjust(rob_chara* rob_chr) { static float_t sub_140406E90(bone_data* a1, bone_data* a2, float_t a3, vec3* a4) { vec3 v18 = 0.0f; - mat4_transform_point(a1->node[3].mat, &v18, &v18); + mat4_transform_point(a1->node[3].mat_ptr, &v18, &v18); *a4 = v18; vec3 v17; v17.x = 0.01f; v17.y = -0.05f; v17.z = 0.0f; - mat4_transform_point(a2->node[0].mat, &v18, &v17); + mat4_transform_point(a2->node[0].mat_ptr, &v18, &v17); if (v18.y - a3 <= v17.y) return v18.y - a3; @@ -9918,7 +9903,7 @@ static void rob_chara_bone_data_get_ik_scale( static mat4* rob_chara_bone_data_get_mat(rob_chara_bone_data* rob_bone_data, size_t index) { bone_node* node = rob_chara_bone_data_get_node(rob_bone_data, index); if (node) - return node->mat; + return node->mat_ptr; return 0; } @@ -10438,13 +10423,13 @@ static void rob_chara_bone_data_set_mats(rob_chara_bone_data* rob_bone_data, case BONE_DATABASE_BONE_ROTATION: case BONE_DATABASE_BONE_TYPE_1: case BONE_DATABASE_BONE_POSITION: - nodes->mat = &rob_bone_data->mats[matrix++]; + nodes->mat_ptr = &rob_bone_data->mats[matrix++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; break; case BONE_DATABASE_BONE_POSITION_ROTATION: - nodes->mat = &rob_bone_data->mats[matrix++]; + nodes->mat_ptr = &rob_bone_data->mats[matrix++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; @@ -10452,17 +10437,17 @@ static void rob_chara_bone_data_set_mats(rob_chara_bone_data* rob_bone_data, leaf_pos++; break; case BONE_DATABASE_BONE_HEAD_IK_ROTATION: - nodes->mat = &rob_bone_data->mats2[matrix2++]; + nodes->mat_ptr = &rob_bone_data->mats2[matrix2++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; - nodes->mat = &rob_bone_data->mats[matrix++]; + nodes->mat_ptr = &rob_bone_data->mats[matrix++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; - nodes->mat = &rob_bone_data->mats2[matrix2++]; + nodes->mat_ptr = &rob_bone_data->mats2[matrix2++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; @@ -10473,22 +10458,22 @@ static void rob_chara_bone_data_set_mats(rob_chara_bone_data* rob_bone_data, break; case BONE_DATABASE_BONE_ARM_IK_ROTATION: case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - nodes->mat = &rob_bone_data->mats[matrix++]; + nodes->mat_ptr = &rob_bone_data->mats[matrix++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; - nodes->mat = &rob_bone_data->mats[matrix++]; + nodes->mat_ptr = &rob_bone_data->mats[matrix++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; - nodes->mat = &rob_bone_data->mats[matrix++]; + nodes->mat_ptr = &rob_bone_data->mats[matrix++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; - nodes->mat = &rob_bone_data->mats2[matrix2++]; + nodes->mat_ptr = &rob_bone_data->mats2[matrix2++]; nodes->name = motion_bones->c_str(); nodes++; motion_bones++; @@ -10502,7 +10487,7 @@ static void rob_chara_bone_data_set_mats(rob_chara_bone_data* rob_bone_data, } for (bone_node& i : rob_bone_data->nodes) - i.ex_data_mat = i.mat; + i.no_scale_mat = i.mat_ptr; if (node != rob_bone_data->node_count) printf_debug_error("Node mismatch"); @@ -11033,15 +11018,15 @@ static bool rob_chara_data_adjust_compare(rob_chara_data_adjust* left, rob_chara && right->type == left->type && right->cycle_type == left->cycle_type && right->ignore_gravity == left->ignore_gravity - && left->external_force.x == right->external_force.x - && left->external_force.y == right->external_force.y - && left->external_force.z == right->external_force.z - && left->external_force_cycle_strength.x == right->external_force_cycle_strength.x - && left->external_force_cycle_strength.y == right->external_force_cycle_strength.y - && left->external_force_cycle_strength.z == right->external_force_cycle_strength.z - && left->external_force_cycle.x == right->external_force_cycle.x - && left->external_force_cycle.y == right->external_force_cycle.y - && left->external_force_cycle.z == right->external_force_cycle.z + && left->ex_force.x == right->ex_force.x + && left->ex_force.y == right->ex_force.y + && left->ex_force.z == right->ex_force.z + && left->ex_force_cycle_strength.x == right->ex_force_cycle_strength.x + && left->ex_force_cycle_strength.y == right->ex_force_cycle_strength.y + && left->ex_force_cycle_strength.z == right->ex_force_cycle_strength.z + && left->ex_force_cycle.x == right->ex_force_cycle.x + && left->ex_force_cycle.y == right->ex_force_cycle.y + && left->ex_force_cycle.z == right->ex_force_cycle.z && left->cycle == right->cycle && left->phase == right->phase; } @@ -11458,98 +11443,138 @@ bool task_rob_manager_del_task() { return false; } -bone_node_expression_data::bone_node_expression_data() { - position = 0.0f; - rotation = 0.0f; +RobTransform::RobTransform() { + pos = 0.0f; + rot = 0.0f; scale = 1.0f; - parent_scale = 1.0f; + hsc = 1.0f; } -void bone_node_expression_data::mat_set(const vec3& parent_scale, mat4& ex_data_mat, mat4& mat) { - vec3 position = this->position * parent_scale; - mat4_mul_translate(&ex_data_mat, &position, &ex_data_mat); - mat4_mul_rotate_zyx(&ex_data_mat, &rotation, &ex_data_mat); - this->parent_scale = scale * parent_scale; - mat = ex_data_mat; - mat4_scale_rot(&mat, &this->parent_scale, &mat); +void RobTransform::CalcMatrixHS(const vec3& hsc, mat4& mat, mat4& dsp_mat) { + vec3 pos = this->pos * hsc; + mat4_mul_translate(&mat, &pos, &mat); + mat4_mul_rotate_zyx(&mat, &rot, &mat); + this->hsc = scale * hsc; + dsp_mat = mat; + mat4_scale_rot(&dsp_mat, &this->hsc, &dsp_mat); } -void bone_node_expression_data::reset_scale() { +void RobTransform::init(float_t px, float_t py, float_t pz, + float_t rx, float_t ry, float_t rz) { + pos.x = px; + pos.y = py; + pos.z = pz; + rot.x = rx; + rot.z = ry; + rot.y = rz; scale = 1.0f; - parent_scale = 1.0f; + hsc = 1.0f; } -void bone_node_expression_data::set_position_rotation( - float_t position_x, float_t position_y, float_t position_z, - float_t rotation_x, float_t rotation_y, float_t rotation_z) { - position.x = position_x; - position.y = position_y; - position.z = position_z; - rotation.x = rotation_x; - rotation.z = rotation_z; - rotation.y = rotation_y; +void RobTransform::init(const vec3& p, const vec3& r) { + pos = p; + rot = r; scale = 1.0f; - parent_scale = 1.0f; + hsc = 1.0f; } -void bone_node_expression_data::set_position_rotation(const vec3& position, const vec3& rotation) { - this->position = position; - this->rotation = rotation; +void RobTransform::reset() { + pos = 0.0f; + rot = 0.0f; scale = 1.0f; - parent_scale = 1.0f; + hsc = 1.0f; } -bone_node::bone_node() : name(), mat(), parent(), ex_data_mat() { +void RobTransform::reset_scale() { + scale = 1.0f; + hsc = 1.0f; +} + +bone_node::bone_node() : name(), mat_ptr(), parent(), no_scale_mat() { } -float_t* bone_node::get_exp_data_component(size_t index, ex_expression_block_stack_type& type) { +float_t* bone_node::get_transform_component(size_t index, Expr_type& type) { switch (index) { case 0: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE; - return &exp_data.position.x; + type = Expr_variable; + return &transform.pos.x; case 1: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE; - return &exp_data.position.y; + type = Expr_variable; + return &transform.pos.y; case 2: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE; - return &exp_data.position.z; + type = Expr_variable; + return &transform.pos.z; case 3: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE_RADIAN; - return &exp_data.rotation.x; + type = Expr_variable_rad; + return &transform.rot.x; case 4: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE_RADIAN; - return &exp_data.rotation.y; + type = Expr_variable_rad; + return &transform.rot.y; case 5: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE_RADIAN; - return &exp_data.rotation.z; + type = Expr_variable_rad; + return &transform.rot.z; case 6: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE; - return &exp_data.scale.x; + type = Expr_variable; + return &transform.scale.x; case 7: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE; - return &exp_data.scale.y; + type = Expr_variable; + return &transform.scale.y; case 8: - type = EX_EXPRESSION_BLOCK_STACK_VARIABLE; - return &exp_data.scale.z; + type = Expr_variable; + return &transform.scale.z; default: return 0; } } -void bone_node::set_name_mat_ex_data_mat(const char* name, mat4* mat, mat4* ex_data_mat) { +const float_t* bone_node::get_transform_component(size_t index, Expr_type& type) const { + switch (index) { + case 0: + type = Expr_variable; + return &transform.pos.x; + case 1: + type = Expr_variable; + return &transform.pos.y; + case 2: + type = Expr_variable; + return &transform.pos.z; + case 3: + type = Expr_variable_rad; + return &transform.rot.x; + case 4: + type = Expr_variable_rad; + return &transform.rot.y; + case 5: + type = Expr_variable_rad; + return &transform.rot.z; + case 6: + type = Expr_variable; + return &transform.scale.x; + case 7: + type = Expr_variable; + return &transform.scale.y; + case 8: + type = Expr_variable; + return &transform.scale.z; + default: + return 0; + } +} + +void bone_node::set_name_mat_no_scale_mat(const char* name, mat4* mat, mat4* no_scale_mat) { this->name = name; - this->mat = mat; + this->mat_ptr = mat; if (mat) *mat = mat4_identity; parent = 0; - exp_data = {}; + transform.reset(); - this->ex_data_mat = ex_data_mat; - if (ex_data_mat) - *ex_data_mat = mat4_identity; + this->no_scale_mat = no_scale_mat; + if (no_scale_mat) + *no_scale_mat = mat4_identity; } mot_key_data::mot_key_data() : key_sets_ready(), key_set_count(), key_set(), @@ -11645,42 +11670,42 @@ bool bone_data::get_constraint_ik(const bone_data* bones) { switch (motion_bone_index) { case MOTION_BONE_N_SKATA_L_WJ_CD_EX: - mat4_get_translation(bones[MOTION_BONE_C_KATA_L].node[2].mat, &target); + mat4_get_translation(bones[MOTION_BONE_C_KATA_L].node[2].mat_ptr, &target); orient_x(target); break; case MOTION_BONE_N_SKATA_R_WJ_CD_EX: - mat4_get_translation(bones[MOTION_BONE_C_KATA_R].node[2].mat, &target); + mat4_get_translation(bones[MOTION_BONE_C_KATA_R].node[2].mat_ptr, &target); orient_x(target); break; case MOTION_BONE_N_SKATA_B_L_WJ_CD_CU_EX: - mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_L_EX].node[0].mat, &target); + mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_L_EX].node[0].mat_ptr, &target); orient_x_cns(target, 0.333f); break; case MOTION_BONE_N_SKATA_B_R_WJ_CD_CU_EX: - mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_R_EX].node[0].mat, &target); + mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_R_EX].node[0].mat_ptr, &target); orient_x_cns(target, 0.333f); break; case MOTION_BONE_N_SKATA_C_L_WJ_CD_CU_EX: - mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_L_EX].node[0].mat, &target); + mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_L_EX].node[0].mat_ptr, &target); orient_x_cns(target, 0.5f); break; case MOTION_BONE_N_SKATA_C_R_WJ_CD_CU_EX: - mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_R_EX].node[0].mat, &target); + mat4_get_translation(bones[MOTION_BONE_N_UP_KATA_R_EX].node[0].mat_ptr, &target); orient_x_cns(target, 0.5f); break; case MOTION_BONE_N_MOMO_A_L_WJ_CD_EX: - mat4_get_translation(bones[MOTION_BONE_CL_MOMO_L].node[2].mat, &target); - mat4_inverse_transform_point(node[0].mat, &target, &target); + mat4_get_translation(bones[MOTION_BONE_CL_MOMO_L].node[2].mat_ptr, &target); + mat4_inverse_transform_point(node[0].mat_ptr, &target, &target); orient_y(-target); break; case MOTION_BONE_N_MOMO_A_R_WJ_CD_EX: - mat4_get_translation(bones[MOTION_BONE_CL_MOMO_R].node[2].mat, &target); - mat4_inverse_transform_point(node[0].mat, &target, &target); + mat4_get_translation(bones[MOTION_BONE_CL_MOMO_R].node[2].mat_ptr, &target); + mat4_inverse_transform_point(node[0].mat_ptr, &target, &target); orient_y(-target); break; case MOTION_BONE_N_HARA_CD_EX: - mat4_get_translation(bones[MOTION_BONE_KL_MUNE_B_WJ].node[0].mat, &target); - mat4_inverse_transform_point(node[0].mat, &target, &target); + mat4_get_translation(bones[MOTION_BONE_KL_MUNE_B_WJ].node[0].mat_ptr, &target); + mat4_inverse_transform_point(node[0].mat_ptr, &target, &target); orient_y(target); break; default: @@ -11689,17 +11714,17 @@ bool bone_data::get_constraint_ik(const bone_data* bones) { return true; } -bool bone_data::get_ex_rotation(bone_node_expression_data& exp_data, const bone_data* bones) { +bool bone_data::get_ex_rotation(RobTransform& transform, const bone_data* bones) { bone_node* node; switch (motion_bone_index) { case MOTION_BONE_N_EYE_L_WJ_EX: - exp_data.rotation.x = -bones[MOTION_BONE_KL_EYE_L].node[0].exp_data.rotation.x; - exp_data.rotation.y = bones[MOTION_BONE_KL_EYE_L].node[0].exp_data.rotation.y * (float_t)(-1.0 / 2.0); + transform.rot.x = -bones[MOTION_BONE_KL_EYE_L].node[0].transform.rot.x; + transform.rot.y = bones[MOTION_BONE_KL_EYE_L].node[0].transform.rot.y * (float_t)(-1.0 / 2.0); break; case MOTION_BONE_N_EYE_R_WJ_EX: - exp_data.rotation.x = -bones[MOTION_BONE_KL_EYE_R].node[0].exp_data.rotation.x; - exp_data.rotation.y = bones[MOTION_BONE_KL_EYE_R].node[0].exp_data.rotation.y * (float_t)(-1.0 / 2.0); + transform.rot.x = -bones[MOTION_BONE_KL_EYE_R].node[0].transform.rot.x; + transform.rot.y = bones[MOTION_BONE_KL_EYE_R].node[0].transform.rot.y * (float_t)(-1.0 / 2.0); break; case MOTION_BONE_N_KUBI_WJ_EX: { mat4 mat = bones[MOTION_BONE_CL_KAO].rot_mat[0]; @@ -11711,88 +11736,88 @@ bool bone_data::get_ex_rotation(bone_node_expression_data& exp_data, const bone_ float_t rot = rotation.z; if (rot < (float_t)-M_PI_2) rot += (float_t)(M_PI * 2.0); - exp_data.rotation.y = (rot - (float_t)M_PI_2) * 0.2f; + transform.rot.y = (rot - (float_t)M_PI_2) * 0.2f; } break; case MOTION_BONE_N_HITO_L_EX: case MOTION_BONE_N_HITO_R_EX: - exp_data.rotation.z = (float_t)(-9.0 * DEG_TO_RAD); + transform.rot.z = (float_t)(-9.0 * DEG_TO_RAD); break; case MOTION_BONE_N_KO_L_EX: - exp_data.rotation.x = (float_t)(-8.0 * DEG_TO_RAD); - exp_data.rotation.z = (float_t)(16.0 * DEG_TO_RAD); + transform.rot.x = (float_t)(-8.0 * DEG_TO_RAD); + transform.rot.z = (float_t)(16.0 * DEG_TO_RAD); break; case MOTION_BONE_N_KUSU_L_EX: case MOTION_BONE_N_KUSU_R_EX: - exp_data.rotation.z = (float_t)(9.0 * DEG_TO_RAD); + transform.rot.z = (float_t)(9.0 * DEG_TO_RAD); break; case MOTION_BONE_N_NAKA_L_EX: case MOTION_BONE_N_NAKA_R_EX: - exp_data.rotation.z = (float_t)(-1.0 * DEG_TO_RAD); + transform.rot.z = (float_t)(-1.0 * DEG_TO_RAD); break; case MOTION_BONE_N_OYA_L_EX: - exp_data.rotation.x = (float_t)(75.0 * DEG_TO_RAD); - exp_data.rotation.y = (float_t)(12.0 * DEG_TO_RAD); - exp_data.rotation.z = (float_t)(-24.0 * DEG_TO_RAD); + transform.rot.x = (float_t)(75.0 * DEG_TO_RAD); + transform.rot.y = (float_t)(12.0 * DEG_TO_RAD); + transform.rot.z = (float_t)(-24.0 * DEG_TO_RAD); break; case MOTION_BONE_N_STE_L_WJ_EX: - exp_data.rotation.x = bones[MOTION_BONE_KL_TE_L_WJ].node[0].exp_data.rotation.x; + transform.rot.x = bones[MOTION_BONE_KL_TE_L_WJ].node[0].transform.rot.x; break; case MOTION_BONE_N_SUDE_L_WJ_EX: case MOTION_BONE_N_SUDE_B_L_WJ_EX: node = &bones[MOTION_BONE_KL_TE_L_WJ].node[0]; - exp_data.rotation.x = bone_data::limit_angle(node->exp_data.rotation.x) * (float_t)(1.0 / 3.0); + transform.rot.x = bone_data::limit_angle(node->transform.rot.x) * (float_t)(1.0 / 3.0); break; case MOTION_BONE_N_SUDE_R_WJ_EX: case MOTION_BONE_N_SUDE_B_R_WJ_EX: node = &bones[MOTION_BONE_KL_TE_R_WJ].node[0]; - exp_data.rotation.x = bone_data::limit_angle(node->exp_data.rotation.x) * (float_t)(1.0 / 3.0); + transform.rot.x = bone_data::limit_angle(node->transform.rot.x) * (float_t)(1.0 / 3.0); break; case MOTION_BONE_N_HIJI_L_WJ_EX: - exp_data.rotation.z = bones[MOTION_BONE_C_KATA_L].node[2].exp_data.rotation.z * (float_t)(1.0 / 2.0); + transform.rot.z = bones[MOTION_BONE_C_KATA_L].node[2].transform.rot.z * (float_t)(1.0 / 2.0); break; case MOTION_BONE_N_UP_KATA_L_EX: case MOTION_BONE_N_UP_KATA_R_EX: break; case MOTION_BONE_N_KO_R_EX: - exp_data.rotation.x = (float_t)(8.0 * DEG_TO_RAD); - exp_data.rotation.z = (float_t)(16.0 * DEG_TO_RAD); + transform.rot.x = (float_t)(8.0 * DEG_TO_RAD); + transform.rot.z = (float_t)(16.0 * DEG_TO_RAD); break; case MOTION_BONE_N_OYA_R_EX: - exp_data.rotation.x = (float_t)(-75.0 * DEG_TO_RAD); - exp_data.rotation.y = (float_t)(-12.0 * DEG_TO_RAD); - exp_data.rotation.z = (float_t)(-24.0 * DEG_TO_RAD); + transform.rot.x = (float_t)(-75.0 * DEG_TO_RAD); + transform.rot.y = (float_t)(-12.0 * DEG_TO_RAD); + transform.rot.z = (float_t)(-24.0 * DEG_TO_RAD); break; case MOTION_BONE_N_STE_R_WJ_EX: - exp_data.rotation.x = bones[MOTION_BONE_KL_TE_R_WJ].node[0].exp_data.rotation.x; + transform.rot.x = bones[MOTION_BONE_KL_TE_R_WJ].node[0].transform.rot.x; break; case MOTION_BONE_N_HIJI_R_WJ_EX: - exp_data.rotation.z = bones[MOTION_BONE_C_KATA_R].node[2].exp_data.rotation.z * (float_t)(1.0 / 2.0); + transform.rot.z = bones[MOTION_BONE_C_KATA_R].node[2].transform.rot.z * (float_t)(1.0 / 2.0); break; case MOTION_BONE_N_HIZA_L_WJ_EX: - exp_data.rotation.z = bones[MOTION_BONE_CL_MOMO_L].node[2].exp_data.rotation.z * (float_t)(1.0 / 2.0); + transform.rot.z = bones[MOTION_BONE_CL_MOMO_L].node[2].transform.rot.z * (float_t)(1.0 / 2.0); break; case MOTION_BONE_N_HIZA_R_WJ_EX: - exp_data.rotation.z = bones[MOTION_BONE_CL_MOMO_R].node[2].exp_data.rotation.z * (float_t)(1.0 / 2.0); + transform.rot.z = bones[MOTION_BONE_CL_MOMO_R].node[2].transform.rot.z * (float_t)(1.0 / 2.0); break; case MOTION_BONE_N_MOMO_B_L_WJ_EX: case MOTION_BONE_N_MOMO_C_L_WJ_EX: node = &bones[MOTION_BONE_CL_MOMO_L].node[0]; - exp_data.rotation.y = bone_data::limit_angle(node->exp_data.rotation.y - + node->exp_data.rotation.x) * (float_t)(1.0 / 3.0); + transform.rot.y = bone_data::limit_angle(node->transform.rot.y + + node->transform.rot.x) * (float_t)(1.0 / 3.0); break; case MOTION_BONE_N_MOMO_B_R_WJ_EX: case MOTION_BONE_N_MOMO_C_R_WJ_EX: node = &bones[MOTION_BONE_CL_MOMO_R].node[0]; - exp_data.rotation.y = bone_data::limit_angle(node->exp_data.rotation.y - + node->exp_data.rotation.x) * (float_t)(1.0 / 3.0); + transform.rot.y = bone_data::limit_angle(node->transform.rot.y + + node->transform.rot.x) * (float_t)(1.0 / 3.0); break; case MOTION_BONE_N_HARA_B_WJ_EX: - exp_data.rotation.y = bones[MOTION_BONE_CL_MUNE].node[0].exp_data.rotation.y * (float_t)(1.0 / 3.0) - + bones[MOTION_BONE_KL_KOSI_Y].node[0].exp_data.rotation.y * (float_t)(2.0 / 3.0); + transform.rot.y = bones[MOTION_BONE_CL_MUNE].node[0].transform.rot.y * (float_t)(1.0 / 3.0) + + bones[MOTION_BONE_KL_KOSI_Y].node[0].transform.rot.y * (float_t)(2.0 / 3.0); break; case MOTION_BONE_N_HARA_C_WJ_EX: - exp_data.rotation.y = bones[MOTION_BONE_CL_MUNE].node[0].exp_data.rotation.y * (float_t)(2.0 / 3.0) - + bones[MOTION_BONE_KL_KOSI_Y].node[0].exp_data.rotation.y * (float_t)(1.0 / 3.0); + transform.rot.y = bones[MOTION_BONE_CL_MUNE].node[0].transform.rot.y * (float_t)(2.0 / 3.0) + + bones[MOTION_BONE_KL_KOSI_Y].node[0].transform.rot.y * (float_t)(1.0 / 3.0); break; default: return false; @@ -11841,7 +11866,7 @@ void bone_data::get_mat(int32_t skeleton_select) { this->rot_mat[0] = rot_mat; } - *node[0].mat = mat; + *node[0].mat_ptr = mat; get_mat_ik(skeleton_select); } @@ -11850,7 +11875,7 @@ void bone_data::get_mat_ik(int32_t skeleton_select) { if (type < BONE_DATABASE_BONE_HEAD_IK_ROTATION) return; - mat4 mat = *node[0].mat; + mat4 mat = *node[0].mat_ptr; vec3 local_target; mat4_inverse_transform_point(&mat, &ik_target, &local_target); @@ -11886,10 +11911,10 @@ void bone_data::get_mat_ik(int32_t skeleton_select) { if (type == BONE_DATABASE_BONE_HEAD_IK_ROTATION) { this->rot_mat[1] = rot_mat; - *node[1].mat = mat; + *node[1].mat_ptr = mat; mat4_mul_translate(&mat, ik_segment_length[skeleton_select], 0.0f, 0.0f, &mat); - *node[2].mat = mat; + *node[2].mat_ptr = mat; return; } @@ -11930,18 +11955,18 @@ void bone_data::get_mat_ik(int32_t skeleton_select) { } mat4_mul_rotate_z(&mat, rot_sin, rot_cos, &mat); - *node[1].mat = mat; + *node[1].mat_ptr = mat; mat4_mul_rotate_z(&rot_mat, rot_sin, rot_cos, &rot_mat); this->rot_mat[1] = rot_mat; mat4_mul_translate(&mat, ik_segment_length, 0.0f, 0.0f, &mat); mat4_mul_rotate_z(&mat, rot_2nd_sin, rot_2nd_cos, &mat); - *node[2].mat = mat; + *node[2].mat_ptr = mat; mat4_rotate_z(rot_2nd_sin, rot_2nd_cos, &rot_mat); this->rot_mat[2] = rot_mat; mat4_mul_translate(&mat, ik_2nd_segment_length, 0.0f, 0.0f, &mat); - *node[3].mat = mat; + *node[3].mat_ptr = mat; } void bone_data::mult_mat(const mat4& parent_mat, const bone_data* bones, bool solve_ik) { @@ -11957,20 +11982,20 @@ void bone_data::mult_mat(const mat4& parent_mat, const bone_data* bones, bool so mat4_mul_translate(&mat, &position, &mat); if (solve_ik) { - node[0].exp_data.rotation = 0.0f; + node[0].transform.rot = 0.0f; if (!check_flags_not_null()) - mat4_get_rotation_zyx(&rot_mat[0], &node[0].exp_data.rotation); - else if (get_ex_rotation(node[0].exp_data, bones)) - mat4_rotate_zyx(&node[0].exp_data.rotation, &rot_mat[0]); + mat4_get_rotation_zyx(&rot_mat[0], &node[0].transform.rot); + else if (get_ex_rotation(node[0].transform, bones)) + mat4_rotate_zyx(&node[0].transform.rot, &rot_mat[0]); else { - *node[0].mat = mat; + *node[0].mat_ptr = mat; if (get_constraint_ik(bones)) { mat4 rot_mat; mat4_invert_rotation_fast(&mat, &rot_mat); - mat4_mul(node[0].mat, &rot_mat, &rot_mat); + mat4_mul(node[0].mat_ptr, &rot_mat, &rot_mat); mat4_clear_trans(&rot_mat, &rot_mat); - mat4_get_rotation_zyx(&rot_mat, &node[0].exp_data.rotation); + mat4_get_rotation_zyx(&rot_mat, &node[0].transform.rot); this->rot_mat[0] = rot_mat; } else @@ -11983,61 +12008,59 @@ void bone_data::mult_mat(const mat4& parent_mat, const bone_data* bones, bool so else { mat4_mul_translate(&mat, &position, &mat); if (solve_ik) - node[0].exp_data.rotation = 0.0f; + node[0].transform.rot = 0.0f; } - *node[0].mat = mat; + *node[0].mat_ptr = mat; if (solve_ik) { - node[0].exp_data.position = position; - node[0].exp_data.reset_scale(); + node[0].transform.pos = position; + node[0].transform.reset_scale(); } if (type < BONE_DATABASE_BONE_HEAD_IK_ROTATION) return; mat4_mul(&rot_mat[1], &mat, &mat); - *node[1].mat = mat; + *node[1].mat_ptr = mat; if (type == BONE_DATABASE_BONE_HEAD_IK_ROTATION) { mat4_mul_translate(&mat, ik_segment_length[1], 0.0f, 0.0f, &mat); - *node[2].mat = mat; + *node[2].mat_ptr = mat; if (solve_ik) { - node[1].exp_data.position = 0.0f; - mat4_get_rotation_zyx(&rot_mat[1], &node[1].exp_data.rotation); - node[1].exp_data.reset_scale(); + node[1].transform.pos = 0.0f; + mat4_get_rotation_zyx(&rot_mat[1], &node[1].transform.rot); + node[1].transform.reset_scale(); - node[2].exp_data.set_position_rotation( - ik_segment_length[1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + node[2].transform.init(ik_segment_length[1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); } } else { mat4_mul_translate(&mat, ik_segment_length[1], 0.0f, 0.0f, &mat); mat4_mul(&rot_mat[2], &mat, &mat); - *node[2].mat = mat; + *node[2].mat_ptr = mat; mat4_mul_translate(&mat, ik_2nd_segment_length[1], 0.0f, 0.0f, &mat); - *node[3].mat = mat; + *node[3].mat_ptr = mat; if (solve_ik) { - node[1].exp_data.position = 0.0f; - mat4_get_rotation_zyx(&rot_mat[1], &node[1].exp_data.rotation); - node[1].exp_data.reset_scale(); + node[1].transform.pos = 0.0f; + mat4_get_rotation_zyx(&rot_mat[1], &node[1].transform.rot); + node[1].transform.reset_scale(); - node[2].exp_data.position = { ik_segment_length[1], 0.0f, 0.0f }; - mat4_get_rotation_zyx(&rot_mat[2], &node[2].exp_data.rotation); - node[2].exp_data.reset_scale(); + node[2].transform.pos = { ik_segment_length[1], 0.0f, 0.0f }; + mat4_get_rotation_zyx(&rot_mat[2], &node[2].transform.rot); + node[2].transform.reset_scale(); - node[3].exp_data.set_position_rotation( - ik_2nd_segment_length[1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + node[3].transform.init(ik_2nd_segment_length[1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); } } } void bone_data::orient_x(const vec3& target) { vec3 x_axis; - mat4_inverse_transform_point(node[0].mat, &target, &x_axis); + mat4_inverse_transform_point(node[0].mat_ptr, &target, &x_axis); float_t len; len = vec3::length_squared(x_axis); @@ -12077,18 +12100,18 @@ void bone_data::orient_x(const vec3& target) { mat4_set_row(&rot_mat, 2, z_axis.x, z_axis.y, z_axis.z, 0.0f); mat4_set_row(&rot_mat, 3, 0.0f, 0.0f, 0.0f, 1.0f); - mat4_mul(&rot_mat, node[0].mat, node[0].mat); + mat4_mul(&rot_mat, node[0].mat_ptr, node[0].mat_ptr); } void bone_data::orient_x_cns(const vec3& target, float_t weight) { vec3 local_target; - mat4_inverse_transform_point(node[0].mat, &target, &local_target); + mat4_inverse_transform_point(node[0].mat_ptr, &target, &local_target); local_target.x = 0.0f; float_t len = vec2::length(*(vec2*)&local_target.y); if (fabsf(len) > 0.000001f) { float_t angle = atan2f((1.0f / len) * local_target.z, (1.0f / len) * local_target.y); - mat4_mul_rotate_x(node[0].mat, angle * weight, node[0].mat); + mat4_mul_rotate_x(node[0].mat_ptr, angle * weight, node[0].mat_ptr); } } @@ -12131,7 +12154,7 @@ void bone_data::orient_y(vec3 y_axis) { mat4_set_row(&rot_mat, 2, z_axis.x, z_axis.y, z_axis.z, 0.0f); mat4_set_row(&rot_mat, 3, 0.0f, 0.0f, 0.0f, 1.0f); - mat4_mul(&rot_mat, node[0].mat, node[0].mat); + mat4_mul(&rot_mat, node[0].mat_ptr, node[0].mat_ptr); } vec3* bone_data::set_key_data(vec3* keyframe_data, @@ -13656,10 +13679,14 @@ void rob_chara_pv_data::reset() { eyes_adjust = {}; } -rob_chara_item_equip_object::rob_chara_item_equip_object() : index(), mats(), obj_info(), -field_14(), texture_data(), null_blocks_data_set(), alpha(), obj_flags(), can_disp(), -field_A4(), mat(), init_iterations(), bone_nodes(), field_138(), osage_depends_on_others(), -osage_nodes_count(), use_opd(), skin_ex_data(), skin(), item_equip() { +RobSkinOfs::RobSkinOfs() : flag() { + +} + +rob_chara_item_equip_object::rob_chara_item_equip_object() : index(), motion_matrix(), +obj_info(), obj_uid_sub(), alpha(), obj_flags(), can_disp(), bone_kind(), +mat(), init_cnt(), motion_node(), field_138(), osage_depends_on_others(), +osage_nodes_count(), use_opd(), skin_ex_data(), skin(), rob_disp() { init_members(0x12345678); } @@ -13670,18 +13697,18 @@ rob_chara_item_equip_object::~rob_chara_item_equip_object() { void rob_chara_item_equip_object::add_motion_reset_data( uint32_t motion_id, float_t frame, int32_t iterations) { if (iterations > 0) - rob_chara_item_equip_object_ctrl_init_iterate(this, iterations); + pos_reset(iterations); - for (ExOsageBlock*& i : osage_blocks) + for (ExOsageBlock*& i : osage_blk) i->AddMotionResetData(motion_id, frame); - for (ExClothBlock*& i : cloth_blocks) + for (ExClothBlock*& i : cloth) i->AddMotionResetData(motion_id, frame); } void rob_chara_item_equip_object::check_no_opd(std::vector& opd_blend_data) { use_opd = true; - if (!osage_blocks.size() && !cloth_blocks.size() || !opd_blend_data.size()) + if (!osage_blk.size() && !cloth.size() || !opd_blend_data.size()) return; for (::opd_blend_data& i : opd_blend_data) { @@ -13696,37 +13723,37 @@ void rob_chara_item_equip_object::check_no_opd(std::vector& opd_ } void rob_chara_item_equip_object::clear_ex_data() { - for (ExNullBlock*& i : null_blocks) { - i->Reset(); + for (ExNullBlock*& i : null_blk) { + i->dest(); delete i; } - null_blocks.clear(); + null_blk.clear(); - for (ExOsageBlock*& i : osage_blocks) { - i->Reset(); + for (ExOsageBlock*& i : osage_blk) { + i->dest(); delete i; } - osage_blocks.clear(); + osage_blk.clear(); - for (ExConstraintBlock*& i : constraint_blocks) { - i->Reset(); + for (ExConstraintBlock*& i : constraint) { + i->dest(); delete i; } - constraint_blocks.clear(); + constraint.clear(); - for (ExExpressionBlock*& i : expression_blocks) { - i->Reset(); + for (ExExpressionBlock*& i : expression) { + i->dest(); delete i; } - expression_blocks.clear(); + expression.clear(); - for (ExClothBlock*& i : cloth_blocks) { - i->Reset(); + for (ExClothBlock*& i : cloth) { + i->dest(); delete i; } - cloth_blocks.clear(); + cloth.clear(); - node_blocks.clear(); + ex_node_block.clear(); } void rob_chara_item_equip_object::disp(const mat4& mat, render_context* rctx) { @@ -13742,49 +13769,48 @@ void rob_chara_item_equip_object::disp(const mat4& mat, render_context* rctx) { rctx->disp_manager->set_obj_flags(chara_flags); if (can_disp) { rctx->disp_manager->entry_obj_by_object_info_object_skin(obj_info, - &texture_pattern, &texture_data, alpha, mats, ex_data_bone_mats.data(), 0, mat); + &texchg_vec, &skn_col, alpha, motion_matrix, matrix.data(), 0, mat); - for (ExNodeBlock*& i : node_blocks) - i->Disp(mat, rctx); + for (ExNodeBlock*& i : ex_node_block) + i->disp(mat, rctx); } rctx->disp_manager->set_obj_flags(flags); } -int32_t rob_chara_item_equip_object::get_bone_index(const char* name, const bone_database* bone_data) { +int32_t rob_chara_item_equip_object::get_node_index(const char* name, const bone_database* bone_data) const { int32_t bone_index = bone_data->get_skeleton_motion_bone_index( bone_database_skeleton_type_to_string(BONE_DATABASE_SKELETON_COMMON), name); if (bone_index == -1) - for (auto& i : ex_bones) + for (auto& i : node_name_map) if (!str_utils_compare(name, i.first)) return 0x8000 | i.second; return bone_index; } -bone_node* rob_chara_item_equip_object::get_bone_node( - int32_t bone_index) { +const bone_node* rob_chara_item_equip_object::get_node(int32_t bone_index) const { if (!(bone_index & 0x8000)) - return &bone_nodes[bone_index & 0x7FFF]; - else if ((bone_index & 0x7FFF) < ex_data_bone_nodes.size()) - return &ex_data_bone_nodes[bone_index & 0x7FFF]; + return &motion_node[bone_index & 0x7FFF]; + else if ((bone_index & 0x7FFF) < ex_node.size()) + return &ex_node[bone_index & 0x7FFF]; return 0; } -bone_node* rob_chara_item_equip_object::get_bone_node(const char* name, const bone_database* bone_data) { - return get_bone_node(get_bone_index(name, bone_data)); +const bone_node* rob_chara_item_equip_object::get_node(const char* name, const bone_database* bone_data) const { + return get_node(get_node_index(name, bone_data)); } const mat4* rob_chara_item_equip_object::get_ex_data_bone_node_mat(const char* name) { - if (!name || !ex_data_bone_nodes.size()) + if (!name || !ex_node.size()) return &mat4_identity; - for (bone_node& i : ex_data_bone_nodes) + for (bone_node& i : ex_node) if (!str_utils_compare(i.name, name)) - return i.mat; + return i.mat_ptr; return &mat4_identity; } -RobOsageNode* rob_chara_item_equip_object::get_normal_ref_osage_node(const std::string& str, size_t* index) { +RobJointNode* rob_chara_item_equip_object::get_normal_ref_osage_node(const std::string& str, size_t* index) { if (!str.size()) return 0; @@ -13798,45 +13824,45 @@ RobOsageNode* rob_chara_item_equip_object::get_normal_ref_osage_node(const std:: if (index) *index = node_idx; - RobOsageNode* node = 0; - for (ExOsageBlock*& i : osage_blocks) + RobJointNode* node = 0; + for (ExOsageBlock*& i : osage_blk) if (!name.compare(i->name)) { - if (node_idx < i->rob.nodes.size()) - node = i->rob.GetNode(node_idx + 1); + if (node_idx < i->osage_work.joint_node_vec.size()) + node = i->osage_work.get_joint_node(node_idx + 1); break; } return node; } -void rob_chara_item_equip_object::get_parent_bone_nodes(bone_node* bone_nodes, const bone_database* bone_data) { - this->bone_nodes = bone_nodes; - mats = bone_nodes->mat; - for (ExNodeBlock*& i : node_blocks) - i->parent_bone_node = get_bone_node(i->parent_name.c_str(), bone_data); +void rob_chara_item_equip_object::get_parent_bone_nodes(bone_node* motion_node, const bone_database* bone_data) { + this->motion_node = motion_node; + motion_matrix = motion_node->mat_ptr; + for (ExNodeBlock*& i : ex_node_block) + i->parent = get_node(i->parent_name.c_str(), bone_data); } void rob_chara_item_equip_object::init_ex_data_bone_nodes(obj_skin_ex_data* ex_data) { - ex_data_bone_nodes.clear(); - ex_data_bone_mats.clear(); - ex_data_mats.clear(); + ex_node.clear(); + matrix.clear(); + no_scale_matrix.clear(); - int32_t num_bone_name = ex_data->num_bone_name; - ex_data_bone_nodes.resize(num_bone_name); - ex_data_bone_mats.resize(num_bone_name); - ex_data_mats.resize(num_bone_name); + int32_t nb_node_name = ex_data->nb_node_name; + ex_node.resize(nb_node_name); + matrix.resize(nb_node_name); + no_scale_matrix.resize(nb_node_name); - bone_node* bone_nodes = ex_data_bone_nodes.data(); - mat4* bone_mats = ex_data_bone_mats.data(); - mat4* mats = ex_data_mats.data(); - for (int32_t i = 0; i < num_bone_name; i++) - bone_nodes[i].mat = &bone_mats[i]; + bone_node* motion_node = ex_node.data(); + mat4* mat = matrix.data(); + mat4* no_scale_mat = no_scale_matrix.data(); + for (int32_t i = 0; i < nb_node_name; i++) + motion_node[i].mat_ptr = &mat[i]; - if (ex_data->bone_name_array) { - ex_bones.clear(); - const char** bone_name_array = ex_data->bone_name_array; - for (int32_t i = 0; i < num_bone_name; i++) { - bone_nodes[i].set_name_mat_ex_data_mat(bone_name_array[i], &bone_mats[i], &mats[i]); - ex_bones.push_back(bone_name_array[i], i); + if (ex_data->ex_node_name) { + node_name_map.clear(); + const char** ex_node_name = ex_data->ex_node_name; + for (int32_t i = 0; i < nb_node_name; i++) { + motion_node[i].set_name_mat_no_scale_mat(ex_node_name[i], &mat[i], &no_scale_mat[i]); + node_name_map.push_back(ex_node_name[i], i); } } } @@ -13844,26 +13870,26 @@ void rob_chara_item_equip_object::init_ex_data_bone_nodes(obj_skin_ex_data* ex_d void rob_chara_item_equip_object::init_members(size_t index) { this->index = index; obj_info = {}; - field_14 = -1; - mats = 0; - texture_pattern.clear(); - texture_data.field_0 = -1; - texture_data.texture_color_coefficients = 1.0f; - texture_data.texture_color_offset = 0.0f; - texture_data.texture_specular_coefficients = 1.0f; - texture_data.texture_specular_offset = 0.0f; + obj_uid_sub = {}; + motion_matrix = 0; + texchg_vec.clear(); + skn_col.type = -1; + skn_col.blend_color = 1.0f; + skn_col.offset_color = 0.0f; + skn_col.blend_specular = 1.0f; + skn_col.offset_specular = 0.0f; alpha = 1.0f; obj_flags = mdl::OBJ_ALPHA_ORDER_POST_GLITTER; - null_blocks_data_set = 0; + skn_ofs.flag = false; can_disp = true; - field_A4 = 0; + bone_kind = 0; mat = 0; - bone_nodes = 0; + motion_node = 0; clear_ex_data(); - ex_data_bone_nodes.clear(); - ex_data_bone_mats.clear(); - ex_data_mats.clear(); - ex_bones.clear(); + ex_node.clear(); + matrix.clear(); + no_scale_matrix.clear(); + node_name_map.clear(); osage_depends_on_others = false; use_opd = false; osage_nodes_count = 0; @@ -13871,11 +13897,11 @@ void rob_chara_item_equip_object::init_members(size_t index) { void rob_chara_item_equip_object::load_ex_data(obj_skin_ex_data* ex_data, const bone_database* bone_data, void* data, const object_database* obj_db) { - if (!ex_data->block_array) + if (!ex_data->ex_node_table) return; - prj::vector_pair osage_node_list; - std::map node_list; + prj::vector_pair joint_node_list; + std::map ex_node_list; clear_ex_data(); size_t constraint_count = 0; @@ -13883,60 +13909,59 @@ void rob_chara_item_equip_object::load_ex_data(obj_skin_ex_data* ex_data, size_t osage_count = 0; size_t cloth_count = 0; size_t null_count = 0; - const char** bone_name_array = ex_data->bone_name_array; - obj_skin_block* block = ex_data->block_array; - int32_t num_block = ex_data->num_block; - for (int32_t i = 0; i < num_block; i++, block++) { + const char** ex_node_name = ex_data->ex_node_name; + obj_skin_ex_node* block = ex_data->ex_node_table; + int32_t num_ex_node = ex_data->num_ex_node; + for (int32_t i = 0; i < num_ex_node; i++, block++) { ExNodeBlock* ex_node; switch (block->type) { - case OBJ_SKIN_BLOCK_CLOTH: { + case OBJ_SKIN_EX_NODE_CLOTH: { if (cloth_count >= 0x08) continue; ExClothBlock* cls = new ExClothBlock; ex_node = cls; - cloth_blocks.push_back(cls); - cls->InitData(this, block->cloth, 0, bone_data); - cls->index = cloth_count + osage_count; - cls->name = block->cloth->mesh_name; + cloth.push_back(cls); + cls->set_data(this, block->cloth, 0, bone_data); + cls->block_idx = cloth_count + osage_count; + cls->name = block->cloth->omote_name; cloth_count++; } break; - case OBJ_SKIN_BLOCK_CONSTRAINT: { + case OBJ_SKIN_EX_NODE_CONSTRAINT: { if (constraint_count >= 0x40) continue; ExConstraintBlock* cns = new ExConstraintBlock; ex_node = cns; - constraint_blocks.push_back(cns); - cns->InitData(this, block->constraint, - bone_name_array[block->constraint->name_index & 0x7FFF], bone_data); + constraint.push_back(cns); + cns->set_data(this, block->constraint, + ex_node_name[block->constraint->node_name & 0x7FFF], bone_data); constraint_count++; } break; - case OBJ_SKIN_BLOCK_EXPRESSION: { + case OBJ_SKIN_EX_NODE_EXPRESSION: { if (expression_count >= 0x50) continue; ExExpressionBlock* exp = new ExExpressionBlock; ex_node = exp; - expression_blocks.push_back(exp); - exp->InitData(this, block->expression, - bone_name_array[block->expression->name_index & 0x7FFF], obj_info, index, bone_data); + expression.push_back(exp); + exp->set_data(this, block->expression, + ex_node_name[block->expression->node_name & 0x7FFF], obj_info, index, bone_data); expression_count++; } break; - case OBJ_SKIN_BLOCK_OSAGE: { + case OBJ_SKIN_EX_NODE_OSAGE: { if (osage_count >= 0x100) continue; ExOsageBlock* osg = new ExOsageBlock; ex_node = osg; - osage_blocks.push_back(osg); - osg->InitData(this, block->osage, - bone_name_array[block->osage->name_index & 0x7FFF], - &skin_ex_data->osage_node_array[block->osage->start_index], - bone_nodes, ex_data_bone_nodes.data(), skin); - osg->GetNodeList(block->osage, - &skin_ex_data->osage_node_array[block->osage->start_index], osage_node_list, node_list); - osg->index = osage_count; + osage_blk.push_back(osg); + osg->set_data(this, block->osage, ex_node_name[block->osage->root_idx & 0x7FFF], + &skin_ex_data->osage_joint[block->osage->joint_ofs], + motion_node, this->ex_node.data(), skin); + osg->get_node_list(block->osage, + &skin_ex_data->osage_joint[block->osage->joint_ofs], joint_node_list, ex_node_list); + osg->block_idx = osage_count; osage_count++; } break; default: { @@ -13945,55 +13970,55 @@ void rob_chara_item_equip_object::load_ex_data(obj_skin_ex_data* ex_data, ExNullBlock* null = new ExNullBlock; ex_node = null; - null_blocks.push_back(null); - null->InitData(this, block->constraint, - bone_name_array[block->constraint->name_index & 0x7FFF], bone_data); + null_blk.push_back(null); + null->set_data(this, block->constraint, + ex_node_name[block->constraint->node_name & 0x7FFF], bone_data); null_count++; } break; } - obj_skin_block_node* node = block->node; - bone_node_expression_data exp_data; - exp_data.position = node->position; - exp_data.rotation = node->rotation; - exp_data.scale = node->scale; - exp_data.parent_scale = 1.0f; - ex_node->parent_name = node->parent_name; + obj_skin_ex_node_transform* b_transform = block->transform; + RobTransform transform; + transform.pos = b_transform->position; + transform.rot = b_transform->rotation; + transform.scale = b_transform->scale; + transform.hsc = 1.0f; + ex_node->parent_name = b_transform->parent_name; - bone_node* parent_bone_node = get_bone_node(node->parent_name, bone_data); - ex_node->parent_bone_node = parent_bone_node; - if (ex_node->bone_node_ptr) { - ex_node->bone_node_ptr->exp_data = exp_data; - ex_node->bone_node_ptr->parent = parent_bone_node; + const bone_node* parent = get_node(b_transform->parent_name, bone_data); + ex_node->parent = parent; + if (ex_node->dst_node) { + ex_node->dst_node->transform = transform; + ex_node->dst_node->parent = parent; } - if (parent_bone_node) { - auto elem = node_list.find(parent_bone_node->name); - if (elem != node_list.end()) + if (parent) { + auto elem = ex_node_list.find(parent->name); + if (elem != ex_node_list.end()) ex_node->parent_node = elem->second; } - node_list.insert({ ex_node->name, ex_node }); - node_blocks.push_back(ex_node); + ex_node_list.insert({ ex_node->name, ex_node }); + ex_node_block.push_back(ex_node); } - for (ExNodeBlock*& i : node_blocks) { + for (ExNodeBlock*& i : ex_node_block) { ExNodeBlock* parent_node = i->parent_node; if (parent_node) { parent_node->has_children_node = true; - if ((parent_node->type & ~0x03) || parent_node->type == EX_OSAGE + if ((parent_node->type & ~0x03) || parent_node->type == EX_NODE_TYPE_OSAGE || !parent_node->is_parent) continue; } i->is_parent = true; } - for (ExOsageBlock*& i : osage_blocks) { + for (ExOsageBlock*& i : osage_blk) { ExOsageBlock* osg = i; - ExNodeBlock* parent_node = osg->parent_node; - bone_node* parent_bone_node = 0; + const ExNodeBlock* parent_node = osg->parent_node; + const bone_node* parent = 0; if (!parent_node || osg->is_parent) - parent_bone_node = osg->parent_bone_node; + parent = osg->parent; else { while (!parent_node->is_parent) { parent_node = parent_node->parent_node; @@ -14002,35 +14027,35 @@ void rob_chara_item_equip_object::load_ex_data(obj_skin_ex_data* ex_data, } if (parent_node) - parent_bone_node = parent_node->parent_bone_node; + parent = parent_node->parent; } - if (parent_bone_node && parent_bone_node->ex_data_mat) { - osg->rob.root_matrix_ptr = parent_bone_node->ex_data_mat; - osg->rob.root_matrix_prev = *parent_bone_node->ex_data_mat; + if (parent && parent->no_scale_mat) { + osg->osage_work.root_matrix_ptr = parent->no_scale_mat; + osg->osage_work.root_matrix_prev = *parent->no_scale_mat; } } - if (ex_data->osage_sibling_info_array) { - obj_skin_osage_sibling_info* sibling_info = ex_data->osage_sibling_info_array; - for (int32_t i = 0; i < ex_data->num_osage_sibling_info; i++, sibling_info++) { - uint32_t name_index = sibling_info->name_index; - uint32_t sibling_name_index = sibling_info->sibling_name_index; + if (ex_data->osage_constraint_tbl) { + obj_skin_osage_constraint_info* sibling_info = ex_data->osage_constraint_tbl; + for (int32_t i = 0; i < ex_data->num_osage_constraint; i++, sibling_info++) { + uint32_t dst_joint = sibling_info->dst_joint; + uint32_t src_joint = sibling_info->src_joint; - auto node_elem = osage_node_list.begin(); - for (; node_elem != osage_node_list.end(); node_elem++) - if (node_elem->first == name_index) + auto node_elem = joint_node_list.begin(); + for (; node_elem != joint_node_list.end(); node_elem++) + if (node_elem->first == dst_joint) break; - auto sibling_node_elem = osage_node_list.begin(); - for (; sibling_node_elem != osage_node_list.end(); sibling_node_elem++) - if (sibling_node_elem->first == sibling_name_index) + auto distance_elem = joint_node_list.begin(); + for (; distance_elem != joint_node_list.end(); distance_elem++) + if (distance_elem->first == src_joint) break; - if (node_elem != osage_node_list.end() && sibling_node_elem != osage_node_list.end()) { - RobOsageNode* _node = node_elem->second; - _node->sibling_node = sibling_node_elem->second; - _node->max_distance = sibling_info->max_distance; + if (node_elem != joint_node_list.end() && distance_elem != joint_node_list.end()) { + RobJointNode* node = node_elem->second; + node->distance = distance_elem->second; + node->length_dist = sibling_info->length; } } } @@ -14039,21 +14064,21 @@ void rob_chara_item_equip_object::load_ex_data(obj_skin_ex_data* ex_data, skp_load_file(data, bone_data, obj_db); size_t osage_nodes_count = 0; - for (ExOsageBlock*& i : osage_blocks) - osage_nodes_count += i->rob.nodes.size() - 1; - for (ExClothBlock*& i : cloth_blocks) - osage_nodes_count += i->rob.nodes.size() - i->rob.root_count; + for (ExOsageBlock*& i : osage_blk) + osage_nodes_count += i->osage_work.joint_node_vec.size() - 1; + for (ExClothBlock*& i : cloth) + osage_nodes_count += i->cloth_work.vtxarg.size() - i->cloth_work.width; this->osage_nodes_count = osage_nodes_count; } -void rob_chara_item_equip_object::load_object_info_ex_data(object_info obj_info, bone_node* bone_nodes, +void rob_chara_item_equip_object::load_object_info_ex_data(object_info obj_info, const bone_node* motion_node, bool osage_reset, const bone_database* bone_data, void* data, const object_database* obj_db) { this->obj_info = obj_info; - this->bone_nodes = bone_nodes; - mats = bone_nodes->mat; - ex_data_bone_nodes.clear(); - ex_bones.clear(); - ex_data_bone_mats.clear(); + this->motion_node = motion_node; + motion_matrix = motion_node->mat_ptr; + ex_node.clear(); + node_name_map.clear(); + matrix.clear(); clear_ex_data(); obj_skin* skin = objset_info_storage_get_obj_skin(this->obj_info); @@ -14068,8 +14093,8 @@ void rob_chara_item_equip_object::load_object_info_ex_data(object_info obj_info, init_ex_data_bone_nodes(skin->ex_data); load_ex_data(skin->ex_data, bone_data, data, obj_db); - if (osage_reset && osage_blocks.size()) - init_iterations = 60; + if (osage_reset && osage_blk.size()) + init_cnt = 60; } void rob_chara_item_equip::load_outfit_object_info(item_id id, object_info obj_info, @@ -14079,18 +14104,38 @@ void rob_chara_item_equip::load_outfit_object_info(item_id id, object_info obj_i load_object_info(obj_info, id, osage_reset, bone_data, data, obj_db); } -void rob_chara_item_equip_object::reset_external_force() { - for (ExOsageBlock*& i : osage_blocks) - i->rob.ResetExtrenalForce(); - for (ExClothBlock*& i : cloth_blocks) - i->rob.ResetExtrenalForce(); +// 0x1405F4820 +void rob_chara_item_equip_object::pos_reset(int32_t init_cnt) { + if (!ex_node_block.size()) + return; + + auto pos_init = &ExNodeBlock::pos_init; + auto pos_init_cont = &ExNodeBlock::pos_init_cont; + + for (ExNodeBlock*& i : ex_node_block) + (i->*pos_init)(); + + for (; init_cnt; init_cnt--) { + if (osage_depends_on_others) + rob_chara_item_equip_object_ctrl_step(this, true); + + for (ExNodeBlock*& i : ex_node_block) + (i->*pos_init_cont)(); + } } -void rob_chara_item_equip_object::reset_nodes_external_force(rob_osage_parts_bit parts_bits) { - for (ExOsageBlock*& i : osage_blocks) - if (i->rob.CheckPartsBits(parts_bits)) { - i->rob.SetNodesExternalForce(0, 1.0f); - i->rob.SetNodesForce(1.0f); +void rob_chara_item_equip_object::reset_ex_force() { + for (ExOsageBlock*& i : osage_blk) + i->reset_ex_force(); + for (ExClothBlock*& i : cloth) + i->reset_ex_force(); +} + +void rob_chara_item_equip_object::reset_nodes_ex_force(rob_osage_parts_bit parts_bits) { + for (ExOsageBlock*& i : osage_blk) + if (i->osage_work.CheckPartsBits(parts_bits)) { + i->osage_work.SetNodesExternalForce(0, 1.0f); + i->osage_work.SetNodesForce(1.0f); } } @@ -14101,19 +14146,19 @@ void rob_chara_item_equip_object::set_alpha_obj_flags(float_t alpha, int32_t fla bool rob_chara_item_equip_object::set_boc( const skin_param_osage_root& skp_root, ExOsageBlock* osg) { - RobOsage& rob_osg = osg->rob; - rob_osg.ResetBoc(); + RobOsage& osage_work = osg->osage_work; + osage_work.dest_boc(); bool has_boc_node = false; for (const skin_param_osage_root_boc& i : skp_root.boc) - for (ExOsageBlock*& j : osage_blocks) { + for (ExOsageBlock*& j : osage_blk) { if (i.ed_root.compare(j->name) - || i.ed_node + 1ULL >= rob_osg.nodes.size() - || i.st_node + 1ULL >= j->rob.nodes.size()) + || i.ed_node + 1ULL >= osage_work.joint_node_vec.size() + || i.st_node + 1ULL >= j->osage_work.joint_node_vec.size()) continue; - RobOsageNode* ed_node = rob_osg.GetNode(i.ed_node + 1ULL); - RobOsageNode* st_node = j->rob.GetNode(i.st_node + 1ULL); + RobJointNode* ed_node = osage_work.get_joint_node(i.ed_node + 1ULL); + RobJointNode* st_node = j->osage_work.get_joint_node(i.st_node + 1ULL); ed_node->data_ptr->boc.push_back(st_node); has_boc_node = true; break; @@ -14127,24 +14172,24 @@ void rob_chara_item_equip_object::set_collision_target_osage( return; const char* colli_tgt_osg = skp_root.colli_tgt_osg.c_str(); - for (ExOsageBlock*& i : osage_blocks) + for (ExOsageBlock*& i : osage_blk) if (!str_utils_compare(colli_tgt_osg, i->name)) { - skp->colli_tgt_osg = &i->rob.nodes; + skp->colli_tgt_osg = &i->osage_work.joint_node_vec; break; } } void rob_chara_item_equip_object::set_disable_collision(rob_osage_parts_bit parts_bits, bool disable) { - for (ExOsageBlock*& i : osage_blocks) - if (i->rob.CheckPartsBits(parts_bits)) + for (ExOsageBlock*& i : osage_blk) + if (i->osage_work.CheckPartsBits(parts_bits)) i->SetDisableCollision(disable); } void rob_chara_item_equip_object::set_motion_reset_data(uint32_t motion_id, float_t frame) { - for (ExOsageBlock*& i : osage_blocks) + for (ExOsageBlock*& i : osage_blk) i->SetMotionResetData(motion_id, frame); - for (ExClothBlock*& i : cloth_blocks) + for (ExClothBlock*& i : cloth) i->SetMotionResetData(motion_id, frame); } @@ -14159,12 +14204,12 @@ void rob_chara_item_equip_object::set_motion_skin_param(int8_t chara_id, uint32_ osage_depends_on_others = false; skin_param_file_data* j = skp_file_data->data(); - for (ExOsageBlock*& i : osage_blocks) { + for (ExOsageBlock*& i : osage_blk) { osage_depends_on_others |= j->depends_on_others; i->SetSkinParam(j++); } - for (ExClothBlock*& i : cloth_blocks) { + for (ExClothBlock*& i : cloth) { osage_depends_on_others |= j->depends_on_others; i->SetSkinParam(j++); } @@ -14176,47 +14221,47 @@ void rob_chara_item_equip_object::set_null_blocks_expression_data( const vec3 rot = rotation * DEG_TO_RAD_FLOAT; const vec3 sc = scale; - null_blocks_data_set = true; - for (ExNullBlock*& i : null_blocks) { - if (!i || !i->bone_node_ptr) + skn_ofs.flag = true; + for (ExNullBlock*& i : null_blk) { + if (!i || !i->dst_node) continue; - bone_node_expression_data* node_exp_data = &i->bone_node_ptr->exp_data; - node_exp_data->position = pos; - node_exp_data->rotation = rot; - node_exp_data->scale = sc; + RobTransform& transform = i->dst_node->transform; + transform.pos = pos; + transform.rot = rot; + transform.scale = sc; } } void rob_chara_item_equip_object::set_osage_play_data_init(const float_t* opdi_data) { - for (ExOsageBlock*& i : osage_blocks) + for (ExOsageBlock*& i : osage_blk) opdi_data = i->SetOsagePlayDataInit(opdi_data); - for (ExClothBlock*& i : cloth_blocks) + for (ExClothBlock*& i : cloth) opdi_data = i->SetOsagePlayDataInit(opdi_data); } void rob_chara_item_equip_object::set_osage_reset() { - for (ExOsageBlock*& i : osage_blocks) + for (ExOsageBlock*& i : osage_blk) i->SetOsageReset(); - for (ExClothBlock*& i : cloth_blocks) + for (ExClothBlock*& i : cloth) i->SetOsageReset(); } -void rob_chara_item_equip_object::set_osage_move_cancel(const float_t& value) { - for (ExOsageBlock*& i : osage_blocks) - i->SetMoveCancel(value); +void rob_chara_item_equip_object::set_osage_move_cancel(const float_t& mv_ccl) { + for (ExOsageBlock*& i : osage_blk) + i->set_move_cancel(mv_ccl); - for (ExClothBlock*& i : cloth_blocks) - i->SetMoveCancel(value); + for (ExClothBlock*& i : cloth) + i->set_move_cancel(mv_ccl); } void rob_chara_item_equip_object::set_texture_pattern(texture_pattern_struct* tex_pat, size_t count) { - texture_pattern.clear(); + texchg_vec.clear(); if (count && tex_pat) for (size_t i = 0; i < count; i++) - texture_pattern.push_back(tex_pat[i]); + texchg_vec.push_back(tex_pat[i]); } void rob_chara_item_equip_object::skp_load(void* kv, const bone_database* bone_data) { @@ -14225,19 +14270,19 @@ void rob_chara_item_equip_object::skp_load(void* kv, const bone_database* bone_d return; osage_depends_on_others = false; - for (ExOsageBlock*& i : osage_blocks) { + for (ExOsageBlock*& i : osage_blk) { ExOsageBlock* osg = i; skin_param_osage_root root; - osg->rob.LoadSkinParam(_kv, osg->name, root, &obj_info, bone_data); - set_collision_target_osage(root, osg->rob.skin_param_ptr); + osg->osage_work.LoadSkinParam(_kv, osg->name, root, &obj_info, bone_data); + set_collision_target_osage(root, osg->osage_work.skin_param_ptr); osage_depends_on_others |= set_boc(root, osg); osage_depends_on_others |= root.coli_type != SkinParam::RootCollisionTypeEnd; osage_depends_on_others |= skp_load_normal_ref(root, 0); } - for (ExClothBlock*& i : cloth_blocks) { + for (ExClothBlock*& i : cloth) { ExClothBlock* cls = i; - cls->rob.LoadSkinParam(_kv, cls->name, bone_data); + cls->cloth_work.LoadSkinParam(_kv, cls->name, bone_data); } } @@ -14248,7 +14293,7 @@ void rob_chara_item_equip_object::skp_load(const skin_param_osage_root& skp_root skin_param_osage_node* j = vec.data(); size_t k = 0; - for (RobOsageNodeData& i : skp_file_data->nodes_data) + for (RobJointNodeData& i : skp_file_data->nodes_data) i.SetForce(skp_root, j++, k++); skp_file_data->depends_on_others |= skp_load_boc(skp_root, &skp_file_data->nodes_data); @@ -14256,17 +14301,17 @@ void rob_chara_item_equip_object::skp_load(const skin_param_osage_root& skp_root } bool rob_chara_item_equip_object::skp_load_boc( - const skin_param_osage_root& skp_root, std::vector* node_data) { + const skin_param_osage_root& skp_root, std::vector* node_data) { bool has_boc_node = false; for (const skin_param_osage_root_boc& i : skp_root.boc) - for (ExOsageBlock*& j : osage_blocks) { + for (ExOsageBlock*& j : osage_blk) { if (i.ed_root.compare(j->name) || i.ed_node >= node_data->size() - || i.st_node >= j->rob.nodes.size()) + || i.st_node >= j->osage_work.joint_node_vec.size()) continue; - RobOsageNodeData& ed_node = node_data->data()[i.ed_node]; - RobOsageNode* st_node = j->rob.GetNode(i.st_node + 1ULL); + RobJointNodeData& ed_node = node_data->data()[i.ed_node]; + RobJointNode* st_node = j->osage_work.get_joint_node(i.st_node + 1ULL); ed_node.boc.push_back(st_node); has_boc_node = true; break; @@ -14291,17 +14336,17 @@ void rob_chara_item_equip_object::skp_load_file(void* data, } bool rob_chara_item_equip_object::skp_load_normal_ref( - const skin_param_osage_root& skp_root, std::vector* node_data) { + const skin_param_osage_root& skp_root, std::vector* node_data) { if (!skp_root.normal_ref.size()) return false; for (const skin_param_osage_root_normal_ref& i : skp_root.normal_ref) { size_t index = 0; - RobOsageNode* n = get_normal_ref_osage_node(i.n, &index); + RobJointNode* n = get_normal_ref_osage_node(i.n, &index); if (!n) continue; - RobOsageNodeData* data = node_data ? &(*node_data)[index] : n->data_ptr; + RobJointNodeData* data = node_data ? &(*node_data)[index] : n->data_ptr; data->normal_ref.n = n; data->normal_ref.u = get_normal_ref_osage_node(i.u, 0); data->normal_ref.d = get_normal_ref_osage_node(i.d, 0); @@ -14325,7 +14370,7 @@ field_920(), field_928(), field_930(), use_opd(), parts_short(), parts_append(), osage_step = 1.0f; for (int32_t i = ITEM_BODY; i < ITEM_MAX; i++) - item_equip_object[i].item_equip = this; + item_equip_object[i].rob_disp = this; } rob_chara_item_equip::~rob_chara_item_equip() { @@ -14364,11 +14409,11 @@ static void sub_140512C20(rob_chara_item_equip* rob_itm_equip, render_context* r data_struct* aft_data = &data_list[DATA_AFT]; bone_database* aft_bone_data = &aft_data->data_ft.bone_data; - bone_node* node = rob_itm_equip->item_equip_object[rob_itm_equip->field_D4].get_bone_node(name, aft_bone_data); - if (!node || !node->mat) + const bone_node* node = rob_itm_equip->item_equip_object[rob_itm_equip->field_D4].get_node(name, aft_bone_data); + if (!node || !node->mat_ptr) return; - mat4_mul(node->mat, &mat, &mat); + mat4_mul(node->mat_ptr, &mat, &mat); int32_t tex_pat_count = (int32_t)rob_itm_equip->texture_pattern.size(); if (tex_pat_count) rctx->disp_manager->set_texture_pattern(tex_pat_count, rob_itm_equip->texture_pattern.data()); @@ -14467,7 +14512,7 @@ object_info rob_chara_item_equip::get_object_info(item_id id) { void rob_chara_item_equip::get_parent_bone_nodes(bone_node* bone_nodes, const bone_database* bone_data) { this->bone_nodes = bone_nodes; - matrices = bone_nodes->mat; + matrices = bone_nodes->no_scale_mat; for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) item_equip_object[i].get_parent_bone_nodes(bone_nodes, bone_data); } @@ -14493,6 +14538,12 @@ void rob_chara_item_equip::load_object_info(object_info obj_info, item_id id, set_disp(id, true); } +// 0x1405135E0 +void rob_chara_item_equip::pos_reset(uint8_t init_cnt) { + for (int32_t i = ITEM_BODY; i < ITEM_MAX; i++) + item_equip_object[i].pos_reset(init_cnt); +} + void rob_chara_item_equip::reset() { bone_nodes = 0; matrices = 0; @@ -14514,15 +14565,15 @@ void rob_chara_item_equip::reset() { max_item_equip_object = ITEM_ITEM16; } -void rob_chara_item_equip::reset_external_force() { +void rob_chara_item_equip::reset_ex_force() { for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) - item_equip_object[i].reset_external_force(); + item_equip_object[i].reset_ex_force(); } void rob_chara_item_equip::reset_init_data(bone_node* bone_nodes) { reset(); this->bone_nodes = bone_nodes; - matrices = bone_nodes->mat; + matrices = bone_nodes->mat_ptr; mat4* v7 = field_13C; int32_t* v8 = field_18; @@ -14540,9 +14591,9 @@ void rob_chara_item_equip::reset_init_data(bone_node* bone_nodes) { mat = mat4_identity; } -void rob_chara_item_equip::reset_nodes_external_force(rob_osage_parts parts) { +void rob_chara_item_equip::reset_nodes_ex_force(rob_osage_parts parts) { item_equip_object[parts == ROB_OSAGE_PARTS_MUFFLER ? ITEM_OUTER : ITEM_KAMI] - .reset_nodes_external_force((rob_osage_parts_bit)(1 << parts)); + .reset_nodes_ex_force((rob_osage_parts_bit)(1 << parts)); } void rob_chara_item_equip::set_alpha_obj_flags(float_t alpha, mdl::ObjFlags flags) { @@ -14579,7 +14630,7 @@ void rob_chara_item_equip::set_motion_reset_data(uint32_t motion_id, float_t fra for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) item_equip_object[i].set_motion_reset_data(motion_id, frame); - task_wind->ptr->reset(); + task_wind->stage_wind.wind->reset(); } void rob_chara_item_equip::set_motion_skin_param(int8_t chara_id, uint32_t motion_id, int32_t frame) { @@ -14637,24 +14688,24 @@ void rob_chara_item_equip::set_osage_reset() { for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) item_equip_object[i].set_osage_reset(); - task_wind->ptr->reset(); + task_wind->stage_wind.wind->reset(); } void rob_chara_item_equip::set_osage_step(float_t value) { osage_step = value; } -void rob_chara_item_equip::set_osage_move_cancel(uint8_t id, const float_t& value) { +void rob_chara_item_equip::set_osage_move_cancel(uint8_t id, const float_t& mv_ccl) { switch (id) { case 0: for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) - item_equip_object[i].set_osage_move_cancel(value); + item_equip_object[i].set_osage_move_cancel(mv_ccl); break; case 1: - item_equip_object[ITEM_KAMI].set_osage_move_cancel(value); + item_equip_object[ITEM_KAMI].set_osage_move_cancel(mv_ccl); break; case 2: - item_equip_object[ITEM_OUTER].set_osage_move_cancel(value); + item_equip_object[ITEM_OUTER].set_osage_move_cancel(mv_ccl); break; } } @@ -15114,13 +15165,13 @@ static void sub_140522F90(rob_chara_item_cos_data* item_cos_data, rob_chara_item if (!item || item->data.col.size()) return; - vec3 texture_color_coefficients = item->data.col[0].col_tone.blend; - vec3 texture_color_offset = item->data.col[0].col_tone.offset; - vec3 texture_specular_coefficients = 1.0f; - vec3 texture_specular_offset = 0.0f; + vec3 blend_color = item->data.col[0].col_tone.blend; + vec3 offset_color = item->data.col[0].col_tone.offset; + vec3 blend_specular = 1.0f; + vec3 offset_specular = 0.0f; if (item->data.col.size() > 1) { - texture_specular_coefficients = item->data.col[1].col_tone.blend; - texture_specular_offset = item->data.col[1].col_tone.offset; + blend_specular = item->data.col[1].col_tone.blend; + offset_specular = item->data.col[1].col_tone.offset; } for (int32_t i = ITEM_ATAMA; i <= ITEM_ITEM16; i++) { @@ -15128,11 +15179,11 @@ static void sub_140522F90(rob_chara_item_cos_data* item_cos_data, rob_chara_item continue; rob_chara_item_equip_object* itm_eq_obj = &rob_itm_equip->item_equip_object[i]; - itm_eq_obj->texture_data.field_0 = false; - itm_eq_obj->texture_data.texture_color_coefficients = texture_color_coefficients; - itm_eq_obj->texture_data.texture_color_offset = texture_color_offset; - itm_eq_obj->texture_data.texture_specular_coefficients = texture_specular_coefficients; - itm_eq_obj->texture_data.texture_specular_offset = texture_specular_offset; + itm_eq_obj->skn_col.type = 0; + itm_eq_obj->skn_col.blend_color = blend_color; + itm_eq_obj->skn_col.offset_color = offset_color; + itm_eq_obj->skn_col.blend_specular = blend_specular; + itm_eq_obj->skn_col.offset_specular = offset_specular; } } @@ -15824,7 +15875,7 @@ void rob_chara_data_adjust::reset() { enable = false; frame = 0.0f; transition_frame = 0.0f; - curr_external_force = 0.0f; + curr_ex_force = 0.0f; curr_force = 1.0f; curr_strength = 1.0f; motion_id = -1; @@ -15833,9 +15884,9 @@ void rob_chara_data_adjust::reset() { type = 6; cycle_type = 0; ignore_gravity = true; - external_force = 0.0f; - external_force_cycle_strength = 0.0f; - external_force_cycle = 0.0f; + ex_force = 0.0f; + ex_force_cycle_strength = 0.0f; + ex_force_cycle = 0.0f; cycle = 1.0f; phase = 0.0f; force = 1.0f; @@ -17289,26 +17340,26 @@ void opd_chara_data::add_frame_data() { std::vector>& opd_data = this->opd_data[i]; size_t node_index = 0; - for (ExOsageBlock*& j : itm_eq_obj->osage_blocks) { + for (ExOsageBlock*& j : itm_eq_obj->osage_blk) { std::vector& opd_node_data = opd_data.data()[node_index++]; - RobOsageNode* k_begin = j->rob.nodes.data() + 1; - RobOsageNode* k_end = j->rob.nodes.data() + j->rob.nodes.size(); + RobJointNode* k_begin = j->osage_work.joint_node_vec.data() + 1; + RobJointNode* k_end = j->osage_work.joint_node_vec.data() + j->osage_work.joint_node_vec.size(); size_t l = 0; - for (RobOsageNode* k = k_begin; k != k_end; k++, l++) { + for (RobJointNode* k = k_begin; k != k_end; k++, l++) { opd_node_data.data()[l].x.data()[frame_index] = k->reset_data.pos.x; opd_node_data.data()[l].y.data()[frame_index] = k->reset_data.pos.y; opd_node_data.data()[l].z.data()[frame_index] = k->reset_data.pos.z; } } - for (ExClothBlock*& j : itm_eq_obj->cloth_blocks) { + for (ExClothBlock*& j : itm_eq_obj->cloth) { std::vector& opd_node_data = opd_data.data()[node_index++]; - CLOTHNode* k_begin = j->rob.nodes.data() + j->rob.root_count; - CLOTHNode* k_end = j->rob.nodes.data() + j->rob.nodes.size(); + CLOTH_VERTEX* k_begin = j->cloth_work.vtxarg.data() + j->cloth_work.width; + CLOTH_VERTEX* k_end = j->cloth_work.vtxarg.data() + j->cloth_work.vtxarg.size(); size_t l = 0; - for (CLOTHNode* k = k_begin; k != k_end; k++, l++) { + for (CLOTH_VERTEX* k = k_begin; k != k_end; k++, l++) { opd_node_data.data()[l].x.data()[frame_index] = k->reset_data.pos.x; opd_node_data.data()[l].y.data()[frame_index] = k->reset_data.pos.y; opd_node_data.data()[l].z.data()[frame_index] = k->reset_data.pos.z; @@ -17375,8 +17426,8 @@ void opd_chara_data::encode_data() { size_t osage_node_index = 0; bool higher_accuracy = false; for (const std::vector& j : opd_data) { - if (osage_node_index < itm_eq_obj->osage_blocks.size()) - higher_accuracy = itm_eq_obj->osage_blocks.data()[osage_node_index]->has_children_node; + if (osage_node_index < itm_eq_obj->osage_blk.size()) + higher_accuracy = itm_eq_obj->osage_blk.data()[osage_node_index]->has_children_node; for (const opd_vec3_data_vec& k : j) { size_t size_x = 0; @@ -17444,29 +17495,29 @@ void opd_chara_data::encode_init_data(uint32_t motion_id) { vec3* d = (vec3*)(data + sizeof(osage_play_data_init_header)); - for (ExOsageBlock*& j : itm_eq_obj->osage_blocks) { - if (!(j->rob.nodes.size())) + for (ExOsageBlock*& j : itm_eq_obj->osage_blk) { + if (!(j->osage_work.joint_node_vec.size())) break; - RobOsageNode* k_begin = j->rob.nodes.data() + 1; - RobOsageNode* k_end = j->rob.nodes.data() + j->rob.nodes.size(); - for (RobOsageNode* k = k_begin; k != k_end; k++) { + RobJointNode* k_begin = j->osage_work.joint_node_vec.data() + 1; + RobJointNode* k_end = j->osage_work.joint_node_vec.data() + j->osage_work.joint_node_vec.size(); + for (RobJointNode* k = k_begin; k != k_end; k++) { d[0] = k->pos; - d[1] = k->delta_pos; + d[1] = k->vec; d += 2; } } - for (ExClothBlock*& j : itm_eq_obj->cloth_blocks) { - if (!(j->rob.nodes.size())) + for (ExClothBlock*& j : itm_eq_obj->cloth) { + if (!(j->cloth_work.vtxarg.size())) break; - CLOTHNode* k_begin = j->rob.nodes.data() + j->rob.root_count; - CLOTHNode* k_end = j->rob.nodes.data() + j->rob.nodes.size(); + CLOTH_VERTEX* k_begin = j->cloth_work.vtxarg.data() + j->cloth_work.width; + CLOTH_VERTEX* k_end = j->cloth_work.vtxarg.data() + j->cloth_work.vtxarg.size(); size_t l = 0; - for (CLOTHNode* k = k_begin; k != k_end; k++, l++) { + for (CLOTH_VERTEX* k = k_begin; k != k_end; k++, l++) { d[0] = k->pos; - d[1] = k->delta_pos; + d[1] = k->vec; d += 2; } } @@ -17521,31 +17572,31 @@ void opd_chara_data::init_data(uint32_t motion_id) { std::vector>& opd_data = this->opd_data[i]; opd_data.clear(); - opd_data.resize(itm_eq_obj->cloth_blocks.size() + itm_eq_obj->osage_blocks.size()); + opd_data.resize(itm_eq_obj->cloth.size() + itm_eq_obj->osage_blk.size()); size_t node_index = 0; - for (ExOsageBlock*& j : itm_eq_obj->osage_blocks) { + for (ExOsageBlock*& j : itm_eq_obj->osage_blk) { std::vector& opd_node_data = opd_data.data()[node_index++]; - opd_node_data.resize(j->rob.nodes.size() - 1); + opd_node_data.resize(j->osage_work.joint_node_vec.size() - 1); - RobOsageNode* k_begin = j->rob.nodes.data() + 1; - RobOsageNode* k_end = j->rob.nodes.data() + j->rob.nodes.size(); + RobJointNode* k_begin = j->osage_work.joint_node_vec.data() + 1; + RobJointNode* k_end = j->osage_work.joint_node_vec.data() + j->osage_work.joint_node_vec.size(); size_t l = 0; - for (RobOsageNode* k = k_begin; k != k_end; k++, l++) { + for (RobJointNode* k = k_begin; k != k_end; k++, l++) { opd_node_data.data()[l].x.resize(frame_count); opd_node_data.data()[l].y.resize(frame_count); opd_node_data.data()[l].z.resize(frame_count); } } - for (ExClothBlock*& j : itm_eq_obj->cloth_blocks) { + for (ExClothBlock*& j : itm_eq_obj->cloth) { std::vector& opd_node_data = opd_data.data()[node_index++]; - opd_node_data.resize(j->rob.nodes.size() - j->rob.root_count); + opd_node_data.resize(j->cloth_work.vtxarg.size() - j->cloth_work.width); - CLOTHNode* k_begin = j->rob.nodes.data() + j->rob.root_count; - CLOTHNode* k_end = j->rob.nodes.data() + j->rob.nodes.size(); + CLOTH_VERTEX* k_begin = j->cloth_work.vtxarg.data() + j->cloth_work.width; + CLOTH_VERTEX* k_end = j->cloth_work.vtxarg.data() + j->cloth_work.vtxarg.size(); size_t l = 0; - for (CLOTHNode* k = k_begin; k != k_end; k++, l++) { + for (CLOTH_VERTEX* k = k_begin; k != k_end; k++, l++) { opd_node_data.data()[l].x.resize(frame_count); opd_node_data.data()[l].y.resize(frame_count); opd_node_data.data()[l].z.resize(frame_count); @@ -17704,7 +17755,7 @@ void OsagePlayDataManager::AppendCharaMotionId(rob_chara* rob_chr, const std::ve for (int32_t i = ITEM_KAMI; i < ITEM_ITEM16; i++) { rob_chara_item_equip_object* itm_eq_obj = rob_itm_equip->get_item_equip_object((item_id)i); if (!itm_eq_obj || itm_eq_obj->obj_info.is_null() - || (!itm_eq_obj->osage_blocks.size() && !itm_eq_obj->cloth_blocks.size())) + || (!itm_eq_obj->osage_blk.size() && !itm_eq_obj->cloth.size())) continue; for (const uint32_t j : motion_ids) @@ -18000,7 +18051,7 @@ rob_osage_mothead::rob_osage_mothead(rob_chara* rob_chr, int32_t stage_index, ui rob_chr->set_stage_data_ring(stage_index); rob_chr->reset_osage(); rob_chr->set_bone_data_frame(frame); - rob_chara_item_equip_ctrl_iterate_nodes(rob_chr->item_equip); + rob_chr->pos_reset(); init_data(mot_db); set_mothead_frame(); } @@ -18032,7 +18083,7 @@ rob_osage_mothead::rob_osage_mothead(rob_chara* rob_chr, int32_t stage_index, rob_chr->set_stage_data_ring(stage_index); rob_chr->reset_osage(); rob_chr->set_bone_data_frame(frame); - rob_chara_item_equip_ctrl_iterate_nodes(rob_chr->item_equip); + rob_chr->pos_reset(); init_data(mot_db); set_mothead_frame(); } @@ -18202,15 +18253,15 @@ void rob_osage_mothead::set_rob_adjust_global(const mothead_data* mhd_data) { v14.transition_duration = (float_t)((int32_t*)data)[0]; v14.type = type; v14.cycle_type = ((int8_t*)data)[5]; - v14.external_force.x = ((float_t*)data)[2]; - v14.external_force.y = ((float_t*)data)[3]; - v14.external_force.z = ((float_t*)data)[4]; - v14.external_force_cycle_strength.x = ((float_t*)data)[5]; - v14.external_force_cycle_strength.y = ((float_t*)data)[6]; - v14.external_force_cycle_strength.z = ((float_t*)data)[7]; - v14.external_force_cycle.x = ((float_t*)data)[8]; - v14.external_force_cycle.y = ((float_t*)data)[9]; - v14.external_force_cycle.z = ((float_t*)data)[10]; + v14.ex_force.x = ((float_t*)data)[2]; + v14.ex_force.y = ((float_t*)data)[3]; + v14.ex_force.z = ((float_t*)data)[4]; + v14.ex_force_cycle_strength.x = ((float_t*)data)[5]; + v14.ex_force_cycle_strength.y = ((float_t*)data)[6]; + v14.ex_force_cycle_strength.z = ((float_t*)data)[7]; + v14.ex_force_cycle.x = ((float_t*)data)[8]; + v14.ex_force_cycle.y = ((float_t*)data)[9]; + v14.ex_force_cycle.z = ((float_t*)data)[10]; v14.cycle = ((float_t*)data)[11]; v14.phase = ((float_t*)data)[12]; } @@ -18236,15 +18287,15 @@ void rob_osage_mothead::set_rob_parts_adjust(const mothead_data* mhd_data) { v16.type = type; v16.cycle_type = ((int8_t*)data)[7]; v16.ignore_gravity = !!((uint8_t*)data)[6]; - v16.external_force.x = ((float_t*)data)[2]; - v16.external_force.y = ((float_t*)data)[3]; - v16.external_force.z = ((float_t*)data)[4]; - v16.external_force_cycle_strength.x = ((float_t*)data)[5]; - v16.external_force_cycle_strength.y = ((float_t*)data)[6]; - v16.external_force_cycle_strength.z = ((float_t*)data)[7]; - v16.external_force_cycle.x = ((float_t*)data)[8]; - v16.external_force_cycle.y = ((float_t*)data)[9]; - v16.external_force_cycle.z = ((float_t*)data)[10]; + v16.ex_force.x = ((float_t*)data)[2]; + v16.ex_force.y = ((float_t*)data)[3]; + v16.ex_force.z = ((float_t*)data)[4]; + v16.ex_force_cycle_strength.x = ((float_t*)data)[5]; + v16.ex_force_cycle_strength.y = ((float_t*)data)[6]; + v16.ex_force_cycle_strength.z = ((float_t*)data)[7]; + v16.ex_force_cycle.x = ((float_t*)data)[8]; + v16.ex_force_cycle.y = ((float_t*)data)[9]; + v16.ex_force_cycle.z = ((float_t*)data)[10]; v16.cycle = ((float_t*)data)[11]; v16.force = ((float_t*)data)[13]; v16.phase = ((float_t*)data)[12]; @@ -18252,7 +18303,7 @@ void rob_osage_mothead::set_rob_parts_adjust(const mothead_data* mhd_data) { v16.strength_transition = (float_t)((int32_t*)data)[15]; } else - rob_chr->item_equip->reset_nodes_external_force((rob_osage_parts)((uint8_t*)data)[4]); + rob_chr->item_equip->reset_nodes_ex_force((rob_osage_parts)((uint8_t*)data)[4]); rob_chara_set_parts_adjust_by_index(rob_chr, (rob_osage_parts)((uint8_t*)data)[4], &v16); } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 242b5b3b..8df48615 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -19,13 +19,13 @@ #include "../object.hpp" #include "../static_var.hpp" -enum ex_expression_block_stack_type { - EX_EXPRESSION_BLOCK_STACK_NUMBER = 0x00, - EX_EXPRESSION_BLOCK_STACK_VARIABLE = 0x01, - EX_EXPRESSION_BLOCK_STACK_VARIABLE_RADIAN = 0x02, - EX_EXPRESSION_BLOCK_STACK_OP1 = 0x03, - EX_EXPRESSION_BLOCK_STACK_OP2 = 0x04, - EX_EXPRESSION_BLOCK_STACK_OP3 = 0x05, +enum Expr_type { + Expr_constant = 0x00, + Expr_variable = 0x01, + Expr_variable_rad = 0x02, + Expr_func1 = 0x03, + Expr_func2 = 0x04, + Expr_func3 = 0x05, }; enum eyes_base_adjust_type { @@ -822,11 +822,12 @@ enum rob_partial_motion_playback_state : uint32_t { }; enum ExNodeType { - EX_NONE = 0x00, - EX_OSAGE = 0x01, - EX_EXPRESSION = 0x02, - EX_CONSTRAINT = 0x03, - EX_CLOTH = 0x04, + EX_NODE_TYPE_NULL = 0x00, + EX_NODE_TYPE_OSAGE = 0x01, + EX_NODE_TYPE_EXPRESSION = 0x02, + EX_NODE_TYPE_CONSTRAINT = 0x03, + EX_NODE_TYPE_CLOTH = 0x04, + EX_NODE_TYPE_MAX = 0x05, }; enum SubActExecType { @@ -871,33 +872,35 @@ namespace SkinParam { struct rob_chara; struct rob_chara_bone_data; -struct bone_node_expression_data { - vec3 position; - vec3 rotation; +struct RobTransform { + vec3 pos; + vec3 rot; vec3 scale; - vec3 parent_scale; + vec3 hsc; - bone_node_expression_data(); + RobTransform(); - void mat_set(const vec3& parent_scale, mat4& ex_data_mat, mat4& mat); + void CalcMatrixHS(const vec3& hsc, mat4& mat, mat4& dsp_mat); + + void init(float_t px, float_t py, float_t pz, + float_t rx, float_t ry, float_t rz); + void init(const vec3& p, const vec3& r); + void reset(); void reset_scale(); - void set_position_rotation(float_t position_x, float_t position_y, float_t position_z, - float_t rotation_x, float_t rotation_y, float_t rotation_z); - void set_position_rotation(const vec3& position, const vec3& rotation); - }; struct bone_node { const char* name; - mat4* mat; - bone_node* parent; - bone_node_expression_data exp_data; - mat4* ex_data_mat; + mat4* mat_ptr; + const bone_node* parent; + RobTransform transform; + mat4* no_scale_mat; bone_node(); - float_t* get_exp_data_component(size_t index, ex_expression_block_stack_type& type); - void set_name_mat_ex_data_mat(const char* name, mat4* mat, mat4* ex_data_mat); + float_t* get_transform_component(size_t index, Expr_type& type); + const float_t* get_transform_component(size_t index, Expr_type& type) const; + void set_name_mat_no_scale_mat(const char* name, mat4* mat, mat4* no_scale_mat); }; struct struc_314 { @@ -987,7 +990,7 @@ struct bone_data { void copy_rot_trans(const bone_data& other); bool check_flags_not_null(); bool get_constraint_ik(const bone_data* bones); - bool get_ex_rotation(bone_node_expression_data& exp_data, const bone_data* bones); + bool get_ex_rotation(RobTransform& transform, const bone_data* bones); void get_mat(int32_t skeleton_select); void get_mat_ik(int32_t skeleton_select); void mult_mat(const mat4& parent_mat, const bone_data* bones, bool solve_ik); @@ -1549,15 +1552,22 @@ struct chara_init_data { struct rob_chara_item_equip_object; +struct RobSkinOfs { + bool flag; + RobTransform transform; + + RobSkinOfs(); +}; + class ExNodeBlock { public: - bone_node* bone_node_ptr; + bone_node* dst_node; ExNodeType type; const char* name; - bone_node* parent_bone_node; + const bone_node* parent; std::string parent_name; ExNodeBlock* parent_node; - rob_chara_item_equip_object* item_equip_object; + const rob_chara_item_equip_object* skin_disp; bool is_parent; bool done; bool has_children_node; @@ -1565,55 +1575,56 @@ public: ExNodeBlock(); virtual ~ExNodeBlock(); - virtual void Init() = 0; + virtual void init() = 0; virtual void CtrlBegin() = 0; - virtual void CtrlStep(int32_t stage, bool disable_external_force) = 0; - virtual void CtrlMain() = 0; + virtual void CtrlStep(int32_t stage, bool disable_ex_force) = 0; + virtual void ctrl() = 0; virtual void CtrlOsagePlayData() = 0; - virtual void Disp(const mat4& mat, render_context* rctx) = 0; - virtual void Reset(); - virtual void Field_40() = 0; - virtual void CtrlInitBegin() = 0; - virtual void CtrlInitMain() = 0; + virtual void disp(const mat4& mat, render_context* rctx) = 0; + virtual void dest(); + virtual void disp_debug() = 0; + virtual void pos_init() = 0; + virtual void pos_init_cont() = 0; virtual void CtrlEnd(); - void InitData(bone_node* bone_node, ExNodeType type, - const char* name, rob_chara_item_equip_object* itm_eq_obj); + void init_members(); + void set_data(bone_node* node, ExNodeType type, + const char* name, const rob_chara_item_equip_object* skin_disp); }; class ExNullBlock : public ExNodeBlock { public: - obj_skin_block_constraint* cns_data; + const obj_skin_ex_node_constraint* data; ExNullBlock(); virtual ~ExNullBlock() override; - virtual void Init() override; - virtual void CtrlBegin(); - virtual void CtrlStep(int32_t stage, bool disable_external_force) override; - virtual void CtrlMain() override; + virtual void init() override; + virtual void CtrlBegin() override; + virtual void CtrlStep(int32_t stage, bool disable_ex_force) override; + virtual void ctrl() override; virtual void CtrlOsagePlayData() override; - virtual void Disp(const mat4& mat, render_context* rctx) override; - virtual void Field_40() override; - virtual void CtrlInitBegin() override; - virtual void CtrlInitMain() override; + virtual void disp(const mat4& mat, render_context* rctx) override; + virtual void disp_debug() override; + virtual void pos_init() override; + virtual void pos_init_cont() override; - void InitData(rob_chara_item_equip_object* itm_eq_obj, obj_skin_block_constraint* cns_data, - const char* cns_data_name, const bone_database* bone_data); + void set_data(const rob_chara_item_equip_object* skin_disp, const obj_skin_ex_node_constraint* data, + const char* name, const bone_database* bone_data); }; -struct RobOsageNode; +struct RobJointNode; -struct RobOsageNodeDataNormalRef { +struct RobJointNodeDataNormalRef { bool set; - RobOsageNode* n; - RobOsageNode* u; - RobOsageNode* d; - RobOsageNode* l; - RobOsageNode* r; + RobJointNode* n; + RobJointNode* u; + RobJointNode* d; + RobJointNode* l; + RobJointNode* r; mat4 mat; - RobOsageNodeDataNormalRef(); + RobJointNodeDataNormalRef(); bool Check(); void GetMat(mat4* mat); @@ -1649,29 +1660,30 @@ struct skin_param_osage_node { skin_param_osage_node(); }; -struct RobOsageNodeResetData { +struct RobJointNodeResetData { vec3 pos; - vec3 delta_pos; + vec3 vec; vec3 rotation; float_t length; - RobOsageNodeResetData(); + RobJointNodeResetData(); }; struct skin_param_osage_root; -struct RobOsageNodeData { +struct RobJointNodeData { float_t force; - std::vector boc; - RobOsageNodeDataNormalRef normal_ref; + std::vector boc; + RobJointNodeDataNormalRef normal_ref; skin_param_osage_node skp_osg_node; - RobOsageNodeData(); - ~RobOsageNodeData(); + RobJointNodeData(); + ~RobJointNodeData(); - void Reset(); void SetForce(const skin_param_osage_root& skp_root, skin_param_osage_node* skp_osg_node, size_t index); + + void reset(); }; struct opd_blend_data { @@ -1708,58 +1720,59 @@ struct opd_node_data_pair { opd_node_data_pair(); - void set_data(opd_blend_data* blend_data, const opd_node_data& node_data); + void set_data(const opd_blend_data* blend_data, const opd_node_data& node_data); }; -struct RobOsageNode { - float_t length; +struct RobJointNode { + float_t length_back; vec3 pos; - vec3 fixed_pos; - vec3 delta_pos; + vec3 old_pos; + vec3 vec; vec3 vel; - float_t child_length; - bone_node* bone_node_ptr; - mat4* bone_node_mat; + float_t length_next; + bone_node* dst_node; + mat4* dst_node_mat; mat4 mat; - RobOsageNode* sibling_node; - float_t max_distance; + RobJointNode* distance; + float_t length_dist; vec3 rel_pos; - RobOsageNodeResetData reset_data; + RobJointNodeResetData reset_data; float_t hit; float_t friction; - vec3 external_force; + vec3 ex_force; float_t force; - RobOsageNodeData* data_ptr; - RobOsageNodeData data; + RobJointNodeData* data_ptr; + RobJointNodeData data; std::vector opd_data; opd_node_data_pair opd_node_data; - RobOsageNode(); - ~RobOsageNode(); + RobJointNode(); + ~RobJointNode(); void CheckFloorCollision(const float_t& floor_height); - void CheckNodeDistance(const float_t& step, const float_t& parent_scale); - void Reset(); + void CheckNodeDistance(const float_t& step, const float_t& hsc); - inline RobOsageNode& GetNextNode() { + void reset(); + + inline RobJointNode& GetNextNode() { return *(this + 1); } - inline const RobOsageNode& GetNextNode() const { + inline const RobJointNode& GetNextNode() const { return *(this + 1); } - inline RobOsageNode& GetPrevNode() { + inline RobJointNode& GetPrevNode() { return *(this - 1); } - inline const RobOsageNode& GetPrevNode() const { + inline const RobJointNode& GetPrevNode() const { return *(this - 1); } - inline float_t TranslateMat(mat4& mat, const bool rot_clamped, const float_t parent_scale_x) { + inline float_t TranslateMat(mat4& mat, const bool rot_clamped, const float_t hsc_x) { const float_t dist = vec3::distance_squared(pos, GetPrevNode().pos); - const float_t len = length * parent_scale_x; + const float_t len = length_back * hsc_x; float_t length; bool length_clamped; @@ -1826,7 +1839,7 @@ struct skin_param_osage_root { float_t coli_r; float_t friction; float_t wind_afc; - int32_t yz_order; + ROTTYPE rottype; std::vector boc; SkinParam::RootCollisionType coli_type; float_t stiffness; @@ -1852,7 +1865,7 @@ struct skin_param { skin_param_hinge hinge; float_t force; float_t force_gain; - std::vector* colli_tgt_osg; + std::vector* colli_tgt_osg; skin_param(); ~skin_param(); @@ -1890,10 +1903,10 @@ struct OsageCollision { Work(); - static void update_cls_work(OsageCollision::Work* cls, - SkinParam::CollisionParam* cls_param, const mat4* tranform); - static void update_cls_work(OsageCollision::Work* cls, - std::vector& cls_list, const mat4* tranform); + static void update_cls_work(OsageCollision::Work* work, + const SkinParam::CollisionParam* cls, const mat4* motmat); + static void update_cls_work(OsageCollision::Work* work, + const std::vector& cls_list, const mat4* motmat); }; std::vector work_list; @@ -1944,183 +1957,185 @@ struct osage_ring_data { struct skin_param_file_data; -struct CLOTHNode { - uint32_t flags; +struct CLOTH_VERTEX { + uint32_t flag; vec3 pos; - vec3 fixed_pos; - vec3 prev_pos; - vec3 delta_pos; + vec3 org_pos; + vec3 old_pos; + vec3 vec; vec3 normal; vec3 tangent; vec3 binormal; - float_t tangent_sign; - vec2 texcoord; - vec3 direction; - float_t dist_top; - float_t dist_bottom; - float_t dist_right; - float_t dist_left; - vec3 field_80; - RobOsageNodeResetData reset_data; + float_t m; + vec2 uv; + vec3 localvec; + float_t length_up; + float_t length_down; + float_t length_left; + float_t length_right; + vec3 F; + RobJointNodeResetData reset_data; std::vector opd_data; opd_node_data_pair opd_node_data; - CLOTHNode(); - ~CLOTHNode(); - - void CalculateTBN(const CLOTHNode* right, const CLOTHNode* left, - const CLOTHNode* top, const CLOTHNode* bottom); + CLOTH_VERTEX(); + ~CLOTH_VERTEX(); }; -struct CLOTHLine { - size_t idx[2]; +struct CLOTH_FLAG { + uint32_t exec : 1; + uint32_t disp : 1; + uint32_t ring : 1; +}; + +struct CLOTH_SPRING { + size_t index0; + size_t index1; float_t length; }; struct CLOTH { - int32_t flags; - size_t root_count; - size_t nodes_count; - std::vector nodes; - vec3 wind_direction; - float_t inertia; - bool set_external_force; - vec3 external_force; - std::vector lines; + CLOTH_FLAG flag; + size_t width; + size_t height; + std::vector vtxarg; + vec3 wind_dir; + float_t wet; + bool use_ex_force; + vec3 ex_force; + std::vector spring; skin_param* skin_param_ptr; skin_param skin_param; OsageCollision::Work coli_chara[64]; OsageCollision::Work coli_ring[64]; osage_ring_data ring; - mat4* mats; CLOTH(); + virtual void set_spring(); virtual ~CLOTH(); - virtual void Init(); - virtual void SetSkinParamColiR(float_t value); - virtual void SetSkinParamFriction(float_t value); - virtual void SetSkinParamWindAfc(float_t value); - virtual void SetWindDirection(const vec3& value); - virtual void SetInertia(float_t value); - virtual void SetSkinParamHinge(float_t hinge_y, float_t hinge_z); - virtual CLOTHNode* GetNodes(); - virtual void Reset(); - virtual void ResetData(); + virtual void set_coli_r(float_t value); + virtual void set_friction(float_t value); + virtual void set_wind_affect(float_t value); + virtual void set_wind_dir(const vec3& value); + virtual void set_wetness(float_t value); + virtual void set_angle_limit(float_t y, float_t z); + virtual CLOTH_VERTEX* get_vertex(); + virtual void init(); + virtual void disp_debug(); + virtual void dest(); }; -struct RobClothRoot { +struct CLOTH_WEIGHTED_ROOT { vec3 pos; vec3 normal; vec4 tangent; - bone_node* node[4]; - mat4* node_mat[4]; - mat4* bone_mat[4]; + const bone_node* node[4]; + const mat4* node_mat[4]; + const mat4* bone_mat[4]; float_t weight[4]; mat4 mat; mat4 mat_pos; mat4 inv_mat_pos; }; -struct RobClothSubMeshArray { - obj_sub_mesh arr[4]; - - RobClothSubMeshArray(); -}; - struct RobCloth : public CLOTH { - std::vector root; - rob_chara_item_equip_object* itm_eq_obj; - obj_skin_block_cloth_root* cls_root; - obj_skin_block_cloth* cls_data; + const mat4* local_mat; + std::vector root; + const rob_chara_item_equip_object* skin_disp; + const obj_skin_ex_node_cloth_root* root_data; + const obj_skin_ex_node_cloth* data; float_t move_cancel; bool osage_reset; obj_mesh mesh[2]; - RobClothSubMeshArray submesh[2]; - obj_mesh_vertex_buffer vertex_buffer[2]; - obj_mesh_index_buffer index_buffer[2]; - std::map, std::list> motion_reset_data; - std::list* reset_data_list; + obj_sub_mesh submesh[2][4]; + obj_mesh_vertex_buffer vb[2]; + obj_mesh_index_buffer ib[2]; + std::map, std::list> motion_reset_data; + std::list* reset_data_list; RobCloth(); virtual ~RobCloth() override; - virtual void ResetData() override; + virtual void disp_debug() override; + virtual void dest() override; void AddMotionResetData(uint32_t motion_id, float_t frame); - void ApplyPhysics(bool ignore_friction); void ApplyResetData(); - void ColiSet(const mat4* mats); - void CollideNodes(const float_t step, bool a3); - void CtrlInitBegin(); - void CtrlInitMain(); - void CtrlMain(const float_t step, bool ignore_friction); - void CtrlOsagePlayData(std::vector& opd_blend_data); - void CtrlStep(const float_t step); - void Disp(const mat4& mat, render_context* rctx); - void GetRootData(); - void InitData(size_t root_count, size_t nodes_count, obj_skin_block_cloth_root* root, - obj_skin_block_cloth_node* nodes, mat4* mats, int32_t loop, - rob_chara_item_equip_object* itm_eq_obj, const bone_database* bone_data); - void InitDataParent(obj_skin_block_cloth* cls_data, - rob_chara_item_equip_object* itm_eq_obj, const bone_database* bone_data); + void CtrlOsagePlayData(const std::vector& opd_blend_data); const float_t* LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count); void LoadSkinParam(void* kv, const char* name, const bone_database* bone_data); - void NodesLimitDistance(); - void ResetExtrenalForce(); - void SetForceAirRes(float_t force, float_t force_gain, float_t air_res); void SetMotionResetData(uint32_t motion_id, float_t frame); - void SetMoveCancel(const float_t& value); const float_t* SetOsagePlayDataInit(const float_t* opdi_data); void SetOsageReset(); void SetRing(const osage_ring_data& ring); void SetSkinParam(skin_param_file_data* skp); void SetSkinParamOsageRoot(const skin_param_osage_root& skp_root); - void UpdateDisp(); - void UpdateNormals(); - static void UpdateVertexBuffer(obj_mesh* mesh, obj_mesh_vertex_buffer* vertex_buffer, - CLOTHNode* node, float_t facing, int32_t indices_count, uint16_t* indices, bool double_faced); + void calc(const float_t dt); + void calc_force(float_t time, bool init_flag); + void calc_normal(); + void calc_root(); + void calc_stretch(); + void calc_velocity(const float_t dt, bool a3); + void ctrl(const float_t dt, bool init_flag); + void disp(const mat4& mat, render_context* rctx); + void make_osage_coli(const mat4* motmat); + void modify_obj(); + void pos_init(); + void pos_init_cont(); + void reset_ex_force(); + void set_data(size_t w, size_t h, const obj_skin_ex_node_cloth_root* rt_data, + const obj_skin_ex_node_cloth_point* move, const mat4* lcl_mat, uint32_t ring_flag, + const rob_chara_item_equip_object* skin, const bone_database* bone_data); + void set_data(const obj_skin_ex_node_cloth* cldata, + const rob_chara_item_equip_object* skin, const bone_database* bone_data); + void set_ex_force(const vec3& f); + void set_move_cancel(const float_t& mv_ccl); + void set_param(float_t force, float_t force_gain, float_t air_res); }; class ExClothBlock : public ExNodeBlock { public: - RobCloth rob; - obj_skin_block_cloth* cls_data; - mat4* mats; - size_t index; + RobCloth cloth_work; + const obj_skin_ex_node_cloth* data; + const mat4* motion_matrix; + size_t block_idx; ExClothBlock(); virtual ~ExClothBlock() override; - virtual void Init() override; - virtual void CtrlBegin(); - virtual void CtrlStep(int32_t stage, bool disable_external_force) override; - virtual void CtrlMain() override; + virtual void init() override; + virtual void CtrlBegin() override; + virtual void CtrlStep(int32_t stage, bool disable_ex_force) override; + virtual void ctrl() override; virtual void CtrlOsagePlayData() override; - virtual void Disp(const mat4& mat, render_context* rctx) override; - virtual void Reset() override; - virtual void Field_40() override; - virtual void CtrlInitBegin() override; - virtual void CtrlInitMain() override; + virtual void disp(const mat4& mat, render_context* rctx) override; + virtual void dest() override; + virtual void disp_debug() override; + virtual void pos_init() override; + virtual void pos_init_cont() override; void AddMotionResetData(uint32_t motion_id, float_t frame); - void ColiSet(); - void InitData(rob_chara_item_equip_object* itm_eq_obj, obj_skin_block_cloth* cls_data, - skin_param_osage_root* skp_root, const bone_database* bone_data); const float_t* LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count); void SetMotionResetData(uint32_t motion_id, float_t frame); - void SetMoveCancel(const float_t& value); const float_t* SetOsagePlayDataInit(const float_t* opdi_data); void SetOsageReset(); void SetRing(const osage_ring_data& ring); void SetSkinParam(skin_param_file_data* skp); void SetSkinParamOsageRoot(const skin_param_osage_root* skp_root); + + void reset_ex_force(); + void set_data(const rob_chara_item_equip_object* skin_disp, const obj_skin_ex_node_cloth* cls_data, + const skin_param_osage_root* skp_root, const bone_database* bone_data); + void set_ex_force(const vec3& f); + void set_move_cancel(const float_t& mv_ccl); + void set_param(); }; struct skin_param_file_data { skin_param skin_param; - std::vector nodes_data; + std::vector nodes_data; bool depends_on_others; skin_param_file_data(); @@ -2136,9 +2151,9 @@ struct osage_setting_osg_cat { struct RobOsage { skin_param* skin_param_ptr; - bone_node_expression_data exp_data; - std::vector nodes; - RobOsageNode end_node; + RobTransform transform; + std::vector joint_node_vec; + RobJointNode effector; skin_param skin_param; osage_setting_osg_cat osage_setting; bool apply_physics; @@ -2146,9 +2161,9 @@ struct RobOsage { float_t field_2A4; OsageCollision::Work coli_chara[64]; OsageCollision::Work coli_ring[64]; - vec3 wind_direction; - float_t inertia; - int32_t yz_order; + vec3 wind_dir; + float_t wet; + ROTTYPE rottype; mat4* root_matrix_ptr; mat4 root_matrix_prev; float_t move_cancel; @@ -2157,247 +2172,232 @@ struct RobOsage { bool osage_reset_done; bool disable_collision; osage_ring_data ring; - std::map, std::list> motion_reset_data; - std::list* reset_data_list; - bool set_external_force; - vec3 external_force; + std::map, std::list> motion_reset_data; + std::list* reset_data_list; + bool use_ex_force; + vec3 ex_force; RobOsage(); ~RobOsage(); void AddMotionResetData(uint32_t motion_id, float_t frame); void ApplyBocRootColi(const float_t step); - void ApplyPhysics(const mat4& root_matrix, const vec3& parent_scale, - const float_t step, bool disable_external_force, bool ring_coli, bool has_children_node); + void ApplyPhysics(const mat4& root_matrix, const vec3& hsc, + const float_t step, bool disable_ex_force, bool ring_coli, bool has_children_node); void ApplyResetData(const mat4& mat); - void BeginCalc(const mat4& root_matrix, const vec3& parent_scale, bool has_children_node); + void BeginCalc(const mat4& root_matrix, const vec3& hsc, bool has_children_node); bool CheckPartsBits(const rob_osage_parts_bit& parts_bits); - void ColiSet(const mat4* mats); void CollideNodes(const float_t step); void CollideNodesTargetOsage(const mat4& root_matrix, - const vec3& parent_scale, const float_t step, bool collide_nodes); - void CtrlEnd(const vec3& parent_scale); - void CtrlInitBegin(const mat4& root_matrix, const vec3& parent_scale, bool sibling_node); - void CtrlInitMain(const mat4& root_matrix, const vec3& parent_scale, - const float_t step, bool disable_external_force); - void CtrlMain(const mat4& root_matrix, const vec3& parent_scale, const float_t step); + const vec3& hsc, const float_t step, bool collide_nodes); + void CtrlEnd(const vec3& hsc); void CtrlOsagePlayData(const mat4& root_matrix, - const vec3& parent_scale, std::vector& opd_blend_data); - void EndCalc(const mat4& root_matrix, const vec3& parent_scale, - const float_t step, bool disable_external_force); - RobOsageNode* GetNode(size_t index); - void InitData(obj_skin_block_osage* osg_data, obj_skin_osage_node* osg_nodes, - bone_node* ex_data_bone_nodes, obj_skin* skin); + const vec3& hsc, const std::vector& opd_blend_data); + void EndCalc(const mat4& root_matrix, const vec3& hsc, + const float_t step, bool disable_ex_force); const float_t* LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count); void LoadSkinParam(void* kv, const char* name, skin_param_osage_root& skp_root, object_info* obj_info, const bone_database* bone_data); - void Reset(); - void ResetBoc(); - void ResetExtrenalForce(); - void RotateMat(mat4& mat, const vec3& parent_scale, bool init_rot = false); - void SetAirRes(float_t air_res); - void SetColiR(float_t coli_r); + void RotateMat(mat4& mat, const vec3& hsc, bool init_rot = false); void SetDisableCollision(const bool& value); - void SetForce(float_t force, float_t force_gain); - void SetHinge(float_t hinge_y, float_t hinge_z); - void SetInitRot(float_t init_rot_y, float_t init_rot_z); void SetMotionResetData(uint32_t motion_id, float_t frame); - void SetMoveCancel(const float_t& value); - void SetNodesExternalForce(const vec3* external_force, const float_t& strength); + void SetNodesExternalForce(const vec3* ex_force, const float_t& gain); void SetNodesForce(const float_t& force); const float_t* SetOsagePlayDataInit(const float_t* opdi_data); void SetOsageReset(); void SetRing(const osage_ring_data& ring); - void SetRot(float_t rot_y, float_t rot_z); void SetSkinParam(skin_param_file_data* skp); void SetSkinParamOsageRoot(const skin_param_osage_root& skp_root); - void SetSkpOsgNodes(std::vector* skp_osg_nodes); + void SetSkpOsgNodes(const std::vector* skp_osg_nodes); void SetWindDirection(const vec3* value); - void SetYZOrder(int32_t yz_order); + + void ctrl(const mat4& root_matrix, const vec3& hsc, const float_t step); + void dest(); + void dest_boc(); + RobJointNode* get_joint_node(size_t index); + void init(const obj_skin_ex_node_osage* osg_data, const obj_skin_osage_joint* joint, + bone_node* ex_node, const obj_skin* skin); + void make_osage_coli(const mat4* motmat); + void pos_init(const mat4& root_matrix, const vec3& hsc, bool dist_flag); + void pos_init_cont(const mat4& root_matrix, const vec3& hsc, + const float_t step, bool disable_ex_force); + void reset_ex_force(); + void set_air_res(float_t air); + void set_angle(float_t angle_y, float_t angle_z); + void set_coli_r(float_t coli_r); + void set_ex_force(const vec3& f); + void set_force(float_t force, float_t gain); + void set_init_angle(float_t angle_y, float_t angle_z); + void set_limit_angle(float_t angle_y, float_t angle_z); + void set_move_cancel(const float_t& mv_ccl); + void set_rot_type(ROTTYPE rot_type); +}; + +struct ExOsageBlockFlag { + uint32_t alive : 1; + uint32_t pos_init : 1; }; class ExOsageBlock : public ExNodeBlock { public: - size_t index; - RobOsage rob; - mat4* mats; - int32_t field_1FF8; - float_t step; + size_t block_idx; + RobOsage osage_work; + const mat4* motion_matrix; + ExOsageBlockFlag flag; + float_t init_coma_step; ExOsageBlock(); virtual ~ExOsageBlock() override; - virtual void Init() override; - virtual void CtrlBegin(); - virtual void CtrlStep(int32_t stage, bool disable_external_force) override; - virtual void CtrlMain() override; + virtual void init() override; + virtual void CtrlBegin() override; + virtual void CtrlStep(int32_t stage, bool disable_ex_force) override; + virtual void ctrl() override; virtual void CtrlOsagePlayData() override; - virtual void Disp(const mat4& mat, render_context* rctx) override; - virtual void Reset() override; - virtual void Field_40() override; - virtual void CtrlInitBegin() override; - virtual void CtrlInitMain() override; + virtual void disp(const mat4& mat, render_context* rctx) override; + virtual void dest() override; + virtual void disp_debug() override; + virtual void pos_init() override; + virtual void pos_init_cont() override; virtual void CtrlEnd() override; void AddMotionResetData(uint32_t motion_id, float_t frame); - void GetNodeList(obj_skin_block_osage* osg_data, obj_skin_osage_node* osg_nodes, - prj::vector_pair& osage_node_list, - std::map& node_list); - void InitData(rob_chara_item_equip_object* itm_eq_obj, obj_skin_block_osage* osg_data, - const char* osg_data_name, obj_skin_osage_node* osg_nodes, bone_node* bone_nodes, - bone_node* ex_data_bone_nodes, obj_skin* skin); const float_t* LoadOpdData(size_t node_index, const float_t* opd_data, size_t opd_count); void SetDisableCollision(const bool& value); void SetMotionResetData(uint32_t motion_id, float_t frame); - void SetMoveCancel(const float_t& value); const float_t* SetOsagePlayDataInit(const float_t* opdi_data); void SetOsageReset(); void SetRing(const osage_ring_data& ring); void SetSkinParam(skin_param_file_data* skp); void SetWindDirection(); + + void get_node_list( + const obj_skin_ex_node_osage* osg_data, const obj_skin_osage_joint* joint, + prj::vector_pair& joint_node_list, + std::map& ex_node_list); + void reset_ex_force(); + void set_data(const rob_chara_item_equip_object* skin_disp, const obj_skin_ex_node_osage* root, + const char* name, const obj_skin_osage_joint* joint, const bone_node* mot_node, + bone_node* ex_node, const obj_skin* skin); + void set_ex_force(const vec3& f); + void set_move_cancel(const float_t& mv_ccl); }; class ExConstraintBlock : public ExNodeBlock { public: - obj_skin_block_constraint_type constraint_type; - bone_node* source_node_ref; - bone_node* up_vector_ref; - obj_skin_block_constraint* cns_data; - int64_t field_80; + obj_skin_ex_node_constraint_type cns_type; + const bone_node* src_node; + const bone_node* upvector_node; + const obj_skin_ex_node_constraint* data; + uint32_t dst_node_id; + uint32_t src_node_id; ExConstraintBlock(); virtual ~ExConstraintBlock() override; - virtual void Init() override; + virtual void init() override; virtual void CtrlBegin() override; - virtual void CtrlStep(int32_t stage, bool disable_external_force) override; - virtual void CtrlMain() override; + virtual void CtrlStep(int32_t stage, bool disable_ex_force) override; + virtual void ctrl() override; virtual void CtrlOsagePlayData() override; - virtual void Disp(const mat4& mat, render_context* rctx) override; - virtual void Field_40() override; - virtual void CtrlInitBegin() override; - virtual void CtrlInitMain() override; + virtual void disp(const mat4& mat, render_context* rctx) override; + virtual void disp_debug() override; + virtual void pos_init() override; + virtual void pos_init_cont() override; void Calc(); void CalcConstraintDirection(mat4 mat); void CalcConstraintDistance(mat4 mat); void CalcConstraintOrientation(mat4 mat); void CalcConstraintPosition(mat4 mat); - void DataSet(); - void InitData(rob_chara_item_equip_object* itm_eq_obj, obj_skin_block_constraint* cns_data, - const char* cns_data_name, const bone_database* bone_data); + void CalcMatrixHS(); + + void set_data(const rob_chara_item_equip_object* skin_disp, const obj_skin_ex_node_constraint* data, + const char* name, const bone_database* bone_data); }; -struct ex_expression_block_stack; - -struct ex_expression_block_stack_number { - float_t value; +union Expr_value { + float_t constant; + const float* variable; + float_t(*func1)(float_t); + float_t(*func2)(float_t, float_t); + float_t(*func3)(float_t, float_t, float_t); }; -struct ex_expression_block_stack_variable { - float_t* value; -}; +struct Expr_node { + Expr_type type; + Expr_value data; + Expr_node* operand[3]; -struct ex_expression_block_stack_variable_radian { - float_t* value; -}; - -struct ex_expression_block_stack_op1 { - float_t(*func)(float_t v1); - ex_expression_block_stack* v1; -}; - -struct ex_expression_block_stack_op2 { - float_t(*func)(float_t v1, float_t v2); - ex_expression_block_stack* v1; - ex_expression_block_stack* v2; -}; - -struct ex_expression_block_stack_op3 { - float_t(*func)(float_t v1, float_t v2, float_t v3); - ex_expression_block_stack* v1; - ex_expression_block_stack* v2; - ex_expression_block_stack* v3; -}; - -struct ex_expression_block_stack { - ex_expression_block_stack_type type; - union { - ex_expression_block_stack_number number; - ex_expression_block_stack_variable var; - ex_expression_block_stack_variable_radian var_rad; - ex_expression_block_stack_op1 op1; - ex_expression_block_stack_op2 op2; - ex_expression_block_stack_op3 op3; - }; + float_t eval(); }; class ExExpressionBlock : public ExNodeBlock { public: - float_t* values[9]; - ex_expression_block_stack_type types[9]; - ex_expression_block_stack* expressions[9]; - ex_expression_block_stack stack_data[384]; - obj_skin_block_expression* exp_data; + float_t* result[9]; + Expr_type result_type[9]; + Expr_node* expr_node[9]; + Expr_node expr_work[384]; + const obj_skin_ex_node_expression* data; bool field_3D20; - void(*field_3D28)(bone_node_expression_data*); - float_t frame; + void(*hard_coded_func)(RobTransform*); + float_t timer; bool step; ExExpressionBlock(); virtual ~ExExpressionBlock() override; - virtual void Init() override; + virtual void init() override; virtual void CtrlBegin() override; - virtual void CtrlStep(int32_t stage, bool disable_external_force) override; - virtual void CtrlMain() override; + virtual void CtrlStep(int32_t stage, bool disable_ex_force) override; + virtual void ctrl() override; virtual void CtrlOsagePlayData() override; - virtual void Disp(const mat4& mat, render_context* rctx) override; - virtual void Field_40() override; - virtual void CtrlInitBegin() override; - virtual void CtrlInitMain() override; + virtual void disp(const mat4& mat, render_context* rctx) override; + virtual void disp_debug() override; + virtual void pos_init() override; + virtual void pos_init_cont() override; void Calc(); - void DataSet(); - void InitData(rob_chara_item_equip_object* itm_eq_obj, obj_skin_block_expression* exp_data, - const char* exp_data_name, object_info a4, size_t index, const bone_database* bone_data); + void CalcMatrixHS(); + + void set_data(const rob_chara_item_equip_object* skin_disp, const obj_skin_ex_node_expression* data, + const char* node_name, object_info a4, size_t index, const bone_database* bone_data); }; struct rob_chara_item_equip; struct rob_chara_item_equip_object { size_t index; - mat4* mats; + const mat4* motion_matrix; object_info obj_info; - int32_t field_14; - std::vector texture_pattern; - texture_data_struct texture_data; - bool null_blocks_data_set; - bone_node_expression_data exp_data; + object_info obj_uid_sub; + std::vector texchg_vec; + RobSkinCol skn_col; + RobSkinOfs skn_ofs; float_t alpha; mdl::ObjFlags obj_flags; bool can_disp; - int32_t field_A4; + uint32_t bone_kind; mat4* mat; - int32_t init_iterations; - bone_node* bone_nodes; - std::vector node_blocks; - std::vector ex_data_bone_nodes; - std::vector ex_data_bone_mats; - std::vector ex_data_mats; - prj::vector_pair ex_bones; + int32_t init_cnt; + const bone_node* motion_node; + std::vector ex_node_block; + std::vector ex_node; + std::vector matrix; + std::vector no_scale_matrix; + prj::vector_pair node_name_map; int64_t field_138; - std::vector null_blocks; - std::vector osage_blocks; - std::vector constraint_blocks; - std::vector expression_blocks; - std::vector cloth_blocks; + std::vector null_blk; + std::vector osage_blk; + std::vector constraint; + std::vector expression; + std::vector cloth; bool osage_depends_on_others; size_t osage_nodes_count; bool use_opd; - obj_skin_ex_data* skin_ex_data; - obj_skin* skin; - rob_chara_item_equip* item_equip; + const obj_skin_ex_data* skin_ex_data; + const obj_skin* skin; + const rob_chara_item_equip* rob_disp; rob_chara_item_equip_object(); ~rob_chara_item_equip_object(); @@ -2406,20 +2406,21 @@ struct rob_chara_item_equip_object { void check_no_opd(std::vector& opd_blend_data); void clear_ex_data(); void disp(const mat4& mat, render_context* rctx); - int32_t get_bone_index(const char* name, const bone_database* bone_data); - bone_node* get_bone_node(int32_t bone_index); - bone_node* get_bone_node(const char* name, const bone_database* bone_data); + const bone_node* get_node(int32_t bone_index) const; + const bone_node* get_node(const char* name, const bone_database* bone_data) const; + int32_t get_node_index(const char* name, const bone_database* bone_data) const; const mat4* get_ex_data_bone_node_mat(const char* name); - RobOsageNode* get_normal_ref_osage_node(const std::string& str, size_t* index); + RobJointNode* get_normal_ref_osage_node(const std::string& str, size_t* index); void get_parent_bone_nodes(bone_node* bone_nodes, const bone_database* bone_data); void init_ex_data_bone_nodes(obj_skin_ex_data* ex_data); void init_members(size_t index = 0xDEADBEEF); void load_ex_data(obj_skin_ex_data* ex_data, const bone_database* bone_data, void* data, const object_database* obj_db); - void load_object_info_ex_data(object_info object_info, bone_node* bone_nodes, + void load_object_info_ex_data(object_info object_info, const bone_node* motion_node, bool osage_reset, const bone_database* bone_data, void* data, const object_database* obj_db); - void reset_external_force(); - void reset_nodes_external_force(rob_osage_parts_bit parts_bits); + void pos_reset(int32_t init_cnt); + void reset_ex_force(); + void reset_nodes_ex_force(rob_osage_parts_bit parts_bits); void set_alpha_obj_flags(float_t alpha, int32_t flags); bool set_boc(const skin_param_osage_root& skp_root, ExOsageBlock* osg); void set_collision_target_osage(const skin_param_osage_root& skp_root, skin_param* skp); @@ -2429,14 +2430,14 @@ struct rob_chara_item_equip_object { void set_null_blocks_expression_data(const vec3& position, const vec3& rotation, const vec3& scale); void set_osage_play_data_init(const float_t* opdi_data); void set_osage_reset(); - void set_osage_move_cancel(const float_t& value); + void set_osage_move_cancel(const float_t& mv_ccl); void set_texture_pattern(texture_pattern_struct* tex_pat, size_t count); void skp_load(void* kv, const bone_database* bone_data); void skp_load(const skin_param_osage_root& skp_root, std::vector& vec, skin_param_file_data* skp_file_data, const bone_database* bone_data); - bool skp_load_boc(const skin_param_osage_root& skp_root, std::vector* node_data); + bool skp_load_boc(const skin_param_osage_root& skp_root, std::vector* node_data); void skp_load_file(void* data, const bone_database* bone_data, const object_database* obj_db); - bool skp_load_normal_ref(const skin_param_osage_root& skp_root, std::vector* node_data); + bool skp_load_normal_ref(const skin_param_osage_root& skp_root, std::vector* node_data); }; struct rob_chara_item_equip { @@ -2508,10 +2509,11 @@ struct rob_chara_item_equip { bool osage_reset, const bone_database* bone_data, void* data, const object_database* obj_db); void load_outfit_object_info(item_id id, object_info obj_info, bool osage_reset, const bone_database* bone_data, void* data, const object_database* obj_db); + void pos_reset(uint8_t init_cnt); void reset(); - void reset_external_force(); + void reset_ex_force(); void reset_init_data(bone_node* bone_nodes); - void reset_nodes_external_force(rob_osage_parts parts); + void reset_nodes_ex_force(rob_osage_parts parts); void set_alpha_obj_flags(float_t alpha, mdl::ObjFlags flags); void set_disable_collision(rob_osage_parts parts, bool disable); void set_disp(item_id id, bool value); @@ -2525,7 +2527,7 @@ struct rob_chara_item_equip { void set_osage_play_data_init(item_id id, const float_t* opdi_data); void set_osage_reset(); void set_osage_step(float_t value); - void set_osage_move_cancel(uint8_t id, const float_t& value); + void set_osage_move_cancel(uint8_t id, const float_t& mv_ccl); void set_shadow_type(int32_t chara_id); void set_texture_pattern(texture_pattern_struct* tex_pat, size_t count); void skp_load(item_id id, const skin_param_osage_root& skp_root, std::vector& vec, @@ -3021,7 +3023,7 @@ struct rob_chara_data_adjust { bool enable; float_t frame; float_t transition_frame; - vec3 curr_external_force; + vec3 curr_ex_force; float_t curr_force; float_t curr_strength; uint32_t motion_id; @@ -3030,9 +3032,9 @@ struct rob_chara_data_adjust { int32_t type; int32_t cycle_type; bool ignore_gravity; - vec3 external_force; - vec3 external_force_cycle_strength; - vec3 external_force_cycle; + vec3 ex_force; + vec3 ex_force_cycle_strength; + vec3 ex_force_cycle; float_t cycle; float_t phase; float_t force; @@ -3680,6 +3682,7 @@ struct rob_chara { MotionBlendType blend_type, const bone_database* bone_data, const motion_database* mot_db); void load_outfit_object_info(item_id id, object_info obj_info, bool osage_reset, const bone_database* bone_data, void* data, const object_database* obj_db); + void pos_reset(); void rob_info_ctrl(); void rob_motion_modifier_ctrl(); void reset_data(const rob_chara_pv_data* pv_data, @@ -3741,7 +3744,7 @@ struct rob_chara { float_t value, rob_partial_motion_playback_state playback_state, float_t blend_duration, float_t play_duration, float_t step, rob_partial_motion_loop_state loop_state, float_t blend_offset, const motion_database* mot_db); - void set_osage_move_cancel(uint8_t id, float_t value); + void set_osage_move_cancel(uint8_t id, float_t mv_ccl); void set_osage_reset(); void set_osage_step(float_t value); void set_parts_disp(item_id id, bool disp); @@ -3867,7 +3870,7 @@ extern const uint32_t* get_opd_motion_set_ids(); const char* get_dev_ram_opdi_dir(); -extern const float_t get_osage_gravity_const(); +extern const float_t get_gravity(); extern const char* get_ram_osage_play_data_dir(); extern const char* get_ram_osage_play_data_tmp_dir(); diff --git a/src/CRE/rob/skin_param.cpp b/src/CRE/rob/skin_param.cpp index 09dc416b..e4b0b725 100644 --- a/src/CRE/rob/skin_param.cpp +++ b/src/CRE/rob/skin_param.cpp @@ -176,7 +176,7 @@ skin_param_osage_root_boc::~skin_param_osage_root_boc() { } skin_param_osage_root::skin_param_osage_root() : field_0(), force(), force_gain(), -rot_y(), rot_z(), init_rot_y(), init_rot_z(), coli_r(), yz_order(), stiffness() { +rot_y(), rot_z(), init_rot_y(), init_rot_z(), coli_r(), rottype(), stiffness() { air_res = 0.5f; hinge_y = 90.0f; hinge_z = 90.0f; @@ -800,11 +800,11 @@ void SkinParamManager::AddFiles() { int32_t osage_count = 0; int32_t cloth_count = 0; - obj_skin_block* b = ex_data->block_array; - for (int32_t k = ex_data->num_block; k; k--, b++) - if (b->type == OBJ_SKIN_BLOCK_OSAGE) + obj_skin_ex_node* b = ex_data->ex_node_table; + for (int32_t k = ex_data->num_ex_node; k; k--, b++) + if (b->type == OBJ_SKIN_EX_NODE_OSAGE) osage_count++; - else if (b->type == OBJ_SKIN_BLOCK_CLOTH) + else if (b->type == OBJ_SKIN_EX_NODE_CLOTH) cloth_count++; if (!ex_data || !(osage_count + cloth_count)) @@ -938,8 +938,8 @@ bool SkinParamManager::CtrlFiles() { rob_chara_item_equip_object* itm_eq_obj = &rob_itm_equip->item_equip_object[skp_file->id]; skin_param_file_data* skp_file_data = skp_file->data->data(); - for (ExNodeBlock* j : itm_eq_obj->node_blocks) { - if (j->type != EX_OSAGE && j->type != EX_CLOTH) + for (ExNodeBlock* j : itm_eq_obj->ex_node_block) { + if (j->type != EX_NODE_TYPE_OSAGE && j->type != EX_NODE_TYPE_CLOTH) continue; const char* name = j->name; diff --git a/src/KKdLib/obj.cpp b/src/KKdLib/obj.cpp index 0d586c78..92ad6786 100644 --- a/src/KKdLib/obj.cpp +++ b/src/KKdLib/obj.cpp @@ -29,20 +29,21 @@ enum obj_vertex_format_file { OBJ_VERTEX_FILE_MODERN_STORAGE = 0x80000000, }; -struct obj_skin_block_header { - int64_t block_signature_offset; - int64_t block_offset; +struct obj_skin_ex_node_header { + int64_t ex_node_signature_offset; + int64_t ex_node_offset; }; struct obj_skin_ex_data_header { - int32_t num_osage; - int64_t osage_node_array_offset; - int64_t osage_name_array_offset; - int64_t block_array_offset; - int32_t num_bone_name; - int64_t bone_name_array_offset; - int64_t osage_sibling_info_array_offset; - int32_t cloth_count; + int32_t nb_root; + int64_t osage_root_offset; + int64_t osage_joint_offset; + int64_t root_name_offset; + int64_t ex_node_array_offset; + int32_t nb_node_name; + int64_t ex_node_name_offset; + int64_t osage_constraint_tbl_offset; + int32_t nb_cloth; }; struct obj_skin_header { @@ -131,26 +132,26 @@ static void obj_move_data_skin_bone(obj_skin_bone* bone_dst, const obj_skin_bone prj::shared_ptr alloc); static obj_skin_ex_data* obj_move_data_skin_ex_data(const obj_skin_ex_data* ex_src, prj::shared_ptr alloc); -static obj_skin_block_cloth* obj_move_data_skin_block_cloth(const obj_skin_block_cloth* cls_src, +static obj_skin_ex_node_cloth* obj_move_data_skin_ex_node_cloth(const obj_skin_ex_node_cloth* cls_src, prj::shared_ptr alloc); -static void obj_move_data_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root_dst, - const obj_skin_block_cloth_root* cloth_root_src, +static void obj_move_data_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root_dst, + const obj_skin_ex_node_cloth_root* cloth_root_src, prj::shared_ptr alloc); -static void obj_move_data_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight_dst, - const obj_skin_block_cloth_root_bone_weight* bone_weight_src, +static void obj_move_data_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight_dst, + const obj_skin_ex_node_cloth_weight* bone_weight_src, prj::shared_ptr alloc); -static obj_skin_block_constraint* obj_move_data_skin_block_constraint(const obj_skin_block_constraint* cns_src, +static obj_skin_ex_node_constraint* obj_move_data_skin_ex_node_constraint(const obj_skin_ex_node_constraint* cns_src, prj::shared_ptr alloc); -static void obj_move_data_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector_dst, - const obj_skin_block_constraint_up_vector* up_vector_src, +static void obj_move_data_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector_dst, + const obj_skin_ex_node_constraint_up_vector* up_vector_src, prj::shared_ptr alloc); -static obj_skin_block_expression* obj_move_data_skin_block_expression(const obj_skin_block_expression* exp_src, +static obj_skin_ex_node_expression* obj_move_data_skin_ex_node_expression(const obj_skin_ex_node_expression* exp_src, prj::shared_ptr alloc); -static obj_skin_block_motion* obj_move_data_skin_block_motion(const obj_skin_block_motion* mot_src, +static obj_skin_ex_node_motion* obj_move_data_skin_ex_node_motion(const obj_skin_ex_node_motion* mot_src, prj::shared_ptr alloc); -static void obj_move_data_skin_block_node(obj_skin_block_node* node_dst, const obj_skin_block_node* node_src, +static void obj_move_data_skin_ex_node_transform(obj_skin_ex_node_transform* node_dst, const obj_skin_ex_node_transform* node_src, prj::shared_ptr alloc); -static obj_skin_block_osage* obj_move_data_skin_block_osage(const obj_skin_block_osage* osg_src, +static obj_skin_ex_node_osage* obj_move_data_skin_ex_node_osage(const obj_skin_ex_node_osage* osg_src, prj::shared_ptr alloc); static obj_skin_skin_param* obj_move_data_skin_param(const obj_skin_skin_param* skp_src, prj::shared_ptr alloc); @@ -170,50 +171,50 @@ static obj_skin* obj_classic_read_skin(prj::shared_ptr all static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset); static obj_skin_ex_data* obj_classic_read_skin_ex_data(prj::shared_ptr alloc, stream& s, int64_t base_offset); -static obj_skin_block_cloth* obj_classic_read_skin_block_cloth( +static obj_skin_ex_node_cloth* obj_classic_read_skin_ex_node_cloth( prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* cls, +static void obj_classic_write_skin_ex_node_cloth(obj_skin_ex_node_cloth* cls, stream& s, std::vector& strings, std::vector& string_offsets, - int64_t* mat_array_offset, int64_t* root_array_offset, int64_t* node_array_offset, - int64_t* mesh_index_array_offset, int64_t* backface_mesh_index_array_offset); -static void obj_classic_read_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, + int64_t* matrix_offset, int64_t* fix_point_offset, int64_t* node_array_offset, + int64_t* omote_index_array_offset, int64_t* ura_index_array_offset); +static void obj_classic_read_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, +static void obj_classic_write_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, stream& s, std::vector& strings, std::vector& string_offsets); -static void obj_classic_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_classic_read_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_classic_write_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, stream& s, std::vector& strings, std::vector& string_offsets); -static obj_skin_block_constraint* obj_classic_read_skin_block_constraint( +static obj_skin_ex_node_constraint* obj_classic_read_skin_ex_node_constraint( prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* cns, +static void obj_classic_write_skin_ex_node_constraint(obj_skin_ex_node_constraint* cns, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array, int64_t* offsets); -static void obj_classic_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, + const char** ex_node_name, int64_t* offsets); +static void obj_classic_read_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, const char** str); -static void obj_classic_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, +static void obj_classic_write_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, std::vector& strings, std::vector& string_offsets); -static void obj_classic_read_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_classic_read_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_classic_write_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, stream& s, std::vector& strings, std::vector& string_offsets); -static obj_skin_block_expression* obj_classic_read_skin_block_expression( +static obj_skin_ex_node_expression* obj_classic_read_skin_ex_node_expression( prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_expression(obj_skin_block_expression* exp, +static void obj_classic_write_skin_ex_node_expression(obj_skin_ex_node_expression* exp, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array); -static obj_skin_block_motion* obj_classic_read_skin_block_motion( + const char** ex_node_name); +static obj_skin_ex_node_motion* obj_classic_read_skin_ex_node_motion( prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_motion(obj_skin_block_motion* mot, +static void obj_classic_write_skin_ex_node_motion(obj_skin_ex_node_motion* mot, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset); -static void obj_classic_read_skin_block_node(obj_skin_block_node* node, + const char** ex_node_name, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset); +static void obj_classic_read_skin_ex_node_transform(obj_skin_ex_node_transform* node, prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_node(obj_skin_block_node* node, +static void obj_classic_write_skin_ex_node_transform(obj_skin_ex_node_transform* node, stream& s, std::vector& strings, std::vector& string_offsets); -static obj_skin_block_osage* obj_classic_read_skin_block_osage( +static obj_skin_ex_node_osage* obj_classic_read_skin_ex_node_osage( prj::shared_ptr alloc, stream& s, const char** str); -static void obj_classic_write_skin_block_osage(obj_skin_block_osage* osg, +static void obj_classic_write_skin_ex_node_osage(obj_skin_ex_node_osage* osg, stream& s, std::vector& strings, std::vector& string_offsets, int64_t* node_array_offset); static obj_skin_skin_param* obj_classic_read_skin_param( prj::shared_ptr alloc, stream& s, const char** str); @@ -247,50 +248,50 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, int64_t base_offset, bool is_x, f2_struct* oskn); static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptr alloc, stream& s, int64_t base_offset, uint32_t header_length, bool is_x); -static obj_skin_block_cloth* obj_modern_read_skin_block_cloth( +static obj_skin_ex_node_cloth* obj_modern_read_skin_ex_node_cloth( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, +static void obj_modern_write_skin_ex_node_cloth(obj_skin_ex_node_cloth* cls, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, - int64_t* mat_array_offset, int64_t* root_array_offset, int64_t* node_array_offset, - int64_t* mesh_index_array_offset, int64_t* backface_mesh_index_array_offset); -static void obj_modern_read_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, + int64_t* matrix_offset, int64_t* fix_point_offset, int64_t* node_array_offset, + int64_t* omote_index_array_offset, int64_t* ura_index_array_offset); +static void obj_modern_read_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, +static void obj_modern_write_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); -static void obj_modern_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_modern_read_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_modern_write_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); -static obj_skin_block_constraint* obj_modern_read_skin_block_constraint( +static obj_skin_ex_node_constraint* obj_modern_read_skin_ex_node_constraint( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* cns, - stream& s, std::vector& strings, std::vector& string_offsets, const char** bone_name_array, +static void obj_modern_write_skin_ex_node_constraint(obj_skin_ex_node_constraint* cns, + stream& s, std::vector& strings, std::vector& string_offsets, const char** ex_node_name, bool is_x, int64_t* offsets); -static void obj_modern_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, +static void obj_modern_read_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, +static void obj_modern_write_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); -static void obj_modern_read_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_modern_read_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_modern_write_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); -static obj_skin_block_expression* obj_modern_read_skin_block_expression( +static obj_skin_ex_node_expression* obj_modern_read_skin_ex_node_expression( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_expression(obj_skin_block_expression* exp, +static void obj_modern_write_skin_ex_node_expression(obj_skin_ex_node_expression* exp, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array, bool is_x); -static obj_skin_block_motion* obj_modern_read_skin_block_motion( + const char** ex_node_name, bool is_x); +static obj_skin_ex_node_motion* obj_modern_read_skin_ex_node_motion( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_motion(obj_skin_block_motion* mot, +static void obj_modern_write_skin_ex_node_motion(obj_skin_ex_node_motion* mot, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, - const char** bone_name_array, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset); -static void obj_modern_read_skin_block_node(obj_skin_block_node* node, + const char** ex_node_name, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset); +static void obj_modern_read_skin_ex_node_transform(obj_skin_ex_node_transform* node, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_node(obj_skin_block_node* node, +static void obj_modern_write_skin_ex_node_transform(obj_skin_ex_node_transform* node, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); -static obj_skin_block_osage* obj_modern_read_skin_block_osage( +static obj_skin_ex_node_osage* obj_modern_read_skin_ex_node_osage( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); -static void obj_modern_write_skin_block_osage(obj_skin_block_osage* osg, +static void obj_modern_write_skin_ex_node_osage(obj_skin_ex_node_osage* osg, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); static void obj_modern_read_vertex(obj_mesh* mesh, prj::shared_ptr alloc, stream& s, int64_t* vertex, const uint32_t vertex_format_index, int32_t num_vertex, uint32_t size_vertex); @@ -383,102 +384,105 @@ size_vertex(), num_vertex(), vertex_array(), attrib(), reserved(), name() { } -obj_skin_block_node::obj_skin_block_node() : parent_name() { +obj_skin_ex_node_transform::obj_skin_ex_node_transform() : parent_name() { } -obj_skin_skin_param_coli::obj_skin_skin_param_coli() : type(), bone0_index(), bone1_index(), radius() { +obj_skin_skin_param_coli::obj_skin_skin_param_coli() : type(), nid0(), nid1(), radius() { } -obj_skin_skin_param::obj_skin_skin_param() : unk0(), force(), force_gain(), air_res(), rot_y(), rot_z(), -hinge_y(), hinge_z(), name(), coli(), coli_count(), coli_r(), friction(), wind_afc(), unk44() { +obj_skin_skin_param::obj_skin_skin_param() : root_nid(), force(), force_gain(), air_res(), angle(), +limit(), name(), coli_array(), num_coli(), coli_r(), friction(), wind_afc(), rottype() { } -obj_skin_block_cloth_root_bone_weight::obj_skin_block_cloth_root_bone_weight() : -bone_name(), weight(), matrix_index(), reserved() { +obj_skin_ex_node_cloth_weight::obj_skin_ex_node_cloth_weight() : +bone_name(), weight(), mat_idx(), dummy() { } -obj_skin_block_cloth_root::obj_skin_block_cloth_root() : field_18(), field_1C(), field_20(), field_24() { +obj_skin_ex_node_cloth_root::obj_skin_ex_node_cloth_root() { } -obj_skin_block_cloth_node::obj_skin_block_cloth_node() : flags(), -dist_top(), dist_bottom(), dist_right(), dist_left() { +obj_skin_ex_node_cloth_point::obj_skin_ex_node_cloth_point() : link_flag(), length() { } -obj_skin_block_cloth::obj_skin_block_cloth() : mesh_name(), backface_mesh_name(), field_8(), -num_root(), num_node(), loop(), mat_array(), num_mat(), root_array(), node_array(), mesh_index_array(), -num_mesh_index(), backface_mesh_index_array(), num_backface_mesh_index(), skin_param(), reserved() { +obj_skin_ex_node_cloth::obj_skin_ex_node_cloth() : omote_name(), ura_name(), version(), +width(), height(), ring_flag(), mat_array(), num_mat(), fix_point(), move_point(), omote_index_array(), +num_omote_index(), ura_index_array(), num_ura_index(), param(), dummy() { } -obj_skin_block_constraint_attach_point::obj_skin_block_constraint_attach_point() +obj_skin_ex_node_constraint_attach_point::obj_skin_ex_node_constraint_attach_point() : affected_by_orientation(), affected_by_scaling() { } -obj_skin_block_constraint_up_vector::obj_skin_block_constraint_up_vector() : active(), roll(), name() { +obj_skin_ex_node_constraint_up_vector::obj_skin_ex_node_constraint_up_vector() : active(), roll(), name() { } -obj_skin_block_constraint_direction::obj_skin_block_constraint_direction() { +obj_skin_ex_node_constraint_direction::obj_skin_ex_node_constraint_direction() { } -obj_skin_block_constraint_distance::obj_skin_block_constraint_distance() : distance() { +obj_skin_ex_node_constraint_distance::obj_skin_ex_node_constraint_distance() : distance() { } -obj_skin_block_constraint_orientation::obj_skin_block_constraint_orientation() { +obj_skin_ex_node_constraint_orientation::obj_skin_ex_node_constraint_orientation() { } -obj_skin_block_constraint_position::obj_skin_block_constraint_position() { +obj_skin_ex_node_constraint_position::obj_skin_ex_node_constraint_position() { } -obj_skin_block_constraint::obj_skin_block_constraint() - : name_index(), source_node_name(), coupling(), type(), data() { +obj_skin_ex_node_constraint::obj_skin_ex_node_constraint() + : node_name(), src_name(), nb_src(), type(), data() { } -obj_skin_block_expression::obj_skin_block_expression() - : name_index(), num_expression(), expression_array() { +obj_skin_ex_node_expression::obj_skin_ex_node_expression() + : node_name(), nb_src(), script() { } -obj_skin_motion_node::obj_skin_motion_node() : name_index() { +obj_skin_motion_node::obj_skin_motion_node() : node_name() { } -obj_skin_block_motion::obj_skin_block_motion() : name(), node_array(), num_node() { +obj_skin_ex_node_motion::obj_skin_ex_node_motion() : name(), node_array(), num_node() { } -obj_skin_osage_node::obj_skin_osage_node() : name_index(), length() { +obj_skin_osage_joint_rotation::obj_skin_osage_joint_rotation() : nid(), length() { } -obj_skin_block_osage::obj_skin_block_osage() : start_index(), count(), node_array(), -num_node(), skin_param(), name_index(), end_name_index(), motion_node_name() { +obj_skin_ex_node_osage::obj_skin_ex_node_osage() : joint_ofs(), nb_joint(), joint_rotation_array(), +num_joint_rotation(), skin_param(), root_idx(), efc_idx(), motion_node_name() { } -obj_skin_block::obj_skin_block() : type(), node() { +obj_skin_ex_node::obj_skin_ex_node() : type(), transform() { } -obj_skin_osage_sibling_info::obj_skin_osage_sibling_info() - : name_index(), sibling_name_index(), max_distance() { +obj_skin_osage_constraint_info::obj_skin_osage_constraint_info() + : dst_joint(), src_joint(), length() { } -obj_skin_ex_data::obj_skin_ex_data() : osage_node_array(), num_osage_node(), block_array(), num_block(), -bone_name_array(), num_bone_name(), osage_sibling_info_array(), num_osage_sibling_info(), reserved() { +obj_skin_osage_joint::obj_skin_osage_joint() : nid(), length() { + +} + +obj_skin_ex_data::obj_skin_ex_data() : nb_jointX(), osage_root(), osage_joint(), ex_node_table(), num_ex_node(), +ex_node_name(), nb_node_name(), osage_constraint_tbl(), num_osage_constraint(), reserved() { } @@ -912,184 +916,184 @@ static obj_skin_ex_data* obj_move_data_skin_ex_data(const obj_skin_ex_data* ex_s obj_skin_ex_data* ex_dst = alloc->allocate(); - int32_t num_osage_node = ex_src->num_osage_node; - ex_dst->osage_node_array = alloc->allocate( - ex_src->osage_node_array, num_osage_node); - ex_dst->num_osage_node = num_osage_node; + int32_t nb_jointX = ex_src->nb_jointX; + ex_dst->osage_joint = alloc->allocate( + ex_src->osage_joint, nb_jointX); + ex_dst->nb_jointX = nb_jointX; - int32_t num_block = ex_src->num_block; - obj_skin_block* block_array_src = ex_src->block_array; - obj_skin_block* block_array_dst = alloc->allocate(num_block); + int32_t num_ex_node = ex_src->num_ex_node; + obj_skin_ex_node* ex_node_array_src = ex_src->ex_node_table; + obj_skin_ex_node* ex_node_array_dst = alloc->allocate(num_ex_node); - for (int32_t i = 0; i < num_block; i++) { - obj_skin_block* block_src = &block_array_src[i]; - obj_skin_block* block_dst = &block_array_dst[i]; - switch (block_src->type) { + for (int32_t i = 0; i < num_ex_node; i++) { + obj_skin_ex_node* ex_node_src = &ex_node_array_src[i]; + obj_skin_ex_node* ex_node_dst = &ex_node_array_dst[i]; + switch (ex_node_src->type) { default: - block_dst->type = OBJ_SKIN_BLOCK_NONE; - block_dst->node = 0; + ex_node_dst->type = OBJ_SKIN_EX_NODE_NONE; + ex_node_dst->transform = 0; break; - case OBJ_SKIN_BLOCK_CLOTH: - block_dst->type = OBJ_SKIN_BLOCK_CLOTH; - block_dst->cloth = obj_move_data_skin_block_cloth(block_src->cloth, alloc); + case OBJ_SKIN_EX_NODE_CLOTH: + ex_node_dst->type = OBJ_SKIN_EX_NODE_CLOTH; + ex_node_dst->cloth = obj_move_data_skin_ex_node_cloth(ex_node_src->cloth, alloc); break; - case OBJ_SKIN_BLOCK_CONSTRAINT: - block_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT; - block_dst->constraint = obj_move_data_skin_block_constraint(block_src->constraint, alloc); + case OBJ_SKIN_EX_NODE_CONSTRAINT: + ex_node_dst->type = OBJ_SKIN_EX_NODE_CONSTRAINT; + ex_node_dst->constraint = obj_move_data_skin_ex_node_constraint(ex_node_src->constraint, alloc); break; - case OBJ_SKIN_BLOCK_EXPRESSION: - block_dst->type = OBJ_SKIN_BLOCK_EXPRESSION; - block_dst->expression = obj_move_data_skin_block_expression(block_src->expression, alloc); + case OBJ_SKIN_EX_NODE_EXPRESSION: + ex_node_dst->type = OBJ_SKIN_EX_NODE_EXPRESSION; + ex_node_dst->expression = obj_move_data_skin_ex_node_expression(ex_node_src->expression, alloc); break; - case OBJ_SKIN_BLOCK_MOTION: - block_dst->type = OBJ_SKIN_BLOCK_MOTION; - block_dst->motion = obj_move_data_skin_block_motion(block_src->motion, alloc); + case OBJ_SKIN_EX_NODE_MOTION: + ex_node_dst->type = OBJ_SKIN_EX_NODE_MOTION; + ex_node_dst->motion = obj_move_data_skin_ex_node_motion(ex_node_src->motion, alloc); break; - case OBJ_SKIN_BLOCK_OSAGE: - block_dst->type = OBJ_SKIN_BLOCK_OSAGE; - block_dst->osage = obj_move_data_skin_block_osage(block_src->osage, alloc); + case OBJ_SKIN_EX_NODE_OSAGE: + ex_node_dst->type = OBJ_SKIN_EX_NODE_OSAGE; + ex_node_dst->osage = obj_move_data_skin_ex_node_osage(ex_node_src->osage, alloc); break; } } - ex_dst->block_array = block_array_dst; - ex_dst->num_block = num_block; + ex_dst->ex_node_table = ex_node_array_dst; + ex_dst->num_ex_node = num_ex_node; - int32_t num_bone_name = ex_src->num_bone_name; - const char** bone_array_src = ex_src->bone_name_array; - const char** bone_array_dst = alloc->allocate(num_bone_name); + int32_t nb_node_name = ex_src->nb_node_name; + const char** ex_node_name_src = ex_src->ex_node_name; + const char** ex_node_name_dst = alloc->allocate(nb_node_name); - for (int32_t i = 0; i < num_bone_name; i++) - bone_array_dst[i] = obj_move_data_string(bone_array_src[i], alloc); + for (int32_t i = 0; i < nb_node_name; i++) + ex_node_name_dst[i] = obj_move_data_string(ex_node_name_src[i], alloc); - ex_dst->bone_name_array = bone_array_dst; - ex_dst->num_bone_name = num_bone_name; + ex_dst->nb_node_name = nb_node_name; + ex_dst->ex_node_name = ex_node_name_dst; - int32_t num_osage_sibling_info = ex_src->num_osage_sibling_info; - ex_dst->osage_sibling_info_array = alloc->allocate( - ex_src->osage_sibling_info_array, num_osage_sibling_info); - ex_dst->num_osage_sibling_info = num_osage_sibling_info; + int32_t num_osage_constraint = ex_src->num_osage_constraint; + ex_dst->osage_constraint_tbl = alloc->allocate( + ex_src->osage_constraint_tbl, num_osage_constraint); + ex_dst->num_osage_constraint = num_osage_constraint; memcpy(ex_dst->reserved, ex_src->reserved, sizeof(int64_t) * 7); return ex_dst; } -static obj_skin_block_cloth* obj_move_data_skin_block_cloth(const obj_skin_block_cloth* cls_src, +static obj_skin_ex_node_cloth* obj_move_data_skin_ex_node_cloth(const obj_skin_ex_node_cloth* cls_src, prj::shared_ptr alloc) { - obj_skin_block_cloth* cls_dst = alloc->allocate(); - cls_dst->mesh_name = obj_move_data_string(cls_src->mesh_name, alloc); - cls_dst->backface_mesh_name = obj_move_data_string(cls_src->backface_mesh_name, alloc); - cls_dst->field_8 = cls_src->field_8; + obj_skin_ex_node_cloth* cls_dst = alloc->allocate(); + cls_dst->omote_name = obj_move_data_string(cls_src->omote_name, alloc); + cls_dst->ura_name = obj_move_data_string(cls_src->ura_name, alloc); + cls_dst->version = cls_src->version; - int32_t num_root = cls_src->num_root; - int32_t num_node = cls_src->num_node; - cls_dst->num_root = num_root; - cls_dst->num_node = num_node; - cls_dst->loop = cls_src->loop; + uint32_t width = cls_src->width; + uint32_t height = cls_src->height; + cls_dst->width = width; + cls_dst->height = height; + cls_dst->ring_flag = cls_src->ring_flag; - int32_t num_mat = cls_src->num_mat; + uint32_t num_mat = cls_src->num_mat; cls_dst->mat_array = alloc->allocate(cls_src->mat_array, num_mat); cls_dst->num_mat = num_mat; - obj_skin_block_cloth_root* root_array_src = cls_src->root_array; - obj_skin_block_cloth_root* root_array_dst = alloc->allocate(num_root); + obj_skin_ex_node_cloth_root* fix_point_src = cls_src->fix_point; + obj_skin_ex_node_cloth_root* fix_point_dst = alloc->allocate(width); - for (int32_t i = 0; i < num_root; i++) - obj_move_data_skin_block_cloth_root(&root_array_dst[i], &root_array_src[i], alloc); + for (uint32_t i = 0; i < width; i++) + obj_move_data_skin_ex_node_cloth_root(&fix_point_dst[i], &fix_point_src[i], alloc); - cls_dst->root_array = root_array_dst; + cls_dst->fix_point = fix_point_dst; - cls_dst->node_array = alloc->allocate( - cls_src->node_array, num_root * (num_node - 1ULL)); + cls_dst->move_point = alloc->allocate( + cls_src->move_point, width * (height - 1ULL)); - int32_t num_mesh_index = cls_src->num_mesh_index; - cls_dst->mesh_index_array = alloc->allocate( - cls_src->mesh_index_array, num_mesh_index); - cls_dst->num_mesh_index = num_mesh_index; + uint32_t num_omote_index = cls_src->num_omote_index; + cls_dst->omote_index_array = alloc->allocate( + cls_src->omote_index_array, num_omote_index); + cls_dst->num_omote_index = num_omote_index; - int32_t num_backface_mesh_index = cls_src->num_backface_mesh_index; - cls_dst->backface_mesh_index_array = alloc->allocate( - cls_src->backface_mesh_index_array, num_backface_mesh_index); - cls_dst->num_backface_mesh_index = num_backface_mesh_index; + uint32_t num_ura_index = cls_src->num_ura_index; + cls_dst->ura_index_array = alloc->allocate( + cls_src->ura_index_array, num_ura_index); + cls_dst->num_ura_index = num_ura_index; - cls_dst->skin_param = obj_move_data_skin_param(cls_src->skin_param, alloc); - cls_dst->reserved = cls_src->reserved; + cls_dst->param = obj_move_data_skin_param(cls_src->param, alloc); + cls_dst->dummy = cls_src->dummy; return cls_dst; } -static void obj_move_data_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root_dst, - const obj_skin_block_cloth_root* cloth_root_src, +static void obj_move_data_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root_dst, + const obj_skin_ex_node_cloth_root* cloth_root_src, prj::shared_ptr alloc) { cloth_root_dst->pos = cloth_root_src->pos; cloth_root_dst->normal = cloth_root_src->normal; - cloth_root_dst->field_18 = cloth_root_src->field_18; - cloth_root_dst->field_1C = cloth_root_src->field_1C; - cloth_root_dst->field_20 = cloth_root_src->field_20; - cloth_root_dst->field_24 = cloth_root_src->field_24; + cloth_root_dst->tangent.x = cloth_root_src->tangent.x; + cloth_root_dst->tangent.y = cloth_root_src->tangent.y; + cloth_root_dst->tangent.z = cloth_root_src->tangent.z; + cloth_root_dst->tangent.w = cloth_root_src->tangent.w; for (uint32_t i = 0; i < 4; i++) - obj_move_data_skin_block_cloth_root_bone_weight(&cloth_root_dst->bone_weights[i], - &cloth_root_src->bone_weights[i], alloc); + obj_move_data_skin_ex_node_cloth_root_bone_weight(&cloth_root_dst->weight[i], + &cloth_root_src->weight[i], alloc); } -static void obj_move_data_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight_dst, - const obj_skin_block_cloth_root_bone_weight* bone_weight_src, +static void obj_move_data_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight_dst, + const obj_skin_ex_node_cloth_weight* bone_weight_src, prj::shared_ptr alloc) { bone_weight_dst->bone_name = obj_move_data_string(bone_weight_src->bone_name, alloc); bone_weight_dst->weight = bone_weight_src->weight; - bone_weight_dst->matrix_index = bone_weight_src->matrix_index; - bone_weight_dst->reserved = bone_weight_src->reserved; + bone_weight_dst->mat_idx = bone_weight_src->mat_idx; + bone_weight_dst->dummy = bone_weight_src->dummy; } -static obj_skin_block_constraint* obj_move_data_skin_block_constraint(const obj_skin_block_constraint* cns_src, +static obj_skin_ex_node_constraint* obj_move_data_skin_ex_node_constraint(const obj_skin_ex_node_constraint* cns_src, prj::shared_ptr alloc) { - obj_skin_block_constraint* cns_dst = alloc->allocate(); - obj_move_data_skin_block_node(&cns_dst->node, &cns_src->node, alloc); - cns_dst->name_index = cns_src->name_index; - cns_dst->source_node_name = obj_move_data_string(cns_src->source_node_name, alloc); - cns_dst->coupling = cns_src->coupling; + obj_skin_ex_node_constraint* cns_dst = alloc->allocate(); + obj_move_data_skin_ex_node_transform(&cns_dst->transform, &cns_src->transform, alloc); + cns_dst->node_name = cns_src->node_name; + cns_dst->nb_src = cns_src->nb_src; + cns_dst->src_name = obj_move_data_string(cns_src->src_name, alloc); switch (cns_src->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: { - cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION; + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: { + cns_dst->type = OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION; - obj_skin_block_constraint_orientation* orientation_src = cns_src->orientation; - obj_skin_block_constraint_orientation* orientation_dst - = alloc->allocate(); + obj_skin_ex_node_constraint_orientation* orientation_src = cns_src->orientation; + obj_skin_ex_node_constraint_orientation* orientation_dst + = alloc->allocate(); orientation_dst->offset = orientation_src->offset; cns_dst->orientation = orientation_dst; } break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: { - cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION; + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: { + cns_dst->type = OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION; - obj_skin_block_constraint_direction* direction_src = cns_src->direction; - obj_skin_block_constraint_direction* direction_dst - = alloc->allocate(); - obj_move_data_skin_block_constraint_up_vector( + obj_skin_ex_node_constraint_direction* direction_src = cns_src->direction; + obj_skin_ex_node_constraint_direction* direction_dst + = alloc->allocate(); + obj_move_data_skin_ex_node_constraint_up_vector( &direction_dst->up_vector, &direction_src->up_vector, alloc); direction_dst->align_axis = direction_src->align_axis; direction_dst->target_offset = direction_src->target_offset; cns_dst->direction = direction_dst; } break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: { - cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_POSITION; + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: { + cns_dst->type = OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION; - obj_skin_block_constraint_position* position_src = cns_src->position; - obj_skin_block_constraint_position* position_dst - = alloc->allocate(); - obj_move_data_skin_block_constraint_up_vector( + obj_skin_ex_node_constraint_position* position_src = cns_src->position; + obj_skin_ex_node_constraint_position* position_dst + = alloc->allocate(); + obj_move_data_skin_ex_node_constraint_up_vector( &position_dst->up_vector, &position_src->up_vector, alloc); position_dst->constrained_object = position_src->constrained_object; position_dst->constraining_object = position_src->constraining_object; cns_dst->position = position_dst; } break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: { - cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE; + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: { + cns_dst->type = OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE; - obj_skin_block_constraint_distance* distance_src = cns_src->distance; - obj_skin_block_constraint_distance* distance_dst - = alloc->allocate(); - obj_move_data_skin_block_constraint_up_vector( + obj_skin_ex_node_constraint_distance* distance_src = cns_src->distance; + obj_skin_ex_node_constraint_distance* distance_dst + = alloc->allocate(); + obj_move_data_skin_ex_node_constraint_up_vector( &distance_dst->up_vector, &distance_src->up_vector, alloc); distance_dst->distance = distance_src->distance; distance_dst->constrained_object = distance_src->constrained_object; @@ -1097,14 +1101,14 @@ static obj_skin_block_constraint* obj_move_data_skin_block_constraint(const obj_ cns_dst->distance = distance_dst; } break; default: - cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns_dst->type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; cns_dst->data = 0; } return cns_dst; } -static void obj_move_data_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector_dst, - const obj_skin_block_constraint_up_vector* up_vector_src, +static void obj_move_data_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector_dst, + const obj_skin_ex_node_constraint_up_vector* up_vector_src, prj::shared_ptr alloc) { up_vector_dst->active = up_vector_src->active; up_vector_dst->roll = up_vector_src->roll; @@ -1113,31 +1117,31 @@ static void obj_move_data_skin_block_constraint_up_vector(obj_skin_block_constra up_vector_dst->name = obj_move_data_string(up_vector_src->name, alloc); } -static obj_skin_block_expression* obj_move_data_skin_block_expression(const obj_skin_block_expression* exp_src, +static obj_skin_ex_node_expression* obj_move_data_skin_ex_node_expression(const obj_skin_ex_node_expression* exp_src, prj::shared_ptr alloc) { - obj_skin_block_expression* exp_dst = alloc->allocate(); - obj_move_data_skin_block_node(&exp_dst->node, &exp_src->node, alloc); - exp_dst->name_index = exp_src->name_index; + obj_skin_ex_node_expression* exp_dst = alloc->allocate(); + obj_move_data_skin_ex_node_transform(&exp_dst->transform, &exp_src->transform, alloc); + exp_dst->node_name = exp_src->node_name; - int32_t num_expression = exp_src->num_expression; - num_expression = min_def(num_expression, 9); - exp_dst->num_expression = num_expression; - for (int32_t i = 0; i < num_expression; i++) - exp_dst->expression_array[i] = obj_move_data_string(exp_src->expression_array[i], alloc); + int32_t nb_src = exp_src->nb_src; + nb_src = min_def(nb_src, 9); + exp_dst->nb_src = nb_src; + for (int32_t i = 0; i < nb_src; i++) + exp_dst->script[i] = obj_move_data_string(exp_src->script[i], alloc); - for (int32_t i = num_expression; i < 9; i++) - exp_dst->expression_array[i] = 0; + for (int32_t i = nb_src; i < 9; i++) + exp_dst->script[i] = 0; return exp_dst; } -static obj_skin_block_motion* obj_move_data_skin_block_motion(const obj_skin_block_motion* mot_src, +static obj_skin_ex_node_motion* obj_move_data_skin_ex_node_motion(const obj_skin_ex_node_motion* mot_src, prj::shared_ptr alloc) { - obj_skin_block_motion* mot_dst = alloc->allocate(); - obj_move_data_skin_block_node(&mot_dst->node, &mot_src->node, alloc); + obj_skin_ex_node_motion* mot_dst = alloc->allocate(); + obj_move_data_skin_ex_node_transform(&mot_dst->transform, &mot_src->transform, alloc); mot_dst->name = 0; - if ((mot_src->name_index & ~0x7FFF) == 0x8000) - mot_dst->name_index = mot_src->name_index; + if ((mot_src->node_name & ~0x7FFF) == 0x8000) + mot_dst->node_name = mot_src->node_name; else mot_dst->name = obj_move_data_string(mot_src->name, alloc); @@ -1147,7 +1151,7 @@ static obj_skin_block_motion* obj_move_data_skin_block_motion(const obj_skin_blo return mot_dst; } -static void obj_move_data_skin_block_node(obj_skin_block_node* node_dst, const obj_skin_block_node* node_src, +static void obj_move_data_skin_ex_node_transform(obj_skin_ex_node_transform* node_dst, const obj_skin_ex_node_transform* node_src, prj::shared_ptr alloc) { node_dst->parent_name = obj_move_data_string(node_src->parent_name, alloc); node_dst->position = node_src->position; @@ -1155,20 +1159,21 @@ static void obj_move_data_skin_block_node(obj_skin_block_node* node_dst, const o node_dst->scale = node_src->scale; } -static obj_skin_block_osage* obj_move_data_skin_block_osage(const obj_skin_block_osage* osg_src, +static obj_skin_ex_node_osage* obj_move_data_skin_ex_node_osage(const obj_skin_ex_node_osage* osg_src, prj::shared_ptr alloc) { - obj_skin_block_osage* osg_dst = alloc->allocate(); - obj_move_data_skin_block_node(&osg_dst->node, &osg_src->node, alloc); - osg_dst->start_index = osg_src->start_index; - osg_dst->count = osg_src->count; + obj_skin_ex_node_osage* osg_dst = alloc->allocate(); + obj_move_data_skin_ex_node_transform(&osg_dst->transform, &osg_src->transform, alloc); + osg_dst->joint_ofs = osg_src->joint_ofs; + osg_dst->nb_joint = osg_src->nb_joint; - int32_t num_node = osg_src->num_node; - osg_dst->node_array = alloc->allocate(osg_src->node_array, num_node); - osg_dst->num_node = num_node; + int32_t num_joint_rotation = osg_src->num_joint_rotation; + osg_dst->joint_rotation_array = alloc->allocate( + osg_src->joint_rotation_array, num_joint_rotation); + osg_dst->num_joint_rotation = num_joint_rotation; osg_dst->skin_param = obj_move_data_skin_param(osg_src->skin_param, alloc); - osg_dst->name_index = osg_src->name_index; - osg_dst->end_name_index = osg_src->end_name_index; + osg_dst->root_idx = osg_src->root_idx; + osg_dst->efc_idx = osg_src->efc_idx; osg_dst->motion_node_name = obj_move_data_string(osg_src->motion_node_name, alloc); return osg_dst; } @@ -1179,24 +1184,24 @@ static obj_skin_skin_param* obj_move_data_skin_param(const obj_skin_skin_param* return 0; obj_skin_skin_param* skp_dst = alloc->allocate(); - skp_dst->unk0 = skp_src->unk0; + skp_dst->root_nid = skp_src->root_nid; skp_dst->force = skp_src->force; skp_dst->force_gain = skp_src->force_gain; skp_dst->air_res = skp_src->air_res; - skp_dst->rot_y = skp_src->rot_y; - skp_dst->rot_z = skp_src->rot_z; - skp_dst->hinge_y = skp_src->hinge_y; - skp_dst->hinge_z = skp_src->hinge_z; + skp_dst->angle[0] = skp_src->angle[0]; + skp_dst->angle[1] = skp_src->angle[1]; + skp_dst->limit[0] = skp_src->limit[0]; + skp_dst->limit[1] = skp_src->limit[1]; skp_dst->name = obj_move_data_string(skp_src->name, alloc); - uint32_t coli_count = skp_src->coli_count; - skp_dst->coli = alloc->allocate(skp_src->coli, coli_count); - skp_dst->coli_count = coli_count; + uint32_t num_coli = skp_src->num_coli; + skp_dst->coli_array = alloc->allocate(skp_src->coli_array, num_coli); + skp_dst->num_coli = num_coli; skp_dst->coli_r = skp_src->coli_r; skp_dst->friction = skp_src->friction; skp_dst->wind_afc = skp_src->wind_afc; - skp_dst->unk44 = skp_src->unk44; + skp_dst->rottype = skp_src->rottype; return skp_dst; } @@ -1890,10 +1895,10 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) s.align_write(0x10); } - obj_skin_block_header* bhs = 0; - int64_t osage_block_node = 0; - int64_t motion_block_node_mats = 0; - int64_t motion_block_node_name_offset = 0; + obj_skin_ex_node_header* bhs = 0; + int64_t osage_ex_node_transform = 0; + int64_t motion_ex_node_transform_mats = 0; + int64_t motion_ex_node_transform_name_offset = 0; int64_t cloth_mats = 0; int64_t cloth_root = 0; int64_t cloth_nodes = 0; @@ -1907,7 +1912,7 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) sh.ex_data_offset = s.get_position(); s.write_int32_t(0); s.write_int32_t(0); - s.write(0x04); + s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); @@ -1918,17 +1923,17 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) s.write(0x1C); s.align_write(0x10); - if (ex->num_osage_node) { - exh.osage_node_array_offset = s.get_position(); - for (int32_t i = 0; i < ex->num_osage_node; i++) { + if (ex->nb_jointX) { + exh.osage_joint_offset = s.get_position(); + for (int32_t i = 0; i < ex->nb_jointX; i++) { s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); } s.align_write(0x10); - exh.osage_sibling_info_array_offset = s.get_position(); - for (int32_t i = 0; i < ex->num_osage_sibling_info; i++) { + exh.osage_constraint_tbl_offset = s.get_position(); + for (int32_t i = 0; i < ex->num_osage_constraint; i++) { s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); @@ -1939,63 +1944,63 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) s.align_write(0x10); } - exh.cloth_count = 0; - exh.num_osage = 0; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type == OBJ_SKIN_BLOCK_CLOTH) - exh.cloth_count++; - else if (block->type == OBJ_SKIN_BLOCK_OSAGE) - exh.num_osage++; + exh.nb_cloth = 0; + exh.nb_root = 0; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type == OBJ_SKIN_EX_NODE_CLOTH) + exh.nb_cloth++; + else if (ex_node->type == OBJ_SKIN_EX_NODE_OSAGE) + exh.nb_root++; } - if (exh.num_osage || exh.cloth_count) { - exh.osage_name_array_offset = s.get_position(); - for (int32_t i = 0; i < exh.num_osage; i++) + if (exh.nb_root || exh.nb_cloth) { + exh.root_name_offset = s.get_position(); + for (int32_t i = 0; i < exh.nb_root; i++) s.write_int32_t(0); - for (int32_t i = 0; i < exh.cloth_count; i++) + for (int32_t i = 0; i < exh.nb_cloth; i++) s.write_int32_t(0); s.align_write(0x10); } - const char** bone_name_array = ex->bone_name_array; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - switch (block->type) { - case OBJ_SKIN_BLOCK_CLOTH: { - obj_skin_block_cloth* cloth = block->cloth; - obj_skin_strings_push_back_check(strings, cloth->mesh_name); - obj_skin_strings_push_back_check(strings, cloth->backface_mesh_name); - for (int32_t k = 0; k < cloth->num_root; k++) { - obj_skin_block_cloth_root* root_array = &cloth->root_array[k]; + const char** ex_node_name = ex->ex_node_name; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + switch (ex_node->type) { + case OBJ_SKIN_EX_NODE_CLOTH: { + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + obj_skin_strings_push_back_check(strings, cloth->omote_name); + obj_skin_strings_push_back_check(strings, cloth->ura_name); + for (uint32_t k = 0; k < cloth->width; k++) { + obj_skin_ex_node_cloth_root* fix_point = &cloth->fix_point[k]; for (uint32_t l = 0; l < 4; l++) - obj_skin_strings_push_back_check(strings, root_array->bone_weights[l].bone_name); + obj_skin_strings_push_back_check(strings, fix_point->weight[l].bone_name); } - if (cloth->skin_param) - obj_skin_strings_push_back_check(strings, cloth->skin_param->name); + if (cloth->param) + obj_skin_strings_push_back_check(strings, cloth->param->name); obj_skin_strings_push_back_check(strings, "CLS"); } break; - case OBJ_SKIN_BLOCK_CONSTRAINT: { - obj_skin_block_constraint* constraint = block->constraint; - obj_skin_strings_push_back_check(strings, constraint->node.parent_name); + case OBJ_SKIN_EX_NODE_CONSTRAINT: { + obj_skin_ex_node_constraint* constraint = ex_node->constraint; + obj_skin_strings_push_back_check(strings, constraint->transform.parent_name); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, constraint->name_index); - obj_skin_strings_push_back_check(strings, constraint->source_node_name); + ex_node_name, constraint->node_name); + obj_skin_strings_push_back_check(strings, constraint->src_name); switch (constraint->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: obj_skin_strings_push_back_check(strings, "Orientation"); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: obj_skin_strings_push_back_check(strings, "Direction"); obj_skin_strings_push_back_check(strings, constraint->direction->up_vector.name); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: obj_skin_strings_push_back_check(strings, "Position"); obj_skin_strings_push_back_check(strings, constraint->position->up_vector.name); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: obj_skin_strings_push_back_check(strings, "Distance"); obj_skin_strings_push_back_check(strings, constraint->distance->up_vector.name); break; @@ -2003,52 +2008,52 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) obj_skin_strings_push_back_check(strings, "CNS"); obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, constraint->name_index); + ex_node_name, constraint->node_name); } break; - case OBJ_SKIN_BLOCK_EXPRESSION: { - obj_skin_block_expression* expression = block->expression; - for (int32_t j = 0; j < expression->num_expression; j++) - obj_skin_strings_push_back_check(strings, expression->expression_array[j]); - obj_skin_strings_push_back_check(strings, expression->node.parent_name); + case OBJ_SKIN_EX_NODE_EXPRESSION: { + obj_skin_ex_node_expression* expression = ex_node->expression; + for (int32_t j = 0; j < expression->nb_src; j++) + obj_skin_strings_push_back_check(strings, expression->script[j]); + obj_skin_strings_push_back_check(strings, expression->transform.parent_name); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, expression->name_index); + ex_node_name, expression->node_name); obj_skin_strings_push_back_check(strings, "EXP"); obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, expression->name_index); + ex_node_name, expression->node_name); } break; - case OBJ_SKIN_BLOCK_MOTION: { - obj_skin_block_motion* motion = block->motion; - obj_skin_strings_push_back_check(strings, motion->node.parent_name); + case OBJ_SKIN_EX_NODE_MOTION: { + obj_skin_ex_node_motion* motion = ex_node->motion; + obj_skin_strings_push_back_check(strings, motion->transform.parent_name); obj_skin_strings_push_back_check(strings, motion->name); for (int32_t j = 0; j < motion->num_node; j++) obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, motion->node_array[j].name_index); + ex_node_name, motion->node_array[j].node_name); obj_skin_strings_push_back_check(strings, "MOT"); obj_skin_strings_push_back_check(bone_names, motion->name); for (int32_t j = 0; j < motion->num_node; j++) obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, motion->node_array[j].name_index); + ex_node_name, motion->node_array[j].node_name); } break; - case OBJ_SKIN_BLOCK_OSAGE: { - obj_skin_block_osage* osage = block->osage; - obj_skin_strings_push_back_check(strings, osage->node.parent_name); + case OBJ_SKIN_EX_NODE_OSAGE: { + obj_skin_ex_node_osage* osage = ex_node->osage; + obj_skin_strings_push_back_check(strings, osage->transform.parent_name); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage->end_name_index); + ex_node_name, osage->efc_idx); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage->name_index); - for (int32_t j = 0; j < osage->count; j++) { - obj_skin_osage_node* osage_node = &ex->osage_node_array[j]; + ex_node_name, osage->root_idx); + for (uint32_t j = 0; j < osage->nb_joint; j++) { + obj_skin_osage_joint* joint = &ex->osage_joint[j]; obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage_node->name_index); + ex_node_name, joint->nid); - int32_t end_name_index = osage->end_name_index; - obj_skin_osage_sibling_info* osage_sibling_info = ex->osage_sibling_info_array; - for (int32_t k = 0; k < ex->num_osage_sibling_info; k++) { - if (end_name_index == osage_sibling_info->name_index) { + int32_t efc_idx = osage->efc_idx; + obj_skin_osage_constraint_info* osage_sibling_info = ex->osage_constraint_tbl; + for (int32_t k = 0; k < ex->num_osage_constraint; k++) { + if (efc_idx == osage_sibling_info->dst_joint) { obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage_sibling_info->sibling_name_index); + ex_node_name, osage_sibling_info->src_joint); break; } osage_sibling_info++; @@ -2060,35 +2065,35 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) obj_skin_strings_push_back_check(strings, "OSG"); obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage->name_index); - for (int32_t j = 0; j < osage->count; j++) { - obj_skin_osage_node* osage_node = &ex->osage_node_array[j]; + ex_node_name, osage->root_idx); + for (uint32_t j = 0; j < osage->nb_joint; j++) { + obj_skin_osage_joint* joint = &ex->osage_joint[j]; obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage_node->name_index); + ex_node_name, joint->nid); - int32_t end_name_index = osage->end_name_index; - obj_skin_osage_sibling_info* osage_sibling_info = ex->osage_sibling_info_array; - for (int32_t k = 0; k < ex->num_osage_sibling_info; k++) { - if (end_name_index == osage_sibling_info->name_index) { + int32_t efc_idx = osage->efc_idx; + obj_skin_osage_constraint_info* osage_sibling_info = ex->osage_constraint_tbl; + for (int32_t k = 0; k < ex->num_osage_constraint; k++) { + if (efc_idx == osage_sibling_info->dst_joint) { obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage_sibling_info->sibling_name_index); + ex_node_name, osage_sibling_info->src_joint); break; } osage_sibling_info++; } } - obj_skin_osage_node* child_osage_node = &ex->osage_node_array[osage->start_index]; - for (int32_t j = 0; j < osage->count; j++) { + obj_skin_osage_joint* child_osage_node = &ex->osage_joint[osage->joint_ofs]; + for (uint32_t j = 0; j < osage->nb_joint; j++) { obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, child_osage_node->name_index); + ex_node_name, child_osage_node->nid); - int32_t name_index = child_osage_node->name_index; - obj_skin_osage_sibling_info* osage_sibling_info = ex->osage_sibling_info_array; - for (int32_t k = 0; k < ex->num_osage_sibling_info; k++) { - if (name_index == osage_sibling_info->name_index) { + int32_t node_name = child_osage_node->nid; + obj_skin_osage_constraint_info* osage_sibling_info = ex->osage_constraint_tbl; + for (int32_t k = 0; k < ex->num_osage_constraint; k++) { + if (node_name == osage_sibling_info->dst_joint) { obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage_sibling_info->sibling_name_index); + ex_node_name, osage_sibling_info->src_joint); break; } osage_sibling_info++; @@ -2096,7 +2101,7 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) child_osage_node++; } obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage->end_name_index); + ex_node_name, osage->efc_idx); if (osage->skin_param) obj_skin_strings_push_back_check(strings, osage->skin_param->name); @@ -2104,15 +2109,15 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) } } - exh.num_bone_name = (int32_t)bone_names.size(); - exh.bone_name_array_offset = s.get_position(); + exh.nb_node_name = (int32_t)bone_names.size(); + exh.ex_node_name_offset = s.get_position(); for (string_hash& i : bone_names) s.write_int32_t(0); s.align_write(0x10); - if (ex->num_block > 0) { - exh.block_array_offset = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { + if (ex->num_ex_node > 0) { + exh.ex_node_array_offset = s.get_position(); + for (int32_t i = 0; i < ex->num_ex_node; i++) { s.write_int32_t(0); s.write_int32_t(0); } @@ -2120,84 +2125,84 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) s.write_int32_t(0); s.align_write(0x10); - bhs = force_malloc(ex->num_block); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_OSAGE) + bhs = force_malloc(ex->num_ex_node); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_OSAGE) continue; - obj_skin_block_osage* osage = block->osage; + obj_skin_ex_node_osage* osage = ex_node->osage; if (osage->skin_param) { obj_skin_skin_param* skin_param = osage->skin_param; - if (skin_param->coli) { - s.write(0x28ULL * skin_param->coli_count); + if (skin_param->coli_array) { + s.write(0x28ULL * skin_param->num_coli); s.align_write(0x10); } s.write(0x38); s.align_write(0x10); } - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); s.write(0x28); s.write(0x14); s.write(0x14); } s.align_write(0x10); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_EXPRESSION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_EXPRESSION) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); s.write(0x28); s.write(0x2C); } s.align_write(0x10); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; - if (cloth->skin_param) { - obj_skin_skin_param* skin_param = cloth->skin_param; - if (skin_param->coli) { - s.write(0x28ULL * skin_param->coli_count); + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + if (cloth->param) { + obj_skin_skin_param* param = cloth->param; + if (param->coli_array) { + s.write(0x28ULL * param->num_coli); s.align_write(0x10); } s.write(0x38); s.align_write(0x10); } - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); s.write(0x34); } s.align_write(0x10); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CONSTRAINT) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CONSTRAINT) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); s.write(0x28); s.write(0x10); - switch (block->constraint->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + switch (ex_node->constraint->type) { + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: s.write(0x0C); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: s.write(0x24); s.write(0x18); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: s.write(0x24); s.write(0x14); s.write(0x14); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: s.write(0x24); s.write(0x04); s.write(0x14); @@ -2207,111 +2212,111 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) } s.align_write(0x10); - int32_t motion_block_count = 0; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + int32_t motion_ex_node_count = 0; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); s.write(0x28); s.write(0x10); - motion_block_count++; + motion_ex_node_count++; } s.align_write(0x10); - if (exh.num_osage) { - osage_block_node = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_OSAGE) + if (exh.nb_root) { + osage_ex_node_transform = s.get_position(); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_OSAGE) continue; - obj_skin_block_osage* osage = block->osage; - s.write(osage->num_node * (sizeof(uint32_t) + sizeof(float_t) * 4)); + obj_skin_ex_node_osage* osage = ex_node->osage; + s.write(osage->num_joint_rotation* (sizeof(uint32_t) + sizeof(float_t) * 4)); } s.align_write(0x10); } - if (motion_block_count) { - motion_block_node_mats = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + if (motion_ex_node_count) { + motion_ex_node_transform_mats = s.get_position(); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - obj_skin_block_motion* motion = block->motion; + obj_skin_ex_node_motion* motion = ex_node->motion; s.write(motion->num_node * sizeof(mat4)); } s.align_write(0x10); - motion_block_node_name_offset = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + motion_ex_node_transform_name_offset = s.get_position(); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - obj_skin_block_motion* motion = block->motion; + obj_skin_ex_node_motion* motion = ex_node->motion; s.write(motion->num_node * sizeof(uint32_t)); } s.align_write(0x10); } - if (exh.cloth_count) { + if (exh.nb_cloth) { cloth_mats = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; + obj_skin_ex_node_cloth* cloth = ex_node->cloth; if (cloth->mat_array) s.write(cloth->num_mat * sizeof(mat4)); } s.align_write(0x10); cloth_root = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; + obj_skin_ex_node_cloth* cloth = ex_node->cloth; s.write((sizeof(int32_t) + 4 * (sizeof(int32_t) + 3 * sizeof(int32_t))) - * cloth->num_root * (cloth->num_node - 1ULL)); + * cloth->width * (cloth->height - 1ULL)); } s.align_write(0x10); cloth_nodes = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; - s.write((11 * sizeof(int32_t)) * cloth->num_root * (cloth->num_node - 1ULL)); + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + s.write((11 * sizeof(int32_t)) * cloth->width * (cloth->height - 1ULL)); } s.align_write(0x10); cloth_mesh_indices = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; - s.write(sizeof(uint16_t) + cloth->num_mesh_index * sizeof(uint16_t)); + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + s.write(sizeof(uint16_t) + cloth->num_omote_index * sizeof(uint16_t)); } s.align_write(0x10); cloth_backface_mesh_indices = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; - s.write(sizeof(uint16_t) + cloth->num_backface_mesh_index * sizeof(uint16_t)); + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + s.write(sizeof(uint16_t) + cloth->num_ura_index * sizeof(uint16_t)); } s.align_write(0x10); } @@ -2338,14 +2343,14 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) int64_t mot_offset = obj_skin_strings_get_string_offset(strings, string_offsets, "MOT"); int64_t osg_offset = obj_skin_strings_get_string_offset(strings, string_offsets, "OSG"); - if (ex->num_block > 0) { - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + if (ex->num_ex_node > 0) { + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_classic_write_skin_block_cloth(block->cloth, + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_classic_write_skin_ex_node_cloth(ex_node->cloth, s, strings, string_offsets, &cloth_mats, &cloth_root, &cloth_nodes, &cloth_mesh_indices, &cloth_backface_mesh_indices); s.position_pop(); @@ -2361,88 +2366,88 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) constraint_type_name_offsets[3] = obj_skin_strings_get_string_offset(strings, string_offsets, "Distance"); - const char** bone_name_array = ex->bone_name_array; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CONSTRAINT) + const char** ex_node_name = ex->ex_node_name; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CONSTRAINT) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_classic_write_skin_block_constraint(block->constraint, - s, strings, string_offsets, bone_name_array, constraint_type_name_offsets); + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_classic_write_skin_ex_node_constraint(ex_node->constraint, + s, strings, string_offsets, ex_node_name, constraint_type_name_offsets); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_EXPRESSION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_EXPRESSION) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_classic_write_skin_block_expression(block->expression, - s, strings, string_offsets, bone_name_array); + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_classic_write_skin_ex_node_expression(ex_node->expression, + s, strings, string_offsets, ex_node_name); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_classic_write_skin_block_motion(block->motion, - s, strings, string_offsets, bone_name_array, - &motion_block_node_name_offset, &motion_block_node_mats); + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_classic_write_skin_ex_node_motion(ex_node->motion, + s, strings, string_offsets, ex_node_name, + &motion_ex_node_transform_name_offset, &motion_ex_node_transform_mats); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_OSAGE) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_OSAGE) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_classic_write_skin_block_osage(block->osage, - s, strings, string_offsets, &osage_block_node); + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_classic_write_skin_ex_node_osage(ex_node->osage, + s, strings, string_offsets, &osage_ex_node_transform); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type == OBJ_SKIN_BLOCK_CLOTH) { - obj_skin_block_cloth* cloth = block->cloth; - obj_skin_strings_push_back_check(osage_names, cloth->mesh_name); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type == OBJ_SKIN_EX_NODE_CLOTH) { + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + obj_skin_strings_push_back_check(osage_names, cloth->omote_name); } - else if (block->type == OBJ_SKIN_BLOCK_OSAGE) { - obj_skin_block_osage* osage = block->osage; + else if (ex_node->type == OBJ_SKIN_EX_NODE_OSAGE) { + obj_skin_ex_node_osage* osage = ex_node->osage; obj_skin_strings_push_back_check_by_index(osage_names, - bone_name_array, osage->name_index); + ex_node_name, osage->root_idx); } } - s.position_push(exh.block_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - switch (block->type) { - case OBJ_SKIN_BLOCK_CLOTH: + s.position_push(exh.ex_node_array_offset, SEEK_SET); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + switch (ex_node->type) { + case OBJ_SKIN_EX_NODE_CLOTH: s.write_uint32_t((uint32_t)cls_offset); - s.write_uint32_t((uint32_t)bhs[i].block_offset); + s.write_uint32_t((uint32_t)bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_CONSTRAINT: + case OBJ_SKIN_EX_NODE_CONSTRAINT: s.write_uint32_t((uint32_t)cns_offset); - s.write_uint32_t((uint32_t)bhs[i].block_offset); + s.write_uint32_t((uint32_t)bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_EXPRESSION: + case OBJ_SKIN_EX_NODE_EXPRESSION: s.write_uint32_t((uint32_t)exp_offset); - s.write_uint32_t((uint32_t)bhs[i].block_offset); + s.write_uint32_t((uint32_t)bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_MOTION: + case OBJ_SKIN_EX_NODE_MOTION: s.write_uint32_t((uint32_t)mot_offset); - s.write_uint32_t((uint32_t)bhs[i].block_offset); + s.write_uint32_t((uint32_t)bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_OSAGE: + case OBJ_SKIN_EX_NODE_OSAGE: s.write_uint32_t((uint32_t)osg_offset); - s.write_uint32_t((uint32_t)bhs[i].block_offset); + s.write_uint32_t((uint32_t)bhs[i].ex_node_offset); break; default: s.write_uint32_t(0); @@ -2470,8 +2475,8 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) if (sk->ex_data) { obj_skin_ex_data* ex = sk->ex_data; - if (ex->num_block > 0) { - s.position_push(exh.bone_name_array_offset, SEEK_SET); + if (ex->num_ex_node > 0) { + s.position_push(exh.ex_node_name_offset, SEEK_SET); for (string_hash& i : bone_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); @@ -2479,30 +2484,33 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) } s.position_pop(); - s.position_push(exh.osage_node_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_node; i++) { - obj_skin_osage_node* osage_node = &ex->osage_node_array[i]; - s.write_uint32_t(osage_node->name_index); - s.write_float_t(osage_node->length); - s.write_uint32_t(osage_node->name_index & 0x7FFF); + exh.osage_root_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, ex->osage_root); + + s.position_push(exh.osage_joint_offset, SEEK_SET); + for (int32_t i = 0; i < ex->nb_jointX; i++) { + obj_skin_osage_joint* joint = &ex->osage_joint[i]; + s.write_uint32_t(joint->nid); + s.write_float_t(joint->length); + s.write_uint32_t(joint->nid & 0x7FFF); } s.position_pop(); - s.position_push(exh.osage_sibling_info_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_sibling_info; i++) { - obj_skin_osage_sibling_info* osage_sibling_info = &ex->osage_sibling_info_array[i]; - s.write_uint32_t(osage_sibling_info->name_index); - s.write_uint32_t(osage_sibling_info->sibling_name_index); - s.write_float_t(osage_sibling_info->max_distance); + s.position_push(exh.osage_constraint_tbl_offset, SEEK_SET); + for (int32_t i = 0; i < ex->num_osage_constraint; i++) { + obj_skin_osage_constraint_info* osage_sibling_info = &ex->osage_constraint_tbl[i]; + s.write_uint32_t(osage_sibling_info->dst_joint); + s.write_uint32_t(osage_sibling_info->src_joint); + s.write_float_t(osage_sibling_info->length); } s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); s.position_pop(); - exh.num_osage = (int32_t)osage_names.size(); - exh.num_osage -= exh.cloth_count; - s.position_push(exh.osage_name_array_offset, SEEK_SET); + exh.nb_root = (int32_t)osage_names.size(); + exh.nb_root -= exh.nb_cloth; + s.position_push(exh.root_name_offset, SEEK_SET); for (string_hash& i : osage_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); @@ -2512,16 +2520,16 @@ static void obj_classic_write_skin(obj_skin* sk, stream& s, int64_t base_offset) } s.position_push(sh.ex_data_offset, SEEK_SET); - s.write_int32_t(exh.num_osage); - s.write_int32_t(ex->num_osage_node); - s.write(0x04); - s.write_uint32_t((uint32_t)exh.osage_node_array_offset); - s.write_uint32_t((uint32_t)exh.osage_name_array_offset); - s.write_uint32_t((uint32_t)exh.block_array_offset); - s.write_int32_t(exh.num_bone_name); - s.write_uint32_t((uint32_t)exh.bone_name_array_offset); - s.write_uint32_t((uint32_t)exh.osage_sibling_info_array_offset); - s.write_int32_t(exh.cloth_count); + s.write_int32_t(exh.nb_root); + s.write_int32_t(ex->nb_jointX); + s.write_uint32_t((uint32_t)exh.osage_root_offset); + s.write_uint32_t((uint32_t)exh.osage_joint_offset); + s.write_uint32_t((uint32_t)exh.root_name_offset); + s.write_uint32_t((uint32_t)exh.ex_node_array_offset); + s.write_int32_t(exh.nb_node_name); + s.write_uint32_t((uint32_t)exh.ex_node_name_offset); + s.write_uint32_t((uint32_t)exh.osage_constraint_tbl_offset); + s.write_int32_t(exh.nb_cloth); s.write_uint32_t((uint32_t)ex->reserved[0]); s.write_uint32_t((uint32_t)ex->reserved[1]); s.write_uint32_t((uint32_t)ex->reserved[2]); @@ -2549,16 +2557,16 @@ static obj_skin_ex_data* obj_classic_read_skin_ex_data(prj::shared_ptrnum_osage_node = s.read_int32_t(); - s.read(0, 0x04); - exh.osage_node_array_offset = s.read_uint32_t(); - exh.osage_name_array_offset = s.read_uint32_t(); - exh.block_array_offset = s.read_uint32_t(); - exh.num_bone_name = s.read_int32_t(); - exh.bone_name_array_offset = s.read_uint32_t(); - exh.osage_sibling_info_array_offset = s.read_uint32_t(); - exh.cloth_count = s.read_int32_t(); + exh.nb_root = s.read_int32_t(); + ex->nb_jointX = s.read_int32_t(); + exh.osage_root_offset = s.read_uint32_t(); + exh.osage_joint_offset = s.read_uint32_t(); + exh.root_name_offset = s.read_uint32_t(); + exh.ex_node_array_offset = s.read_uint32_t(); + exh.nb_node_name = s.read_int32_t(); + exh.ex_node_name_offset = s.read_uint32_t(); + exh.osage_constraint_tbl_offset = s.read_uint32_t(); + exh.nb_cloth = s.read_int32_t(); ex->reserved[0] = s.read_uint32_t(); ex->reserved[1] = s.read_uint32_t(); ex->reserved[2] = s.read_uint32_t(); @@ -2567,185 +2575,187 @@ static obj_skin_ex_data* obj_classic_read_skin_ex_data(prj::shared_ptrreserved[5] = s.read_uint32_t(); ex->reserved[6] = s.read_uint32_t(); - ex->bone_name_array = 0; - ex->num_bone_name = 0; - if (!exh.bone_name_array_offset) + ex->ex_node_name = 0; + ex->nb_node_name = 0; + if (!exh.ex_node_name_offset) return ex; - int32_t num_bone_name = exh.num_bone_name; - const char** bone_name_array = alloc->allocate(num_bone_name); - if (!bone_name_array) + int32_t nb_node_name = exh.nb_node_name; + const char** ex_node_name = alloc->allocate(nb_node_name); + if (!ex_node_name) return ex; - ex->bone_name_array = bone_name_array; - ex->num_bone_name = num_bone_name; + ex->ex_node_name = ex_node_name; + ex->nb_node_name = nb_node_name; - s.set_position(exh.bone_name_array_offset, SEEK_SET); - for (int32_t i = 0; i < num_bone_name; i++) { + s.set_position(exh.ex_node_name_offset, SEEK_SET); + for (int32_t i = 0; i < nb_node_name; i++) { int32_t string_offset = s.read_uint32_t(); if (string_offset) - bone_name_array[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, string_offset); + ex_node_name[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, string_offset); else - bone_name_array[i] = 0; + ex_node_name[i] = 0; } - if (exh.osage_node_array_offset) { - ex->osage_node_array = alloc->allocate(ex->num_osage_node); + if (exh.osage_root_offset) + ex->osage_root = obj_read_utf8_string_null_terminated_offset(alloc, s, exh.osage_root_offset); + else + ex->osage_root = 0; - s.set_position(exh.osage_node_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_node; i++) { - obj_skin_osage_node* osage_node = &ex->osage_node_array[i]; + if (exh.osage_joint_offset) { + ex->osage_joint = alloc->allocate(ex->nb_jointX); - osage_node->name_index = s.read_uint32_t(); - osage_node->length = s.read_float_t(); + s.set_position(exh.osage_joint_offset, SEEK_SET); + for (int32_t i = 0; i < ex->nb_jointX; i++) { + obj_skin_osage_joint* joint = &ex->osage_joint[i]; + + joint->nid = s.read_uint32_t(); + joint->length = s.read_float_t(); s.read(0, 0x04); } } - if (exh.block_array_offset) { - ex->num_block = 0; - s.set_position(exh.block_array_offset, SEEK_SET); + if (exh.ex_node_array_offset) { + ex->num_ex_node = 0; + s.set_position(exh.ex_node_array_offset, SEEK_SET); while (s.read_uint32_t()) { s.read(0, 0x04); - ex->num_block++; + ex->num_ex_node++; } - obj_skin_block_header* bhs = force_malloc(ex->num_block); - s.set_position(exh.block_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_block; i++) { - bhs[i].block_signature_offset = s.read_uint32_t(); - bhs[i].block_offset = s.read_uint32_t(); + obj_skin_ex_node_header* bhs = force_malloc(ex->num_ex_node); + s.set_position(exh.ex_node_array_offset, SEEK_SET); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + bhs[i].ex_node_signature_offset = s.read_uint32_t(); + bhs[i].ex_node_offset = s.read_uint32_t(); } - ex->block_array = alloc->allocate(ex->num_block); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; + ex->ex_node_table = alloc->allocate(ex->num_ex_node); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; - std::string block_signature = s.read_string_null_terminated_offset( - bhs[i].block_signature_offset); - if (block_signature.size() != 3) + std::string ex_node_signature = s.read_string_null_terminated_offset( + bhs[i].ex_node_signature_offset); + if (ex_node_signature.size() != 3) continue; - uint32_t signature = load_reverse_endianness_uint32_t(block_signature.c_str()); + uint32_t signature = load_reverse_endianness_uint32_t(ex_node_signature.c_str()); switch (signature) { case 'CLS\0': - block->type = OBJ_SKIN_BLOCK_CLOTH; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->cloth = obj_classic_read_skin_block_cloth( - alloc, s, bone_name_array); + ex_node->type = OBJ_SKIN_EX_NODE_CLOTH; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->cloth = obj_classic_read_skin_ex_node_cloth( + alloc, s, ex_node_name); break; case 'CNS\0': - block->type = OBJ_SKIN_BLOCK_CONSTRAINT; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->constraint = obj_classic_read_skin_block_constraint( - alloc, s, bone_name_array); + ex_node->type = OBJ_SKIN_EX_NODE_CONSTRAINT; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->constraint = obj_classic_read_skin_ex_node_constraint( + alloc, s, ex_node_name); break; case 'EXP\0': - block->type = OBJ_SKIN_BLOCK_EXPRESSION; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->expression = obj_classic_read_skin_block_expression( - alloc, s, bone_name_array); + ex_node->type = OBJ_SKIN_EX_NODE_EXPRESSION; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->expression = obj_classic_read_skin_ex_node_expression( + alloc, s, ex_node_name); break; case 'MOT\0': - block->type = OBJ_SKIN_BLOCK_MOTION; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->motion = obj_classic_read_skin_block_motion( - alloc, s, bone_name_array); + ex_node->type = OBJ_SKIN_EX_NODE_MOTION; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->motion = obj_classic_read_skin_ex_node_motion( + alloc, s, ex_node_name); break; case 'OSG\0': - block->type = OBJ_SKIN_BLOCK_OSAGE; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->osage = obj_classic_read_skin_block_osage( - alloc, s, bone_name_array); + ex_node->type = OBJ_SKIN_EX_NODE_OSAGE; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->osage = obj_classic_read_skin_ex_node_osage( + alloc, s, ex_node_name); break; } } free_def(bhs); } - if (exh.osage_sibling_info_array_offset) { - ex->num_osage_sibling_info = 0; - s.set_position(exh.osage_sibling_info_array_offset, SEEK_SET); + if (exh.osage_constraint_tbl_offset) { + ex->num_osage_constraint = 0; + s.set_position(exh.osage_constraint_tbl_offset, SEEK_SET); while (s.read_uint32_t()) { s.read(0, 0x08); - ex->num_osage_sibling_info++; + ex->num_osage_constraint++; } - obj_skin_osage_sibling_info* osi = alloc->allocate< - obj_skin_osage_sibling_info>(ex->num_osage_sibling_info); - ex->osage_sibling_info_array = osi; - s.set_position(exh.osage_sibling_info_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_sibling_info; i++, osi++) { - osi->name_index = s.read_uint32_t(); - osi->sibling_name_index = s.read_uint32_t(); - osi->max_distance = s.read_float_t(); + obj_skin_osage_constraint_info* osi = alloc->allocate< + obj_skin_osage_constraint_info>(ex->num_osage_constraint); + ex->osage_constraint_tbl = osi; + s.set_position(exh.osage_constraint_tbl_offset, SEEK_SET); + for (int32_t i = 0; i < ex->num_osage_constraint; i++, osi++) { + osi->dst_joint = s.read_uint32_t(); + osi->src_joint = s.read_uint32_t(); + osi->length = s.read_float_t(); } } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_OSAGE) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_OSAGE) continue; - obj_skin_block_osage* osage = block->osage; - if (!osage->node_array) + obj_skin_ex_node_osage* osage = ex_node->osage; + if (!osage->joint_rotation_array) continue; - int32_t count = osage->count; - obj_skin_osage_node* child_osage_node = &ex->osage_node_array[osage->start_index]; - obj_skin_osage_node* osage_node = osage->node_array; - for (int32_t j = 0; j < count; j++) { - osage_node->name_index = child_osage_node->name_index; - osage_node->length = child_osage_node->length; - - child_osage_node++; - osage_node++; + uint32_t count = osage->nb_joint; + const obj_skin_osage_joint* joint = &ex->osage_joint[osage->joint_ofs]; + obj_skin_osage_joint_rotation* node = osage->joint_rotation_array; + for (uint32_t j = 0; j < count; j++, joint++, node++) { + node->nid = joint->nid; + node->length = joint->length; } } return ex; } -static obj_skin_block_cloth* obj_classic_read_skin_block_cloth( +static obj_skin_ex_node_cloth* obj_classic_read_skin_ex_node_cloth( prj::shared_ptr alloc, stream& s, const char** str) { - obj_skin_block_cloth* cls = alloc->allocate(); - uint32_t mesh_name_offset = s.read_uint32_t(); - uint32_t backface_mesh_name_offset = s.read_uint32_t(); - cls->field_8 = s.read_uint32_t(); - cls->num_root = s.read_int32_t(); - cls->num_node = s.read_int32_t(); - cls->loop = s.read_uint32_t(); - uint32_t mat_array_offset = s.read_uint32_t(); - uint32_t root_array_offset = s.read_uint32_t(); - uint32_t node_array_offset = s.read_uint32_t(); - uint32_t mesh_index_array_offset = s.read_uint32_t(); - uint32_t backface_mesh_index_array_offset = s.read_uint32_t(); - uint32_t skin_param_offset = s.read_uint32_t(); - cls->reserved = s.read_uint32_t(); + obj_skin_ex_node_cloth* cls = alloc->allocate(); + uint32_t omote_name_offset = s.read_uint32_t(); + uint32_t ura_name_offset = s.read_uint32_t(); + cls->version = s.read_uint32_t(); + cls->width = s.read_uint32_t(); + cls->height = s.read_uint32_t(); + cls->ring_flag = s.read_uint32_t(); + uint32_t matrix_offset = s.read_uint32_t(); + uint32_t fix_point_offset = s.read_uint32_t(); + uint32_t move_point_offset = s.read_uint32_t(); + uint32_t omote_index_array_offset = s.read_uint32_t(); + uint32_t ura_index_array_offset = s.read_uint32_t(); + uint32_t param_offset = s.read_uint32_t(); + cls->dummy = s.read_uint32_t(); - cls->mesh_name = obj_read_utf8_string_null_terminated_offset(alloc, s, mesh_name_offset); - cls->backface_mesh_name = obj_read_utf8_string_null_terminated_offset(alloc, s, backface_mesh_name_offset); + cls->omote_name = obj_read_utf8_string_null_terminated_offset(alloc, s, omote_name_offset); + cls->ura_name = obj_read_utf8_string_null_terminated_offset(alloc, s, ura_name_offset); - if (mat_array_offset) { - int32_t max_matrix_index = -1; + if (matrix_offset) { + int32_t max_mat_idx = -1; - s.position_push(root_array_offset, SEEK_SET); - for (int32_t i = 0; i < cls->num_root; i++) { + s.position_push(fix_point_offset, SEEK_SET); + for (uint32_t i = 0; i < cls->width; i++) { s.read(0x28); for (uint32_t j = 0; j < 4; j++) { uint32_t name_offset = s.read_uint32_t(); s.read(0x04); - int32_t matrix_index = s.read_int32_t(); + int32_t mat_idx = s.read_int32_t(); s.read(0x04); - if (name_offset && max_matrix_index < matrix_index) - max_matrix_index = matrix_index; + if (name_offset && max_mat_idx < mat_idx) + max_mat_idx = mat_idx; } } s.position_pop(); - cls->num_mat = max_matrix_index > -1 ? max_matrix_index + 1 : 0; + cls->num_mat = max_mat_idx > -1 ? max_mat_idx + 1 : 0; cls->mat_array = alloc->allocate(cls->num_mat); - s.position_push(mat_array_offset, SEEK_SET); - for (int32_t i = 0; i < cls->num_mat; i++) { + s.position_push(matrix_offset, SEEK_SET); + for (uint32_t i = 0; i < cls->num_mat; i++) { mat4& mat = cls->mat_array[i]; mat.row0.x = s.read_float_t(); mat.row1.x = s.read_float_t(); @@ -2767,89 +2777,89 @@ static obj_skin_block_cloth* obj_classic_read_skin_block_cloth( s.position_pop(); } - if (root_array_offset) { - s.position_push(root_array_offset, SEEK_SET); - cls->root_array = alloc->allocate(cls->num_root); - for (int32_t i = 0; i < cls->num_root; i++) - obj_classic_read_skin_block_cloth_root(&cls->root_array[i], alloc, s, str); + if (fix_point_offset) { + s.position_push(fix_point_offset, SEEK_SET); + cls->fix_point = alloc->allocate(cls->width); + for (uint32_t i = 0; i < cls->width; i++) + obj_classic_read_skin_ex_node_cloth_root(&cls->fix_point[i], alloc, s, str); s.position_pop(); } - if (node_array_offset) { - s.position_push(node_array_offset, SEEK_SET); - cls->node_array = alloc->allocate( - cls->num_root * (cls->num_node - 1ULL)); - for (int32_t i = 0; i < cls->num_node - 1; i++) - for (int32_t j = 0; j < cls->num_root; j++) { - obj_skin_block_cloth_node* f = &cls->node_array[i * cls->num_root + j]; - f->flags = s.read_uint32_t(); + if (move_point_offset) { + s.position_push(move_point_offset, SEEK_SET); + cls->move_point = alloc->allocate( + cls->width * (cls->height - 1ULL)); + for (uint32_t i = 0; i < cls->height - 1; i++) + for (uint32_t j = 0; j < cls->width; j++) { + obj_skin_ex_node_cloth_point* f = &cls->move_point[i * cls->width + j]; + f->link_flag = s.read_uint32_t(); f->pos.x = s.read_float_t(); f->pos.y = s.read_float_t(); f->pos.z = s.read_float_t(); - f->delta_pos.x = s.read_float_t(); - f->delta_pos.y = s.read_float_t(); - f->delta_pos.z = s.read_float_t(); - f->dist_top = s.read_float_t(); - f->dist_bottom = s.read_float_t(); - f->dist_right = s.read_float_t(); - f->dist_left = s.read_float_t(); + f->vec.x = s.read_float_t(); + f->vec.y = s.read_float_t(); + f->vec.z = s.read_float_t(); + f->length[0] = s.read_float_t(); + f->length[1] = s.read_float_t(); + f->length[2] = s.read_float_t(); + f->length[3] = s.read_float_t(); } s.position_pop(); } - if (mesh_index_array_offset) { - s.position_push(mesh_index_array_offset, SEEK_SET); - cls->num_mesh_index = s.read_uint16_t_reverse_endianness(); - cls->mesh_index_array = alloc->allocate(cls->num_mesh_index); - s.read(cls->mesh_index_array, cls->num_mesh_index * sizeof(uint16_t)); + if (omote_index_array_offset) { + s.position_push(omote_index_array_offset, SEEK_SET); + cls->num_omote_index = s.read_uint16_t_reverse_endianness(); + cls->omote_index_array = alloc->allocate(cls->num_omote_index); + s.read(cls->omote_index_array, cls->num_omote_index * sizeof(uint16_t)); s.position_pop(); } - if (backface_mesh_index_array_offset) { - s.position_push(backface_mesh_index_array_offset, SEEK_SET); - cls->num_backface_mesh_index = s.read_uint16_t_reverse_endianness(); - cls->backface_mesh_index_array = alloc->allocate(cls->num_backface_mesh_index); - s.read(cls->backface_mesh_index_array, cls->num_backface_mesh_index * sizeof(uint16_t)); + if (ura_index_array_offset) { + s.position_push(ura_index_array_offset, SEEK_SET); + cls->num_ura_index = s.read_uint16_t_reverse_endianness(); + cls->ura_index_array = alloc->allocate(cls->num_ura_index); + s.read(cls->ura_index_array, cls->num_ura_index * sizeof(uint16_t)); s.position_pop(); } - if (skin_param_offset) - cls->skin_param = obj_classic_read_skin_param(alloc, s, str); + if (param_offset) + cls->param = obj_classic_read_skin_param(alloc, s, str); return cls; } -static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* cls, +static void obj_classic_write_skin_ex_node_cloth(obj_skin_ex_node_cloth* cls, stream& s, std::vector& strings, std::vector& string_offsets, - int64_t* mat_array_offset, int64_t* root_array_offset, int64_t* node_array_offset, - int64_t* mesh_index_array_offset, int64_t* backface_mesh_index_array_offset) { - int64_t skin_param_offset = 0; - if (cls->skin_param) { - skin_param_offset = s.get_position(); - obj_classic_write_skin_param(cls->skin_param, s, strings, string_offsets); + int64_t* matrix_offset, int64_t* fix_point_offset, int64_t* move_point_offset, + int64_t* omote_index_array_offset, int64_t* ura_index_array_offset) { + int64_t param_offset = 0; + if (cls->param) { + param_offset = s.get_position(); + obj_classic_write_skin_param(cls->param, s, strings, string_offsets); } - int64_t mesh_name_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, cls->mesh_name); - int64_t backface_mesh_name_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, cls->backface_mesh_name); + int64_t omote_name_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, cls->omote_name); + int64_t ura_name_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, cls->ura_name); - s.write_uint32_t((uint32_t)mesh_name_offset); - s.write_uint32_t((uint32_t)backface_mesh_name_offset); - s.write_int32_t(cls->field_8); - s.write_int32_t(cls->num_root); - s.write_int32_t(cls->num_node); - s.write_int32_t(cls->loop); - s.write_uint32_t((uint32_t)*mat_array_offset); - s.write_uint32_t((uint32_t)*root_array_offset); - s.write_uint32_t((uint32_t)*node_array_offset); - s.write_uint32_t((uint32_t)*mesh_index_array_offset); - s.write_uint32_t((uint32_t)*backface_mesh_index_array_offset); - s.write_uint32_t((uint32_t)skin_param_offset); - s.write_uint32_t(cls->reserved); + s.write_uint32_t((uint32_t)omote_name_offset); + s.write_uint32_t((uint32_t)ura_name_offset); + s.write_int32_t(cls->version); + s.write_int32_t(cls->width); + s.write_int32_t(cls->height); + s.write_int32_t(cls->ring_flag); + s.write_uint32_t((uint32_t)*matrix_offset); + s.write_uint32_t((uint32_t)*fix_point_offset); + s.write_uint32_t((uint32_t)*move_point_offset); + s.write_uint32_t((uint32_t)*omote_index_array_offset); + s.write_uint32_t((uint32_t)*ura_index_array_offset); + s.write_uint32_t((uint32_t)param_offset); + s.write_uint32_t(cls->dummy); if (cls->mat_array) { - s.position_push(*mat_array_offset, SEEK_SET); - for (int32_t i = 0; i < cls->num_mat; i++) { + s.position_push(*matrix_offset, SEEK_SET); + for (uint32_t i = 0; i < cls->num_mat; i++) { mat4& mat = cls->mat_array[i]; s.write_float_t(mat.row0.x); s.write_float_t(mat.row1.x); @@ -2867,65 +2877,65 @@ static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* cls, s.write_float_t(mat.row1.w); s.write_float_t(mat.row2.w); s.write_float_t(mat.row3.w); - *mat_array_offset += sizeof(mat4); + *matrix_offset += sizeof(mat4); } s.position_pop(); } - if (cls->root_array) { - s.position_push(*root_array_offset, SEEK_SET); - int32_t num_root = cls->num_root; - obj_skin_block_cloth_root* root_array = cls->root_array; - for (int32_t i = 0; i < num_root; i++) - obj_classic_write_skin_block_cloth_root(&root_array[i], + if (cls->fix_point) { + s.position_push(*fix_point_offset, SEEK_SET); + uint32_t width = cls->width; + obj_skin_ex_node_cloth_root* fix_point = cls->fix_point; + for (uint32_t i = 0; i < width; i++) + obj_classic_write_skin_ex_node_cloth_root(&fix_point[i], s, strings, string_offsets); s.position_pop(); - *root_array_offset += (sizeof(int32_t) + 4 * (sizeof(int32_t) + 3 * sizeof(int32_t))) - * cls->num_root * (cls->num_node - 1ULL); + *fix_point_offset += (sizeof(int32_t) + 4 * (sizeof(int32_t) + 3 * sizeof(int32_t))) + * cls->width * (cls->height - 1ULL); } - if (cls->node_array) { - s.position_push(*node_array_offset, SEEK_SET); - int32_t num_root = cls->num_root; - int32_t num_node = cls->num_node; - obj_skin_block_cloth_node* node_array = cls->node_array; - for (int32_t i = 0; i < num_node - 1; i++) - for (int32_t j = 0; j < num_root; j++) { - obj_skin_block_cloth_node* f = &node_array[i * cls->num_root + j]; - s.write_uint32_t(f->flags); + if (cls->move_point) { + s.position_push(*move_point_offset, SEEK_SET); + uint32_t width = cls->width; + uint32_t height = cls->height; + obj_skin_ex_node_cloth_point* move_point = cls->move_point; + for (uint32_t i = 1; i < height; i++) + for (uint32_t j = 0; j < width; j++) { + obj_skin_ex_node_cloth_point* f = &move_point[i * cls->width + j]; + s.write_uint32_t(f->link_flag); s.write_float_t(f->pos.x); s.write_float_t(f->pos.y); s.write_float_t(f->pos.z); - s.write_float_t(f->delta_pos.x); - s.write_float_t(f->delta_pos.y); - s.write_float_t(f->delta_pos.z); - s.write_float_t(f->dist_top); - s.write_float_t(f->dist_bottom); - s.write_float_t(f->dist_right); - s.write_float_t(f->dist_left); + s.write_float_t(f->vec.x); + s.write_float_t(f->vec.y); + s.write_float_t(f->vec.z); + s.write_float_t(f->length[0]); + s.write_float_t(f->length[1]); + s.write_float_t(f->length[2]); + s.write_float_t(f->length[3]); } s.position_pop(); - *node_array_offset += (11 * sizeof(int32_t)) * cls->num_root * (cls->num_node - 1ULL); + *move_point_offset += (11 * sizeof(int32_t)) * cls->width * (cls->height - 1ULL); } - if (cls->mesh_index_array) { - s.position_push(*mesh_index_array_offset, SEEK_SET); - s.write_uint16_t((uint16_t)cls->num_mesh_index); - s.write(cls->mesh_index_array, cls->num_mesh_index * sizeof(uint16_t)); + if (cls->omote_index_array) { + s.position_push(*omote_index_array_offset, SEEK_SET); + s.write_uint16_t((uint16_t)cls->num_omote_index); + s.write(cls->omote_index_array, cls->num_omote_index * sizeof(uint16_t)); s.position_pop(); - *mesh_index_array_offset += sizeof(uint16_t) + cls->num_mesh_index * sizeof(uint16_t); + *omote_index_array_offset += sizeof(uint16_t) + cls->num_omote_index * sizeof(uint16_t); } - if (cls->backface_mesh_index_array) { - s.position_push(*backface_mesh_index_array_offset, SEEK_SET); - s.write_uint16_t((uint16_t)cls->num_backface_mesh_index); - s.write(cls->backface_mesh_index_array, cls->num_backface_mesh_index * sizeof(uint16_t)); + if (cls->ura_index_array) { + s.position_push(*ura_index_array_offset, SEEK_SET); + s.write_uint16_t((uint16_t)cls->num_ura_index); + s.write(cls->ura_index_array, cls->num_ura_index * sizeof(uint16_t)); s.position_pop(); - *backface_mesh_index_array_offset += sizeof(uint16_t) + cls->num_backface_mesh_index * sizeof(uint16_t); + *ura_index_array_offset += sizeof(uint16_t) + cls->num_ura_index * sizeof(uint16_t); } } -static void obj_classic_read_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, +static void obj_classic_read_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, prj::shared_ptr alloc, stream& s, const char** str) { cloth_root->pos.x = s.read_float_t(); cloth_root->pos.y = s.read_float_t(); @@ -2933,17 +2943,17 @@ static void obj_classic_read_skin_block_cloth_root(obj_skin_block_cloth_root* cl cloth_root->normal.x = s.read_float_t(); cloth_root->normal.y = s.read_float_t(); cloth_root->normal.z = s.read_float_t(); - cloth_root->field_18 = s.read_float_t(); - cloth_root->field_1C = s.read_int32_t(); - cloth_root->field_20 = s.read_int32_t(); - cloth_root->field_24 = s.read_int32_t(); + cloth_root->tangent.x = s.read_float_t(); + cloth_root->tangent.y = s.read_float_t(); + cloth_root->tangent.z = s.read_float_t(); + cloth_root->tangent.w = s.read_float_t(); for (uint32_t i = 0; i < 4; i++) - obj_classic_read_skin_block_cloth_root_bone_weight(&cloth_root->bone_weights[i], + obj_classic_read_skin_ex_node_cloth_root_bone_weight(&cloth_root->weight[i], alloc, s, str); } -static void obj_classic_write_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, +static void obj_classic_write_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, stream& s, std::vector& strings, std::vector& string_offsets) { s.write_float_t(cloth_root->pos.x); s.write_float_t(cloth_root->pos.y); @@ -2951,39 +2961,39 @@ static void obj_classic_write_skin_block_cloth_root(obj_skin_block_cloth_root* c s.write_float_t(cloth_root->normal.x); s.write_float_t(cloth_root->normal.y); s.write_float_t(cloth_root->normal.z); - s.write_float_t(cloth_root->field_18); - s.write_int32_t(cloth_root->field_1C); - s.write_int32_t(cloth_root->field_20); - s.write_int32_t(cloth_root->field_24); + s.write_float_t(cloth_root->tangent.x); + s.write_float_t(cloth_root->tangent.y); + s.write_float_t(cloth_root->tangent.z); + s.write_float_t(cloth_root->tangent.w); for (uint32_t j = 0; j < 4; j++) - obj_classic_write_skin_block_cloth_root_bone_weight(&cloth_root->bone_weights[j], + obj_classic_write_skin_ex_node_cloth_root_bone_weight(&cloth_root->weight[j], s, strings, string_offsets); } -static void obj_classic_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_classic_read_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, prj::shared_ptr alloc, stream& s, const char** str) { int32_t bone_name_offset = s.read_uint32_t(); bone_weight->bone_name = obj_read_utf8_string_null_terminated_offset(alloc, s, bone_name_offset); bone_weight->weight = s.read_float_t(); - bone_weight->matrix_index = s.read_uint32_t(); - bone_weight->reserved = s.read_uint32_t(); + bone_weight->mat_idx = s.read_uint32_t(); + bone_weight->dummy = s.read_uint32_t(); } -static void obj_classic_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_classic_write_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, stream& s, std::vector& strings, std::vector& string_offsets) { int64_t bone_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, bone_weight->bone_name); s.write_uint32_t((uint32_t)bone_name_offset); s.write_float_t(bone_weight->weight); - s.write_uint32_t(bone_weight->matrix_index); - s.write_uint32_t(bone_weight->reserved); + s.write_uint32_t(bone_weight->mat_idx); + s.write_uint32_t(bone_weight->dummy); } -static obj_skin_block_constraint* obj_classic_read_skin_block_constraint( +static obj_skin_ex_node_constraint* obj_classic_read_skin_ex_node_constraint( prj::shared_ptr alloc, stream& s, const char** str) { - obj_skin_block_constraint* cns = alloc->allocate(); - obj_classic_read_skin_block_node(&cns->node, alloc, s, str); + obj_skin_ex_node_constraint* cns = alloc->allocate(); + obj_classic_read_skin_ex_node_transform(&cns->transform, alloc, s, str); uint32_t type_offset = s.read_uint32_t(); char* type = s.read_utf8_string_null_terminated_offset(type_offset); @@ -2991,40 +3001,40 @@ static obj_skin_block_constraint* obj_classic_read_skin_block_constraint( uint32_t name_offset = s.read_uint32_t(); char* name = s.read_utf8_string_null_terminated_offset(name_offset); - cns->name_index = 0; + cns->node_name = 0; if (name) for (const char** i = str; *i; i++) if (!str_utils_compare(name, *i)) { - cns->name_index = 0x8000 | (int32_t)(i - str); + cns->node_name = 0x8000 | (int32_t)(i - str); break; } free_def(name); - cns->coupling = (obj_skin_block_constraint_coupling)s.read_uint32_t(); + cns->nb_src = s.read_uint32_t(); - uint32_t source_node_name_offset = s.read_uint32_t(); - cns->source_node_name = obj_read_utf8_string_null_terminated_offset(alloc, s, source_node_name_offset); + uint32_t src_name_offset = s.read_uint32_t(); + cns->src_name = obj_read_utf8_string_null_terminated_offset(alloc, s, src_name_offset); if (!type) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; cns->data = 0; } else if (!str_utils_compare(type, "Orientation")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION; - obj_skin_block_constraint_orientation* orientation - = alloc->allocate(); + obj_skin_ex_node_constraint_orientation* orientation + = alloc->allocate(); orientation->offset.x = s.read_float_t(); orientation->offset.y = s.read_float_t(); orientation->offset.z = s.read_float_t(); cns->orientation = orientation; } else if (!str_utils_compare(type, "Direction")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION; - obj_skin_block_constraint_direction* direction - = alloc->allocate(); - obj_classic_read_skin_block_constraint_up_vector(&direction->up_vector, + obj_skin_ex_node_constraint_direction* direction + = alloc->allocate(); + obj_classic_read_skin_ex_node_constraint_up_vector(&direction->up_vector, alloc, s, str); direction->align_axis.x = s.read_float_t(); direction->align_axis.y = s.read_float_t(); @@ -3035,80 +3045,80 @@ static obj_skin_block_constraint* obj_classic_read_skin_block_constraint( cns->direction = direction; } else if (!str_utils_compare(type, "Position")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_POSITION; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION; - obj_skin_block_constraint_position* position - = alloc->allocate(); - obj_classic_read_skin_block_constraint_up_vector(&position->up_vector, + obj_skin_ex_node_constraint_position* position + = alloc->allocate(); + obj_classic_read_skin_ex_node_constraint_up_vector(&position->up_vector, alloc, s, str); - obj_classic_read_skin_block_constraint_attach_point(&position->constrained_object, + obj_classic_read_skin_ex_node_constraint_attach_point(&position->constrained_object, s, str); - obj_classic_read_skin_block_constraint_attach_point(&position->constraining_object, + obj_classic_read_skin_ex_node_constraint_attach_point(&position->constraining_object, s, str); cns->position = position; } else if (!str_utils_compare(type, "Distance")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE; - obj_skin_block_constraint_distance* distance - = alloc->allocate(); - obj_classic_read_skin_block_constraint_up_vector(&distance->up_vector, + obj_skin_ex_node_constraint_distance* distance + = alloc->allocate(); + obj_classic_read_skin_ex_node_constraint_up_vector(&distance->up_vector, alloc, s, str); distance->distance = s.read_float_t(); - obj_classic_read_skin_block_constraint_attach_point(&distance->constrained_object, + obj_classic_read_skin_ex_node_constraint_attach_point(&distance->constrained_object, s, str); - obj_classic_read_skin_block_constraint_attach_point(&distance->constraining_object, + obj_classic_read_skin_ex_node_constraint_attach_point(&distance->constraining_object, s, str); cns->distance = distance; } else { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; cns->data = 0; } free_def(type); return cns; } -static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* cns, +static void obj_classic_write_skin_ex_node_constraint(obj_skin_ex_node_constraint* cns, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array, int64_t* offsets) { - obj_classic_write_skin_block_node(&cns->node, s, strings, string_offsets); + const char** ex_node_name, int64_t* offsets) { + obj_classic_write_skin_ex_node_transform(&cns->transform, s, strings, string_offsets); int64_t type_offset = 0; switch (cns->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: type_offset = offsets[0]; break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: type_offset = offsets[1]; break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: type_offset = offsets[2]; break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: type_offset = offsets[3]; break; } s.write_uint32_t((uint32_t)type_offset); int64_t name_offset = obj_skin_strings_get_string_offset_by_index(strings, - string_offsets, bone_name_array, cns->name_index); + string_offsets, ex_node_name, cns->node_name); s.write_uint32_t((uint32_t)name_offset); - s.write_int32_t(cns->coupling); + s.write_uint32_t(cns->nb_src); - int64_t source_node_name_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, cns->source_node_name); - s.write_uint32_t((uint32_t)source_node_name_offset); + int64_t src_name_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, cns->src_name); + s.write_uint32_t((uint32_t)src_name_offset); switch (cns->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: s.write_float_t(cns->orientation->offset.x); s.write_float_t(cns->orientation->offset.y); s.write_float_t(cns->orientation->offset.z); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: - obj_classic_write_skin_block_constraint_up_vector(&cns->direction->up_vector, + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: + obj_classic_write_skin_ex_node_constraint_up_vector(&cns->direction->up_vector, s, strings, string_offsets); s.write_float_t(cns->direction->align_axis.x); s.write_float_t(cns->direction->align_axis.y); @@ -3117,27 +3127,27 @@ static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* c s.write_float_t(cns->direction->target_offset.y); s.write_float_t(cns->direction->target_offset.z); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: - obj_classic_write_skin_block_constraint_up_vector(&cns->position->up_vector, + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: + obj_classic_write_skin_ex_node_constraint_up_vector(&cns->position->up_vector, s, strings, string_offsets); - obj_classic_write_skin_block_constraint_attach_point(&cns->position->constrained_object, + obj_classic_write_skin_ex_node_constraint_attach_point(&cns->position->constrained_object, s, strings, string_offsets); - obj_classic_write_skin_block_constraint_attach_point(&cns->position->constraining_object, + obj_classic_write_skin_ex_node_constraint_attach_point(&cns->position->constraining_object, s, strings, string_offsets); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: - obj_classic_write_skin_block_constraint_up_vector(&cns->distance->up_vector, + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: + obj_classic_write_skin_ex_node_constraint_up_vector(&cns->distance->up_vector, s, strings, string_offsets); s.write_float_t(cns->distance->distance); - obj_classic_write_skin_block_constraint_attach_point(&cns->distance->constrained_object, + obj_classic_write_skin_ex_node_constraint_attach_point(&cns->distance->constrained_object, s, strings, string_offsets); - obj_classic_write_skin_block_constraint_attach_point(&cns->distance->constraining_object, + obj_classic_write_skin_ex_node_constraint_attach_point(&cns->distance->constraining_object, s, strings, string_offsets); break; } } -static void obj_classic_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, +static void obj_classic_read_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, const char** str) { attach_point->affected_by_orientation = s.read_uint32_t() != 0; attach_point->affected_by_scaling = s.read_uint32_t() != 0; @@ -3146,7 +3156,7 @@ static void obj_classic_read_skin_block_constraint_attach_point(obj_skin_block_c attach_point->offset.z = s.read_float_t(); } -static void obj_classic_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, +static void obj_classic_write_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, std::vector& strings, std::vector& string_offsets) { s.write_int32_t(attach_point->affected_by_orientation ? 1 : 0); s.write_int32_t(attach_point->affected_by_scaling ? 1 : 0); @@ -3155,7 +3165,7 @@ static void obj_classic_write_skin_block_constraint_attach_point(obj_skin_block_ s.write_float_t(attach_point->offset.z); } -static void obj_classic_read_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_classic_read_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, prj::shared_ptr alloc, stream& s, const char** str) { up_vector->active = !!s.read_uint32_t(); up_vector->roll = s.read_float_t(); @@ -3170,7 +3180,7 @@ static void obj_classic_read_skin_block_constraint_up_vector(obj_skin_block_cons up_vector->name = obj_read_utf8_string_null_terminated_offset(alloc, s, name_offset); } -static void obj_classic_write_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_classic_write_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, stream& s, std::vector& strings, std::vector& string_offsets) { s.write_int32_t(up_vector->active ? 1 : 0); s.write_float_t(up_vector->roll); @@ -3186,64 +3196,63 @@ static void obj_classic_write_skin_block_constraint_up_vector(obj_skin_block_con s.write_uint32_t((uint32_t)name_offset); } -static obj_skin_block_expression* obj_classic_read_skin_block_expression( +static obj_skin_ex_node_expression* obj_classic_read_skin_ex_node_expression( prj::shared_ptr alloc, stream& s, const char** str) { - obj_skin_block_expression* exp = alloc->allocate(); - obj_classic_read_skin_block_node(&exp->node, alloc, s, str); + obj_skin_ex_node_expression* exp = alloc->allocate(); + obj_classic_read_skin_ex_node_transform(&exp->transform, alloc, s, str); uint32_t name_offset = s.read_uint32_t(); char* name = s.read_utf8_string_null_terminated_offset(name_offset); - exp->name_index = 0; + exp->node_name = 0; if (name) for (const char** i = str; *i; i++) if (!str_utils_compare(name, *i)) { - exp->name_index = 0x8000 | (int32_t)(i - str); + exp->node_name = 0x8000 | (int32_t)(i - str); break; } free_def(name); - int32_t num_expression = s.read_int32_t(); - num_expression = min_def(num_expression, 9); - exp->num_expression = num_expression; - for (int32_t i = 0; i < num_expression; i++) { - uint32_t expression_offset = s.read_uint32_t(); - if (expression_offset) - exp->expression_array[i] - = obj_read_utf8_string_null_terminated_offset(alloc, s, expression_offset); + int32_t nb_src = s.read_int32_t(); + nb_src = min_def(nb_src, 9); + exp->nb_src = nb_src; + for (int32_t i = 0; i < nb_src; i++) { + uint32_t script_offset = s.read_uint32_t(); + if (script_offset) + exp->script[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, script_offset); } - for (int32_t i = num_expression; i < 9; i++) - exp->expression_array[i] = 0; + for (int32_t i = nb_src; i < 9; i++) + exp->script[i] = 0; return exp; } -static void obj_classic_write_skin_block_expression(obj_skin_block_expression* exp, +static void obj_classic_write_skin_ex_node_expression(obj_skin_ex_node_expression* exp, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array) { - obj_classic_write_skin_block_node(&exp->node, s, strings, string_offsets); + const char** ex_node_name) { + obj_classic_write_skin_ex_node_transform(&exp->transform, s, strings, string_offsets); int64_t name_offset = obj_skin_strings_get_string_offset_by_index(strings, - string_offsets, bone_name_array, exp->name_index); + string_offsets, ex_node_name, exp->node_name); s.write_uint32_t((uint32_t)name_offset); - int32_t num_expression = exp->num_expression; - num_expression = min_def(num_expression, 9); - s.write_int32_t(num_expression); - for (int32_t i = 0; i < num_expression; i++) { - int64_t expression_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, exp->expression_array[i]); - s.write_uint32_t((uint32_t)expression_offset); + int32_t nb_src = exp->nb_src; + nb_src = min_def(nb_src, 9); + s.write_int32_t(nb_src); + for (int32_t i = 0; i < nb_src; i++) { + int64_t script_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, exp->script[i]); + s.write_uint32_t((uint32_t)script_offset); } - for (int32_t i = num_expression; i < 9; i++) + for (int32_t i = nb_src; i < 9; i++) s.write_int32_t(0); } -static obj_skin_block_motion* obj_classic_read_skin_block_motion( +static obj_skin_ex_node_motion* obj_classic_read_skin_ex_node_motion( prj::shared_ptr alloc, stream& s, const char** str) { - obj_skin_block_motion* mot = alloc->allocate(); - obj_classic_read_skin_block_node(&mot->node, alloc, s, str); + obj_skin_ex_node_motion* mot = alloc->allocate(); + obj_classic_read_skin_ex_node_transform(&mot->transform, alloc, s, str); uint32_t name_offset = s.read_uint32_t(); mot->num_node = s.read_int32_t(); @@ -3252,11 +3261,11 @@ static obj_skin_block_motion* obj_classic_read_skin_block_motion( char* name = s.read_utf8_string_null_terminated_offset(name_offset); - mot->name_index = 0; + mot->node_name = 0; if (name) for (const char** i = str; *i; i++) if (!str_utils_compare(name, *i)) { - mot->name_index = 0x8000 | (int32_t)(i - str); + mot->node_name = 0x8000 | (int32_t)(i - str); break; } free_def(name); @@ -3271,7 +3280,7 @@ static obj_skin_block_motion* obj_classic_read_skin_block_motion( if (bone_name_array_offset) { s.position_push(bone_name_array_offset, SEEK_SET); for (int32_t i = 0; i < mot->num_node; i++) - mot->node_array[i].name_index = s.read_uint32_t(); + mot->node_array[i].node_name = s.read_uint32_t(); s.position_pop(); } @@ -3301,13 +3310,13 @@ static obj_skin_block_motion* obj_classic_read_skin_block_motion( return mot; } -static void obj_classic_write_skin_block_motion(obj_skin_block_motion* mot, +static void obj_classic_write_skin_ex_node_motion(obj_skin_ex_node_motion* mot, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset) { - obj_classic_write_skin_block_node(&mot->node, s, strings, string_offsets); + const char** ex_node_name, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset) { + obj_classic_write_skin_ex_node_transform(&mot->transform, s, strings, string_offsets); int64_t name_offset = obj_skin_strings_get_string_offset_by_index(strings, - string_offsets, bone_name_array, mot->name_index); + string_offsets, ex_node_name, mot->node_name); s.write_uint32_t((uint32_t)name_offset); s.write_int32_t(mot->num_node); s.write_uint32_t((uint32_t)*bone_name_array_offset); @@ -3316,7 +3325,7 @@ static void obj_classic_write_skin_block_motion(obj_skin_block_motion* mot, if (mot->node_array) { s.position_push(*bone_name_array_offset, SEEK_SET); for (int32_t i = 0; i < mot->num_node; i++) - s.write_uint32_t(mot->node_array[i].name_index); + s.write_uint32_t(mot->node_array[i].node_name); s.position_pop(); *bone_name_array_offset += mot->num_node * sizeof(uint32_t); @@ -3345,7 +3354,7 @@ static void obj_classic_write_skin_block_motion(obj_skin_block_motion* mot, } } -static void obj_classic_read_skin_block_node(obj_skin_block_node* node, +static void obj_classic_read_skin_ex_node_transform(obj_skin_ex_node_transform* node, prj::shared_ptr alloc, stream& s, const char** str) { uint32_t parent_name_offset = s.read_uint32_t(); node->parent_name = obj_read_utf8_string_null_terminated_offset(alloc, s, parent_name_offset); @@ -3361,7 +3370,7 @@ static void obj_classic_read_skin_block_node(obj_skin_block_node* node, node->scale.z = s.read_float_t(); } -static void obj_classic_write_skin_block_node(obj_skin_block_node* node, +static void obj_classic_write_skin_ex_node_transform(obj_skin_ex_node_transform* node, stream& s, std::vector& strings, std::vector& string_offsets) { int64_t parent_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, node->parent_name); @@ -3378,35 +3387,35 @@ static void obj_classic_write_skin_block_node(obj_skin_block_node* node, s.write_float_t(node->scale.z); } -static obj_skin_block_osage* obj_classic_read_skin_block_osage( +static obj_skin_ex_node_osage* obj_classic_read_skin_ex_node_osage( prj::shared_ptr alloc, stream& s, const char** str) { - obj_skin_block_osage* osg = alloc->allocate(); - obj_classic_read_skin_block_node(&osg->node, alloc, s, str); + obj_skin_ex_node_osage* osg = alloc->allocate(); + obj_classic_read_skin_ex_node_transform(&osg->transform, alloc, s, str); - osg->start_index = s.read_uint32_t(); - osg->count = s.read_uint32_t(); - osg->name_index = s.read_uint32_t(); - osg->end_name_index = s.read_uint32_t(); + osg->joint_ofs = s.read_uint32_t(); + osg->nb_joint = s.read_uint32_t(); + osg->root_idx = s.read_uint32_t(); + osg->efc_idx = s.read_uint32_t(); uint32_t offset = s.read_uint32_t(); s.read(0, 0x14); - osg->node_array = 0; + osg->joint_rotation_array = 0; - if (!osg->count || !offset) + if (!osg->nb_joint || !offset) return osg; - osg->num_node = osg->count; - osg->node_array = alloc->allocate(osg->count); + osg->num_joint_rotation = osg->nb_joint; + osg->joint_rotation_array = alloc->allocate(osg->nb_joint); s.position_push(offset, SEEK_SET); if (!(s.read_uint32_t() & 0x8000)) osg->skin_param = obj_classic_read_skin_param(alloc, s, str); else { s.set_position(offset, SEEK_SET); - for (int32_t i = 0; i < osg->num_node; i++) { - obj_skin_osage_node* node = &osg->node_array[i]; - node->name_index = s.read_uint32_t(); + for (int32_t i = 0; i < osg->num_joint_rotation; i++) { + obj_skin_osage_joint_rotation* node = &osg->joint_rotation_array[i]; + node->nid = s.read_uint32_t(); node->length = s.read_float_t(); node->rotation.x = s.read_float_t(); node->rotation.y = s.read_float_t(); @@ -3417,7 +3426,7 @@ static obj_skin_block_osage* obj_classic_read_skin_block_osage( return osg; } -static void obj_classic_write_skin_block_osage(obj_skin_block_osage* osg, +static void obj_classic_write_skin_ex_node_osage(obj_skin_ex_node_osage* osg, stream& s, std::vector& strings, std::vector& string_offsets, int64_t* node_array_offset) { int64_t skin_param_offset = 0; if (osg->skin_param) { @@ -3425,12 +3434,12 @@ static void obj_classic_write_skin_block_osage(obj_skin_block_osage* osg, obj_classic_write_skin_param(osg->skin_param, s, strings, string_offsets); } - obj_classic_write_skin_block_node(&osg->node, s, strings, string_offsets); + obj_classic_write_skin_ex_node_transform(&osg->transform, s, strings, string_offsets); - s.write_int32_t(osg->start_index); - s.write_int32_t(osg->count); - s.write_uint32_t(osg->name_index); - s.write_uint32_t(osg->end_name_index); + s.write_uint32_t(osg->joint_ofs); + s.write_uint32_t(osg->nb_joint); + s.write_uint32_t(osg->root_idx); + s.write_uint32_t(osg->efc_idx); if (osg->skin_param) s.write_uint32_t((uint32_t)skin_param_offset); @@ -3438,68 +3447,68 @@ static void obj_classic_write_skin_block_osage(obj_skin_block_osage* osg, s.write_uint32_t((uint32_t)*node_array_offset); s.write(0x14); - if (!osg->skin_param && osg->node_array) { + if (!osg->skin_param && osg->joint_rotation_array) { s.position_push(*node_array_offset, SEEK_SET); - for (int32_t i = 0; i < osg->num_node; i++) { - obj_skin_osage_node* node = &osg->node_array[i]; - s.write_uint32_t(node->name_index); + for (int32_t i = 0; i < osg->num_joint_rotation; i++) { + obj_skin_osage_joint_rotation* node = &osg->joint_rotation_array[i]; + s.write_uint32_t(node->nid); s.write_float_t(node->length); s.write_float_t(node->rotation.x); s.write_float_t(node->rotation.y); s.write_float_t(node->rotation.z); } s.position_pop(); - *node_array_offset += osg->num_node * (sizeof(uint32_t) + sizeof(float_t) * 4); + *node_array_offset += osg->num_joint_rotation * (sizeof(uint32_t) + sizeof(float_t) * 4); } } static obj_skin_skin_param* obj_classic_read_skin_param( prj::shared_ptr alloc, stream& s, const char** str) { obj_skin_skin_param* skp = alloc->allocate(); - skp->coli = 0; - skp->coli_count = 0; + skp->coli_array = 0; + skp->num_coli = 0; - skp->unk0 = s.read_int32_t(); + skp->root_nid = s.read_int32_t(); skp->force = s.read_float_t(); skp->force_gain = s.read_float_t(); skp->air_res = s.read_float_t(); - skp->rot_y = s.read_float_t(); - skp->rot_z = s.read_float_t(); - skp->hinge_y = s.read_float_t(); - skp->hinge_z = s.read_float_t(); + skp->angle[0] = s.read_float_t(); + skp->angle[1] = s.read_float_t(); + skp->limit[0] = s.read_float_t(); + skp->limit[1] = s.read_float_t(); uint32_t name_offset = s.read_uint32_t(); uint32_t coli_offset = s.read_uint32_t(); skp->coli_r = s.read_float_t(); skp->friction = s.read_float_t(); skp->wind_afc = s.read_float_t(); - skp->unk44 = s.read_int32_t(); + skp->rottype = (ROTTYPE)s.read_int32_t(); skp->name = obj_read_utf8_string_null_terminated_offset(alloc, s, name_offset); if (coli_offset) { s.set_position(coli_offset, SEEK_SET); - int32_t coli_count = 0; + int32_t num_coli = 0; while (s.read_int32_t()) { s.read(44); - coli_count++; + num_coli++; } - skp->coli = alloc->allocate(coli_count); - skp->coli_count = coli_count; + skp->coli_array = alloc->allocate(num_coli); + skp->num_coli = num_coli; s.set_position(coli_offset, SEEK_SET); - for (int32_t i = 0; i < skp->coli_count; i++) { - obj_skin_skin_param_coli* coli = &skp->coli[i]; + for (int32_t i = 0; i < skp->num_coli; i++) { + obj_skin_skin_param_coli* coli = &skp->coli_array[i]; coli->type = (obj_skin_skin_param_coli_type)s.read_int32_t(); - coli->bone0_index = s.read_int32_t(); - coli->bone1_index = s.read_int32_t(); + coli->nid0 = s.read_int32_t(); + coli->nid1 = s.read_int32_t(); coli->radius = s.read_float_t(); - coli->bone0_pos.x = s.read_float_t(); - coli->bone0_pos.y = s.read_float_t(); - coli->bone0_pos.z = s.read_float_t(); - coli->bone1_pos.x = s.read_float_t(); - coli->bone1_pos.y = s.read_float_t(); - coli->bone1_pos.z = s.read_float_t(); + coli->pos0.x = s.read_float_t(); + coli->pos0.y = s.read_float_t(); + coli->pos0.z = s.read_float_t(); + coli->pos1.x = s.read_float_t(); + coli->pos1.y = s.read_float_t(); + coli->pos1.z = s.read_float_t(); } } return skp; @@ -3508,20 +3517,20 @@ static obj_skin_skin_param* obj_classic_read_skin_param( static void obj_classic_write_skin_param(obj_skin_skin_param* skp, stream& s, std::vector& strings, std::vector& string_offsets) { int64_t coli_offset = 0; - if (skp->coli) { + if (skp->coli_array) { coli_offset = s.get_position(); - for (int32_t i = 0; i < skp->coli_count; i++) { - obj_skin_skin_param_coli* coli = &skp->coli[i]; + for (int32_t i = 0; i < skp->num_coli; i++) { + obj_skin_skin_param_coli* coli = &skp->coli_array[i]; s.write_int32_t(coli->type); - s.write_int32_t(coli->bone0_index); - s.write_int32_t(coli->bone1_index); + s.write_int32_t(coli->nid0); + s.write_int32_t(coli->nid1); s.write_float_t(coli->radius); - s.write_float_t(coli->bone0_pos.x); - s.write_float_t(coli->bone0_pos.y); - s.write_float_t(coli->bone0_pos.z); - s.write_float_t(coli->bone1_pos.x); - s.write_float_t(coli->bone1_pos.y); - s.write_float_t(coli->bone1_pos.z); + s.write_float_t(coli->pos0.x); + s.write_float_t(coli->pos0.y); + s.write_float_t(coli->pos0.z); + s.write_float_t(coli->pos1.x); + s.write_float_t(coli->pos1.y); + s.write_float_t(coli->pos1.z); } s.align_write(0x10); } @@ -3529,20 +3538,20 @@ static void obj_classic_write_skin_param(obj_skin_skin_param* skp, int64_t name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, skp->name); - s.write_int32_t(skp->unk0); + s.write_int32_t(skp->root_nid); s.write_float_t(skp->force); s.write_float_t(skp->force_gain); s.write_float_t(skp->air_res); - s.write_float_t(skp->rot_y); - s.write_float_t(skp->rot_z); - s.write_float_t(skp->hinge_y); - s.write_float_t(skp->hinge_z); + s.write_float_t(skp->angle[0]); + s.write_float_t(skp->angle[1]); + s.write_float_t(skp->limit[0]); + s.write_float_t(skp->limit[1]); s.write_uint32_t((uint32_t)name_offset); s.write_uint32_t((uint32_t)coli_offset); s.write_float_t(skp->coli_r); s.write_float_t(skp->friction); s.write_float_t(skp->wind_afc); - s.write_int32_t(skp->unk44); + s.write_int32_t(skp->rottype); s.write(0x08); } @@ -5203,9 +5212,9 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, obj_skin_ex_data_header exh = {}; - obj_skin_block_header* bhs = 0; - int64_t motion_block_node_mats = 0; - int64_t motion_block_node_name_offset = 0; + obj_skin_ex_node_header* bhs = 0; + int64_t motion_ex_node_transform_mats = 0; + int64_t motion_ex_node_transform_name_offset = 0; int64_t cloth_mats = 0; int64_t cloth_root = 0; int64_t cloth_nodes = 0; @@ -5218,41 +5227,41 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, if (sk->ex_data) { obj_skin_ex_data* ex = sk->ex_data; - const char** bone_name_array = ex->bone_name_array; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - switch (block->type) { - case OBJ_SKIN_BLOCK_CLOTH: { - obj_skin_block_cloth* cloth = block->cloth; - obj_skin_strings_push_back_check(strings, cloth->mesh_name); - obj_skin_strings_push_back_check(strings, cloth->backface_mesh_name); + const char** ex_node_name = ex->ex_node_name; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + switch (ex_node->type) { + case OBJ_SKIN_EX_NODE_CLOTH: { + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + obj_skin_strings_push_back_check(strings, cloth->omote_name); + obj_skin_strings_push_back_check(strings, cloth->ura_name); - for (int32_t k = 0; k < cloth->num_root; k++) { - obj_skin_block_cloth_root* root_array = &cloth->root_array[k]; + for (uint32_t k = 0; k < cloth->width; k++) { + obj_skin_ex_node_cloth_root* fix_point = &cloth->fix_point[k]; for (uint32_t l = 0; l < 4; l++) - obj_skin_strings_push_back_check(strings, root_array->bone_weights[l].bone_name); + obj_skin_strings_push_back_check(strings, fix_point->weight[l].bone_name); } obj_skin_strings_push_back_check(strings, "CLS"); } break; - case OBJ_SKIN_BLOCK_CONSTRAINT: { - obj_skin_block_constraint* constraint = block->constraint; - obj_skin_strings_push_back_check(strings, constraint->node.parent_name); + case OBJ_SKIN_EX_NODE_CONSTRAINT: { + obj_skin_ex_node_constraint* constraint = ex_node->constraint; + obj_skin_strings_push_back_check(strings, constraint->transform.parent_name); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, constraint->name_index); - obj_skin_strings_push_back_check(strings, constraint->source_node_name); + ex_node_name, constraint->node_name); + obj_skin_strings_push_back_check(strings, constraint->src_name); switch (constraint->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: obj_skin_strings_push_back_check(strings, "Orientation"); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: obj_skin_strings_push_back_check(strings, "Direction"); obj_skin_strings_push_back_check(strings, constraint->direction->up_vector.name); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: obj_skin_strings_push_back_check(strings, "Position"); obj_skin_strings_push_back_check(strings, constraint->position->up_vector.name); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: obj_skin_strings_push_back_check(strings, "Distance"); obj_skin_strings_push_back_check(strings, constraint->distance->up_vector.name); break; @@ -5260,103 +5269,103 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, obj_skin_strings_push_back_check(strings, "CNS"); obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, constraint->name_index); + ex_node_name, constraint->node_name); } break; - case OBJ_SKIN_BLOCK_EXPRESSION: { - obj_skin_block_expression* expression = block->expression; - for (int32_t j = 0; j < expression->num_expression; j++) - obj_skin_strings_push_back_check(strings, expression->expression_array[j]); - obj_skin_strings_push_back_check(strings, expression->node.parent_name); + case OBJ_SKIN_EX_NODE_EXPRESSION: { + obj_skin_ex_node_expression* expression = ex_node->expression; + for (int32_t j = 0; j < expression->nb_src; j++) + obj_skin_strings_push_back_check(strings, expression->script[j]); + obj_skin_strings_push_back_check(strings, expression->transform.parent_name); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, expression->name_index); + ex_node_name, expression->node_name); obj_skin_strings_push_back_check(strings, "EXP"); obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, expression->name_index); + ex_node_name, expression->node_name); } break; - case OBJ_SKIN_BLOCK_MOTION: { - obj_skin_block_motion* motion = block->motion; - obj_skin_strings_push_back_check(strings, motion->node.parent_name); + case OBJ_SKIN_EX_NODE_MOTION: { + obj_skin_ex_node_motion* motion = ex_node->motion; + obj_skin_strings_push_back_check(strings, motion->transform.parent_name); obj_skin_strings_push_back_check(strings, motion->name); for (int32_t j = 0; j < motion->num_node; j++) obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, motion->node_array[j].name_index); + ex_node_name, motion->node_array[j].node_name); obj_skin_strings_push_back_check(strings, "MOT"); if (!is_x) obj_skin_strings_push_back_check(bone_names, motion->name); for (int32_t j = 0; j < motion->num_node; j++) obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, motion->node_array[j].name_index); + ex_node_name, motion->node_array[j].node_name); } break; - case OBJ_SKIN_BLOCK_OSAGE: { - obj_skin_block_osage* osage = block->osage; - obj_skin_strings_push_back_check(strings, osage->node.parent_name); + case OBJ_SKIN_EX_NODE_OSAGE: { + obj_skin_ex_node_osage* osage = ex_node->osage; + obj_skin_strings_push_back_check(strings, osage->transform.parent_name); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage->end_name_index); + ex_node_name, osage->efc_idx); obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage->name_index); - obj_skin_osage_node* osage_node = &ex->osage_node_array[osage->start_index]; - for (int32_t j = 0; j < osage->count; j++) { + ex_node_name, osage->root_idx); + obj_skin_osage_joint* joint = &ex->osage_joint[osage->joint_ofs]; + for (uint32_t j = 0; j < osage->nb_joint; j++) { obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage_node->name_index); + ex_node_name, joint->nid); - int32_t end_name_index = osage->end_name_index; - obj_skin_osage_sibling_info* osage_sibling_info = ex->osage_sibling_info_array; - for (int32_t k = 0; k < ex->num_osage_sibling_info; k++) { - if (end_name_index == osage_sibling_info->name_index) { + int32_t efc_idx = osage->efc_idx; + obj_skin_osage_constraint_info* osage_sibling_info = ex->osage_constraint_tbl; + for (int32_t k = 0; k < ex->num_osage_constraint; k++) { + if (efc_idx == osage_sibling_info->dst_joint) { obj_skin_strings_push_back_check_by_index(strings, - bone_name_array, osage_sibling_info->sibling_name_index); + ex_node_name, osage_sibling_info->src_joint); break; } osage_sibling_info++; } - osage_node++; + joint++; } obj_skin_strings_push_back_check(strings, "OSG"); obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage->name_index); - osage_node = &ex->osage_node_array[osage->start_index]; - for (int32_t j = 0; j < osage->count; j++) { + ex_node_name, osage->root_idx); + joint = &ex->osage_joint[osage->joint_ofs]; + for (uint32_t j = 0; j < osage->nb_joint; j++) { obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage_node->name_index); + ex_node_name, joint->nid); - int32_t end_name_index = osage->end_name_index; - obj_skin_osage_sibling_info* osage_sibling_info = ex->osage_sibling_info_array; - for (int32_t k = 0; k < ex->num_osage_sibling_info; k++) { - if (end_name_index == osage_sibling_info->name_index) { + int32_t efc_idx = osage->efc_idx; + obj_skin_osage_constraint_info* osage_sibling_info = ex->osage_constraint_tbl; + for (int32_t k = 0; k < ex->num_osage_constraint; k++) { + if (efc_idx == osage_sibling_info->dst_joint) { obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage_sibling_info->sibling_name_index); + ex_node_name, osage_sibling_info->src_joint); break; } osage_sibling_info++; } - osage_node++; + joint++; } obj_skin_strings_push_back_check_by_index(bone_names, - bone_name_array, osage->end_name_index); + ex_node_name, osage->efc_idx); } break; } } - exh.cloth_count = 0; - exh.num_osage = 0; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type == OBJ_SKIN_BLOCK_CLOTH) - exh.cloth_count++; - else if (block->type == OBJ_SKIN_BLOCK_EXPRESSION) + exh.nb_cloth = 0; + exh.nb_root = 0; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type == OBJ_SKIN_EX_NODE_CLOTH) + exh.nb_cloth++; + else if (ex_node->type == OBJ_SKIN_EX_NODE_EXPRESSION) expressions_count++; - else if (block->type == OBJ_SKIN_BLOCK_MOTION) { + else if (ex_node->type == OBJ_SKIN_EX_NODE_MOTION) { motion_count++; - motion_nodes_count += block->motion->num_node; + motion_nodes_count += ex_node->motion->num_node; } - else if (block->type == OBJ_SKIN_BLOCK_OSAGE) - exh.num_osage++; + else if (ex_node->type == OBJ_SKIN_EX_NODE_OSAGE) + exh.nb_root++; } - exh.num_bone_name = (int32_t)bone_names.size(); + exh.nb_node_name = (int32_t)bone_names.size(); } if (sk->ex_data) { @@ -5380,22 +5389,22 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } off = align_val(off, 0x10); - if (ex->num_osage_node) { - ee = { off, 1, 12, (uint32_t)ex->num_osage_node }; + if (ex->nb_jointX) { + ee = { off, 1, 12, (uint32_t)ex->nb_jointX }; ee.append(0, 2, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(ex->num_osage_node * 12ULL); + off = (uint32_t)(ex->nb_jointX * 12ULL); off = align_val(off, 0x10); - ee = { off, 1, 12, (uint32_t)ex->num_osage_sibling_info }; + ee = { off, 1, 12, (uint32_t)ex->num_osage_constraint }; ee.append(0, 3, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(ex->num_osage_sibling_info * 12ULL); + off = (uint32_t)(ex->num_osage_constraint * 12ULL); off = align_val(off, 0x10); } - if (exh.num_osage || exh.cloth_count) { - int32_t count = exh.num_osage + exh.cloth_count; + if (exh.nb_root || exh.nb_cloth) { + int32_t count = exh.nb_root + exh.nb_cloth; if (!is_x) { ee = { off, 1, 4, (uint32_t)count }; ee.append(0, 1, ENRS_DWORD); @@ -5412,50 +5421,50 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } if (!is_x) { - ee = { off, 1, 4, (uint32_t)exh.num_bone_name }; + ee = { off, 1, 4, (uint32_t)exh.nb_node_name }; ee.append(0, 1, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(exh.num_bone_name * 4ULL); + off = (uint32_t)(exh.nb_node_name * 4ULL); } else { - ee = { off, 1, 8, (uint32_t)exh.num_bone_name }; + ee = { off, 1, 8, (uint32_t)exh.nb_node_name }; ee.append(0, 1, ENRS_QWORD); e.vec.push_back(ee); - off = (uint32_t)(exh.num_bone_name * 8ULL); + off = (uint32_t)(exh.nb_node_name * 8ULL); } off = align_val(off, 0x10); - if (ex->num_block > 0) { + if (ex->num_ex_node > 0) { if (!is_x) { - ee = { off, 1, 8, (uint32_t)ex->num_block }; + ee = { off, 1, 8, (uint32_t)ex->num_ex_node }; ee.append(0, 2, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(ex->num_block * 8ULL); + off = (uint32_t)(ex->num_ex_node * 8ULL); } else { - ee = { off, 1, 16, (uint32_t)ex->num_block }; + ee = { off, 1, 16, (uint32_t)ex->num_ex_node }; ee.append(0, 2, ENRS_QWORD); e.vec.push_back(ee); - off = (uint32_t)(ex->num_block * 16ULL); + off = (uint32_t)(ex->num_ex_node * 16ULL); } off = align_val(off, 0x10); - if (exh.num_osage) { + if (exh.nb_root) { if (!is_x) { - ee = { off, 2, 76, (uint32_t)exh.num_osage }; + ee = { off, 2, 76, (uint32_t)exh.nb_root }; ee.append(0, 14, ENRS_DWORD); ee.append(4, 1, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(exh.num_osage * 76ULL); + off = (uint32_t)(exh.nb_root * 76ULL); } else { - ee = { off, 4, 104, (uint32_t)exh.num_osage }; + ee = { off, 4, 104, (uint32_t)exh.nb_root }; ee.append(0, 1, ENRS_QWORD); ee.append(0, 9, ENRS_DWORD); ee.append(4, 4, ENRS_DWORD); ee.append(8, 1, ENRS_QWORD); e.vec.push_back(ee); - off = (uint32_t)(exh.num_osage * 104ULL); + off = (uint32_t)(exh.nb_root * 104ULL); } off = align_val(off, 0x10); } @@ -5480,33 +5489,33 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, off = align_val(off, 0x10); } - if (exh.cloth_count) { + if (exh.nb_cloth) { if (!is_x) { - ee = { off, 1, 52, (uint32_t)exh.cloth_count }; + ee = { off, 1, 52, (uint32_t)exh.nb_cloth }; ee.append(0, 13, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(exh.cloth_count * 52ULL); + off = (uint32_t)(exh.nb_cloth * 52ULL); } else { - ee = { off, 4, 88, (uint32_t)exh.cloth_count }; + ee = { off, 4, 88, (uint32_t)exh.nb_cloth }; ee.append(0, 2, ENRS_QWORD); ee.append(0, 4, ENRS_DWORD); ee.append(0, 6, ENRS_QWORD); ee.append(0, 1, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(exh.cloth_count * 88ULL); + off = (uint32_t)(exh.nb_cloth * 88ULL); } off = align_val(off, 0x10); } int32_t constraint_count = 0; - obj_skin_block_constraint_type cns_type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CONSTRAINT) + obj_skin_ex_node_constraint_type cns_type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CONSTRAINT) continue; - if (cns_type == block->constraint->type) { + if (cns_type == ex_node->constraint->type) { constraint_count++; continue; } @@ -5517,29 +5526,29 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, off = ee.size * ee.repeat_count; } - cns_type = block->constraint->type; + cns_type = ex_node->constraint->type; if (!is_x) switch (cns_type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: ee = { off, 6, 68, 0 }; ee.append(0, 17, ENRS_DWORD); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: ee = { off, 8, 144, 0 }; ee.append(0, 29, ENRS_DWORD); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: ee = { off, 8, 132, 0 }; ee.append(0, 33, ENRS_DWORD); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: ee = { off, 8, 136, 0 }; ee.append(0, 34, ENRS_DWORD); break; } else switch (cns_type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: ee = { off, 6, 96, 0 }; ee.append(0, 1, ENRS_QWORD); ee.append(0, 9, ENRS_DWORD); @@ -5548,7 +5557,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, ee.append(4, 1, ENRS_QWORD); ee.append(0, 3, ENRS_DWORD); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: ee = { off, 8, 144, 0 }; ee.append(0, 1, ENRS_QWORD); ee.append(0, 9, ENRS_DWORD); @@ -5559,7 +5568,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, ee.append(0, 1, ENRS_QWORD); ee.append(0, 6, ENRS_DWORD); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: ee = { off, 8, 160, 0 }; ee.append(0, 1, ENRS_QWORD); ee.append(0, 9, ENRS_DWORD); @@ -5570,7 +5579,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, ee.append(0, 1, ENRS_QWORD); ee.append(0, 10, ENRS_DWORD); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: ee = { off, 8, 168, 0 }; ee.append(0, 1, ENRS_QWORD); ee.append(0, 9, ENRS_DWORD); @@ -5624,43 +5633,43 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, off = align_val(off, 0x10); } - if (exh.cloth_count) { - int32_t num_mat = 0; - int32_t num_root = 0; - int32_t num_node = 0; - int32_t num_mesh_index = 0; - int32_t num_backface_mesh_index = 0; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type == OBJ_SKIN_BLOCK_CLOTH) { - num_mat += block->cloth->mat_array ? block->cloth->num_mat : 0; - num_root += block->cloth->root_array ? block->cloth->num_root : 0; - num_node += block->cloth->node_array - ? block->cloth->num_root * (block->cloth->num_node - 1) : 0; - num_mesh_index += block->cloth->mesh_index_array - ? block->cloth->num_mesh_index + 1 : 0; - num_backface_mesh_index += block->cloth->backface_mesh_index_array - ? block->cloth->num_backface_mesh_index + 1 : 0; + if (exh.nb_cloth) { + uint32_t num_mat = 0; + uint32_t width = 0; + uint32_t height = 0; + uint32_t num_omote_index = 0; + uint32_t num_ura_index = 0; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type == OBJ_SKIN_EX_NODE_CLOTH) { + num_mat += ex_node->cloth->mat_array ? ex_node->cloth->num_mat : 0; + width += ex_node->cloth->fix_point ? ex_node->cloth->width : 0; + height += ex_node->cloth->move_point + ? ex_node->cloth->width * (ex_node->cloth->height - 1) : 0; + num_omote_index += ex_node->cloth->omote_index_array + ? ex_node->cloth->num_omote_index + 1 : 0; + num_ura_index += ex_node->cloth->ura_index_array + ? ex_node->cloth->num_ura_index + 1 : 0; } } if (num_mat) { - ee = { off, 1, sizeof(mat4), (uint32_t)num_mat }; + ee = { off, 1, sizeof(mat4), num_mat }; ee.append(0, 16, ENRS_DWORD); e.vec.push_back(ee); off = (uint32_t)(num_mat * sizeof(mat4)); off = align_val(off, 0x10); } - if (num_root) { + if (width) { if (!is_x) { - ee = { off, 1, 104, (uint32_t)num_root }; + ee = { off, 1, 104, width }; ee.append(0, 26, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(num_root * 104ULL); + off = (uint32_t)(width * 104ULL); } else { - ee = { off, 9, 136, (uint32_t)num_root }; + ee = { off, 9, 136, width }; ee.append(0, 10, ENRS_DWORD); ee.append(0, 1, ENRS_QWORD); ee.append(0, 3, ENRS_DWORD); @@ -5671,32 +5680,32 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, ee.append(4, 1, ENRS_QWORD); ee.append(0, 3, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(num_root * 136ULL); + off = (uint32_t)(width * 136ULL); } off = align_val(off, 0x10); } - if (num_node) { - ee = { off, 1, 44, (uint32_t)num_node }; + if (height) { + ee = { off, 1, 44, height }; ee.append(0, 11, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(num_node * 44ULL); + off = (uint32_t)(height * 44ULL); off = align_val(off, 0x10); } - if (num_mesh_index) { - ee = { off, 1, 2, (uint32_t)num_mesh_index }; + if (num_omote_index) { + ee = { off, 1, 2, num_omote_index }; ee.append(0, 1, ENRS_WORD); e.vec.push_back(ee); - off = (uint32_t)(num_mesh_index * 2ULL); + off = (uint32_t)(num_omote_index * 2ULL); off = align_val(off, 0x10); } - if (num_backface_mesh_index) { - ee = { off, 1, 2, (uint32_t)num_backface_mesh_index }; + if (num_ura_index) { + ee = { off, 1, 2, num_ura_index }; ee.append(0, 1, ENRS_WORD); e.vec.push_back(ee); - off = (uint32_t)(num_backface_mesh_index * 2ULL); + off = (uint32_t)(num_ura_index * 2ULL); off = align_val(off, 0x10); } } @@ -5814,17 +5823,17 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } s.align_write(0x10); - if (ex->num_osage_node) { - exh.osage_node_array_offset = s.get_position(); - for (int32_t i = 0; i < ex->num_osage_node; i++) { + if (ex->nb_jointX) { + exh.osage_joint_offset = s.get_position(); + for (int32_t i = 0; i < ex->nb_jointX; i++) { s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); } s.align_write(0x10); - exh.osage_sibling_info_array_offset = s.get_position(); - for (int32_t i = 0; i < ex->num_osage_sibling_info; i++) { + exh.osage_constraint_tbl_offset = s.get_position(); + for (int32_t i = 0; i < ex->num_osage_constraint; i++) { s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); @@ -5835,26 +5844,26 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.align_write(0x10); } - if (exh.num_osage || exh.cloth_count) { - exh.osage_name_array_offset = s.get_position(); + if (exh.nb_root || exh.nb_cloth) { + exh.root_name_offset = s.get_position(); if (!is_x) { - for (int32_t i = 0; i < exh.num_osage; i++) + for (int32_t i = 0; i < exh.nb_root; i++) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); - for (int32_t i = 0; i < exh.cloth_count; i++) + for (int32_t i = 0; i < exh.nb_cloth; i++) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); } else { - for (int32_t i = 0; i < exh.num_osage; i++) + for (int32_t i = 0; i < exh.nb_root; i++) io_write_offset_x_pof_add(s, 0, &pof); - for (int32_t i = 0; i < exh.cloth_count; i++) + for (int32_t i = 0; i < exh.nb_cloth; i++) io_write_offset_x_pof_add(s, 0, &pof); } s.align_write(0x10); } - exh.bone_name_array_offset = s.get_position(); + exh.ex_node_name_offset = s.get_position(); if (!is_x) for (string_hash& i : bone_names) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); @@ -5863,10 +5872,10 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, io_write_offset_x_pof_add(s, 0, &pof); s.align_write(0x10); - if (ex->num_block > 0) { - exh.block_array_offset = s.get_position(); + if (ex->num_ex_node > 0) { + exh.ex_node_array_offset = s.get_position(); if (!is_x) { - for (int32_t i = 0; i < ex->num_block; i++) { + for (int32_t i = 0; i < ex->num_ex_node; i++) { io_write_offset_f2_pof_add(s, 0, 0x20, &pof); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); } @@ -5874,7 +5883,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.write_offset_f2(0, 0x20); } else { - for (int32_t i = 0; i < ex->num_block; i++) { + for (int32_t i = 0; i < ex->num_ex_node; i++) { io_write_offset_x_pof_add(s, 0, &pof); io_write_offset_x_pof_add(s, 0, &pof); } @@ -5883,27 +5892,27 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } s.align_write(0x10); - bhs = force_malloc(ex->num_block); + bhs = force_malloc(ex->num_ex_node); if (!is_x) - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_OSAGE) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_OSAGE) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x24); s.write(0x24); } else - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_OSAGE) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_OSAGE) continue; - obj_skin_block_osage* osage = block->osage; + obj_skin_ex_node_osage* osage = ex_node->osage; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x28); if (osage->motion_node_name) { @@ -5917,77 +5926,77 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.align_write(0x10); if (!is_x) - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_EXPRESSION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_EXPRESSION) continue; - obj_skin_block_expression* expression = block->expression; + obj_skin_ex_node_expression* expression = ex_node->expression; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x24); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x04); - for (int32_t j = 0; j < expression->num_expression && j < 9; j++) + for (int32_t j = 0; j < expression->nb_src && j < 9; j++) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); - for (int32_t j = expression->num_expression; j < 9; j++) + for (int32_t j = expression->nb_src; j < 9; j++) s.write(0x04); } else - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_EXPRESSION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_EXPRESSION) continue; - obj_skin_block_expression* expression = block->expression; + obj_skin_ex_node_expression* expression = ex_node->expression; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x28); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x08); - for (int32_t j = 0; j < expression->num_expression && j < 9; j++) + for (int32_t j = 0; j < expression->nb_src && j < 9; j++) io_write_offset_x_pof_add(s, 0, &pof); - for (int32_t j = expression->num_expression; j < 9; j++) + for (int32_t j = expression->nb_src; j < 9; j++) s.write(0x08); } s.align_write(0x10); if (!is_x) - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; + obj_skin_ex_node_cloth* cloth = ex_node->cloth; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x10); - if (cloth->num_node) + if (cloth->height) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); else s.write(0x04); - if (cloth->num_root) { + if (cloth->width) { io_write_offset_f2_pof_add(s, 0, 0x20, &pof); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); } else s.write(0x08); - if (cloth->num_mesh_index) + if (cloth->num_omote_index) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); else s.write(0x04); - if (cloth->num_backface_mesh_index) + if (cloth->num_ura_index) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); else s.write(0x04); @@ -5995,36 +6004,36 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.write(0x08); } else - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; + obj_skin_ex_node_cloth* cloth = ex_node->cloth; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_x_pof_add(s, 0, &pof); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x10); - if (cloth->num_node) + if (cloth->height) io_write_offset_x_pof_add(s, 0, &pof); else s.write(0x08); - if (cloth->num_root) { + if (cloth->width) { io_write_offset_x_pof_add(s, 0, &pof); io_write_offset_x_pof_add(s, 0, &pof); } else s.write(0x10); - if (cloth->num_mesh_index) + if (cloth->num_omote_index) io_write_offset_x_pof_add(s, 0, &pof); else s.write(0x08); - if (cloth->num_backface_mesh_index) + if (cloth->num_ura_index) io_write_offset_x_pof_add(s, 0, &pof); else s.write(0x08); @@ -6034,34 +6043,34 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.align_write(0x10); if (!is_x) - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CONSTRAINT) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CONSTRAINT) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x24); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x04); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); - switch (block->constraint->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + switch (ex_node->constraint->type) { + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: s.write(0x0C); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: s.write(0x20); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x18); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: s.write(0x20); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x14); s.write(0x14); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: s.write(0x20); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x04); @@ -6071,35 +6080,35 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } } else - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CONSTRAINT) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CONSTRAINT) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x28); io_write_offset_x_pof_add(s, 0, &pof); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x08); io_write_offset_x_pof_add(s, 0, &pof); - switch (block->constraint->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + switch (ex_node->constraint->type) { + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: s.write(0x0C); s.write(0x04); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: s.write(0x20); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x18); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: s.write(0x20); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x14); s.write(0x14); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: s.write(0x20); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x04); @@ -6112,12 +6121,12 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.align_write(0x10); if (!is_x) - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); s.write(0x24); io_write_offset_f2_pof_add(s, 0, 0x20, &pof); @@ -6126,12 +6135,12 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, io_write_offset_f2_pof_add(s, 0, 0x20, &pof); } else - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - bhs[i].block_offset = s.get_position(); + bhs[i].ex_node_offset = s.get_position(); io_write_offset_x_pof_add(s, 0, &pof); s.write(0x28); io_write_offset_x_pof_add(s, 0, &pof); @@ -6142,37 +6151,37 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.align_write(0x10); if (motion_count) { - motion_block_node_mats = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + motion_ex_node_transform_mats = s.get_position(); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - obj_skin_block_motion* motion = block->motion; + obj_skin_ex_node_motion* motion = ex_node->motion; s.write(motion->num_node * sizeof(mat4)); } s.align_write(0x10); - motion_block_node_name_offset = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + motion_ex_node_transform_name_offset = s.get_position(); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - obj_skin_block_motion* motion = block->motion; + obj_skin_ex_node_motion* motion = ex_node->motion; s.write(motion->num_node * sizeof(uint32_t)); } s.align_write(0x10); } - if (exh.cloth_count) { + if (exh.nb_cloth) { cloth_mats = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; + obj_skin_ex_node_cloth* cloth = ex_node->cloth; if (cloth->mat_array) s.write(cloth->num_mat * sizeof(mat4)); } @@ -6180,57 +6189,57 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, cloth_root = s.get_position(); if (!is_x) - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; + obj_skin_ex_node_cloth* cloth = ex_node->cloth; s.write((sizeof(int32_t) + 4 * (sizeof(int32_t) + 3 * sizeof(int32_t))) - * cloth->num_root * (cloth->num_node - 1ULL)); + * cloth->width * (cloth->height - 1ULL)); } else - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; + obj_skin_ex_node_cloth* cloth = ex_node->cloth; s.write((sizeof(int32_t) + 4 * (sizeof(int64_t) + 4 * sizeof(int32_t))) - * cloth->num_root* (cloth->num_node - 1ULL)); + * cloth->width* (cloth->height - 1ULL)); } s.align_write(0x10); cloth_nodes = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; - s.write((11 * sizeof(int32_t)) * cloth->num_root * (cloth->num_node - 1ULL)); + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + s.write((11 * sizeof(int32_t)) * cloth->width * (cloth->height - 1ULL)); } s.align_write(0x10); cloth_mesh_indices = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; - s.write(sizeof(uint16_t) + cloth->num_mesh_index * sizeof(uint16_t)); + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + s.write(sizeof(uint16_t) + cloth->num_omote_index * sizeof(uint16_t)); } s.align_write(0x10); cloth_backface_mesh_indices = s.get_position(); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - obj_skin_block_cloth* cloth = block->cloth; - s.write(sizeof(uint16_t) + cloth->num_backface_mesh_index * sizeof(uint16_t)); + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + s.write(sizeof(uint16_t) + cloth->num_ura_index * sizeof(uint16_t)); } s.align_write(0x10); } @@ -6257,14 +6266,14 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, int64_t mot_offset = obj_skin_strings_get_string_offset(strings, string_offsets, "MOT"); int64_t osg_offset = obj_skin_strings_get_string_offset(strings, string_offsets, "OSG"); - if (ex->num_block > 0) { - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CLOTH) + if (ex->num_ex_node > 0) { + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CLOTH) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_modern_write_skin_block_cloth(block->cloth, + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_modern_write_skin_ex_node_cloth(ex_node->cloth, s, strings, string_offsets, is_x, &cloth_mats, &cloth_root, &cloth_nodes, &cloth_mesh_indices, &cloth_backface_mesh_indices); s.position_pop(); @@ -6280,89 +6289,89 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, constraint_type_name_offsets[3] = obj_skin_strings_get_string_offset(strings, string_offsets, "Distance"); - const char** bone_name_array = ex->bone_name_array; - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_CONSTRAINT) + const char** ex_node_name = ex->ex_node_name; + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_CONSTRAINT) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_modern_write_skin_block_constraint(block->constraint, - s, strings, string_offsets, bone_name_array, is_x, constraint_type_name_offsets); + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_modern_write_skin_ex_node_constraint(ex_node->constraint, + s, strings, string_offsets, ex_node_name, is_x, constraint_type_name_offsets); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_EXPRESSION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_EXPRESSION) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_modern_write_skin_block_expression(block->expression, - s, strings, string_offsets, bone_name_array, is_x); + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_modern_write_skin_ex_node_expression(ex_node->expression, + s, strings, string_offsets, ex_node_name, is_x); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_MOTION) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_MOTION) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_modern_write_skin_block_motion(block->motion, - s, strings, string_offsets, is_x, bone_name_array, - &motion_block_node_name_offset, &motion_block_node_mats); + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_modern_write_skin_ex_node_motion(ex_node->motion, + s, strings, string_offsets, is_x, ex_node_name, + &motion_ex_node_transform_name_offset, &motion_ex_node_transform_mats); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type != OBJ_SKIN_BLOCK_OSAGE) + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type != OBJ_SKIN_EX_NODE_OSAGE) continue; - s.position_push(bhs[i].block_offset, SEEK_SET); - obj_modern_write_skin_block_osage(block->osage, + s.position_push(bhs[i].ex_node_offset, SEEK_SET); + obj_modern_write_skin_ex_node_osage(ex_node->osage, s, strings, string_offsets, is_x); s.position_pop(); } - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - if (block->type == OBJ_SKIN_BLOCK_CLOTH) { - obj_skin_block_cloth* cloth = block->cloth; - obj_skin_strings_push_back_check(osage_names, cloth->mesh_name); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + if (ex_node->type == OBJ_SKIN_EX_NODE_CLOTH) { + obj_skin_ex_node_cloth* cloth = ex_node->cloth; + obj_skin_strings_push_back_check(osage_names, cloth->omote_name); } - else if (block->type == OBJ_SKIN_BLOCK_OSAGE) { - obj_skin_block_osage* osage = block->osage; + else if (ex_node->type == OBJ_SKIN_EX_NODE_OSAGE) { + obj_skin_ex_node_osage* osage = ex_node->osage; obj_skin_strings_push_back_check_by_index(osage_names, - bone_name_array, osage->name_index); + ex_node_name, osage->root_idx); } } - s.position_push(exh.block_array_offset, SEEK_SET); + s.position_push(exh.ex_node_array_offset, SEEK_SET); if (!is_x) { - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - switch (block->type) { - case OBJ_SKIN_BLOCK_CLOTH: + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + switch (ex_node->type) { + case OBJ_SKIN_EX_NODE_CLOTH: s.write_offset_f2(cls_offset, 0x20); - s.write_offset_f2(bhs[i].block_offset, 0x20); + s.write_offset_f2(bhs[i].ex_node_offset, 0x20); break; - case OBJ_SKIN_BLOCK_CONSTRAINT: + case OBJ_SKIN_EX_NODE_CONSTRAINT: s.write_offset_f2(cns_offset, 0x20); - s.write_offset_f2(bhs[i].block_offset, 0x20); + s.write_offset_f2(bhs[i].ex_node_offset, 0x20); break; - case OBJ_SKIN_BLOCK_EXPRESSION: + case OBJ_SKIN_EX_NODE_EXPRESSION: s.write_offset_f2(exp_offset, 0x20); - s.write_offset_f2(bhs[i].block_offset, 0x20); + s.write_offset_f2(bhs[i].ex_node_offset, 0x20); break; - case OBJ_SKIN_BLOCK_MOTION: + case OBJ_SKIN_EX_NODE_MOTION: s.write_offset_f2(mot_offset, 0x20); - s.write_offset_f2(bhs[i].block_offset, 0x20); + s.write_offset_f2(bhs[i].ex_node_offset, 0x20); break; - case OBJ_SKIN_BLOCK_OSAGE: + case OBJ_SKIN_EX_NODE_OSAGE: s.write_offset_f2(osg_offset, 0x20); - s.write_offset_f2(bhs[i].block_offset, 0x20); + s.write_offset_f2(bhs[i].ex_node_offset, 0x20); break; default: s.write_offset_f2(0, 0); @@ -6374,28 +6383,28 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.write_offset_f2(0, 0); } else { - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; - switch (block->type) { - case OBJ_SKIN_BLOCK_CLOTH: + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; + switch (ex_node->type) { + case OBJ_SKIN_EX_NODE_CLOTH: s.write_offset_x(cls_offset); - s.write_offset_x(bhs[i].block_offset); + s.write_offset_x(bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_CONSTRAINT: + case OBJ_SKIN_EX_NODE_CONSTRAINT: s.write_offset_x(cns_offset); - s.write_offset_x(bhs[i].block_offset); + s.write_offset_x(bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_EXPRESSION: + case OBJ_SKIN_EX_NODE_EXPRESSION: s.write_offset_x(exp_offset); - s.write_offset_x(bhs[i].block_offset); + s.write_offset_x(bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_MOTION: + case OBJ_SKIN_EX_NODE_MOTION: s.write_offset_x(mot_offset); - s.write_offset_x(bhs[i].block_offset); + s.write_offset_x(bhs[i].ex_node_offset); break; - case OBJ_SKIN_BLOCK_OSAGE: + case OBJ_SKIN_EX_NODE_OSAGE: s.write_offset_x(osg_offset); - s.write_offset_x(bhs[i].block_offset); + s.write_offset_x(bhs[i].ex_node_offset); break; default: s.write_offset_x(0); @@ -6431,8 +6440,8 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, if (sk->ex_data) { obj_skin_ex_data* ex = sk->ex_data; - if (ex->num_block > 0) { - s.position_push(exh.bone_name_array_offset, SEEK_SET); + if (ex->num_ex_node > 0) { + s.position_push(exh.ex_node_name_offset, SEEK_SET); if (!is_x) for (string_hash& i : bone_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, @@ -6447,30 +6456,33 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } s.position_pop(); - s.position_push(exh.osage_node_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_node; i++) { - obj_skin_osage_node* osage_node = &ex->osage_node_array[i]; - s.write_uint32_t_reverse_endianness(osage_node->name_index); - s.write_float_t_reverse_endianness(osage_node->length); + exh.osage_root_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, ex->osage_root); + + s.position_push(exh.osage_joint_offset, SEEK_SET); + for (int32_t i = 0; i < ex->nb_jointX; i++) { + obj_skin_osage_joint* joint = &ex->osage_joint[i]; + s.write_uint32_t_reverse_endianness(joint->nid); + s.write_float_t_reverse_endianness(joint->length); s.write_uint32_t_reverse_endianness(0); } s.position_pop(); - s.position_push(exh.osage_sibling_info_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_sibling_info; i++) { - obj_skin_osage_sibling_info* osage_sibling_info = &ex->osage_sibling_info_array[i]; - s.write_uint32_t_reverse_endianness(osage_sibling_info->name_index); - s.write_uint32_t_reverse_endianness(osage_sibling_info->sibling_name_index); - s.write_float_t_reverse_endianness(osage_sibling_info->max_distance); + s.position_push(exh.osage_constraint_tbl_offset, SEEK_SET); + for (int32_t i = 0; i < ex->num_osage_constraint; i++) { + obj_skin_osage_constraint_info* osage_sibling_info = &ex->osage_constraint_tbl[i]; + s.write_uint32_t_reverse_endianness(osage_sibling_info->dst_joint); + s.write_uint32_t_reverse_endianness(osage_sibling_info->src_joint); + s.write_float_t_reverse_endianness(osage_sibling_info->length); } s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); s.position_pop(); - exh.num_osage = (int32_t)osage_names.size(); - exh.num_osage -= exh.cloth_count; - s.position_push(exh.osage_name_array_offset, SEEK_SET); + exh.nb_root = (int32_t)osage_names.size(); + exh.nb_root -= exh.nb_cloth; + s.position_push(exh.root_name_offset, SEEK_SET); if (!is_x) for (string_hash& i : osage_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, @@ -6488,16 +6500,16 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.position_push(sh.ex_data_offset, SEEK_SET); if (!is_x) { - s.write_int32_t_reverse_endianness(exh.num_osage); - s.write_int32_t_reverse_endianness(ex->num_osage_node); - s.write(0x04); - s.write_offset_f2(exh.osage_node_array_offset, 0x20); - s.write_offset_f2(exh.osage_name_array_offset, 0x20); - s.write_offset_f2(exh.block_array_offset, 0x20); - s.write_int32_t_reverse_endianness(exh.num_bone_name); - s.write_offset_f2(exh.bone_name_array_offset, 0x20); - s.write_offset_f2(exh.osage_sibling_info_array_offset, 0x20); - s.write_int32_t_reverse_endianness(exh.cloth_count); + s.write_int32_t_reverse_endianness(exh.nb_root); + s.write_int32_t_reverse_endianness(ex->nb_jointX); + s.write_offset_f2(exh.osage_root_offset, 0x20); + s.write_offset_f2(exh.osage_joint_offset, 0x20); + s.write_offset_f2(exh.root_name_offset, 0x20); + s.write_offset_f2(exh.ex_node_array_offset, 0x20); + s.write_int32_t_reverse_endianness(exh.nb_node_name); + s.write_offset_f2(exh.ex_node_name_offset, 0x20); + s.write_offset_f2(exh.osage_constraint_tbl_offset, 0x20); + s.write_int32_t_reverse_endianness(exh.nb_cloth); s.write_offset_f2(ex->reserved[0], 0x20); s.write_offset_f2(ex->reserved[1], 0x20); s.write_offset_f2(ex->reserved[2], 0x20); @@ -6507,16 +6519,16 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, s.write_offset_f2(ex->reserved[6], 0x20); } else { - s.write_int32_t_reverse_endianness(exh.num_osage); - s.write_int32_t_reverse_endianness(ex->num_osage_node); - s.write(0x08); - s.write_offset_x(exh.osage_node_array_offset); - s.write_offset_x(exh.osage_name_array_offset); - s.write_offset_x(exh.block_array_offset); - s.write_int32_t_reverse_endianness(exh.num_bone_name); - s.write_offset_x(exh.bone_name_array_offset); - s.write_offset_x(exh.osage_sibling_info_array_offset); - s.write_int32_t_reverse_endianness(exh.cloth_count); + s.write_int32_t_reverse_endianness(exh.nb_root); + s.write_int32_t_reverse_endianness(ex->nb_jointX); + s.write_offset_x(exh.osage_root_offset); + s.write_offset_x(exh.osage_joint_offset); + s.write_offset_x(exh.root_name_offset); + s.write_offset_x(exh.ex_node_array_offset); + s.write_int32_t_reverse_endianness(exh.nb_node_name); + s.write_offset_x(exh.ex_node_name_offset); + s.write_offset_x(exh.osage_constraint_tbl_offset); + s.write_int32_t_reverse_endianness(exh.nb_cloth); s.write_offset_x(ex->reserved[0]); s.write_offset_x(ex->reserved[1]); s.write_offset_x(ex->reserved[2]); @@ -6560,16 +6572,16 @@ static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptrnum_osage_node = s.read_int32_t_reverse_endianness(); - s.read(0, 0x04); - exh.osage_node_array_offset = s.read_offset_f2(header_length); - exh.osage_name_array_offset = s.read_offset_f2(header_length); - exh.block_array_offset = s.read_offset_f2(header_length); - exh.num_bone_name = s.read_int32_t_reverse_endianness(); - exh.bone_name_array_offset = s.read_offset_f2(header_length); - exh.osage_sibling_info_array_offset = s.read_offset_f2(header_length); - exh.cloth_count = s.read_int32_t_reverse_endianness(); + exh.nb_root = s.read_int32_t_reverse_endianness(); + ex->nb_jointX = s.read_int32_t_reverse_endianness(); + exh.osage_root_offset = s.read_offset_f2(header_length); + exh.osage_joint_offset = s.read_offset_f2(header_length); + exh.root_name_offset = s.read_offset_f2(header_length); + exh.ex_node_array_offset = s.read_offset_f2(header_length); + exh.nb_node_name = s.read_int32_t_reverse_endianness(); + exh.ex_node_name_offset = s.read_offset_f2(header_length); + exh.osage_constraint_tbl_offset = s.read_offset_f2(header_length); + exh.nb_cloth = s.read_int32_t_reverse_endianness(); ex->reserved[0] = s.read_offset_f2(header_length); ex->reserved[1] = s.read_offset_f2(header_length); ex->reserved[2] = s.read_offset_f2(header_length); @@ -6579,16 +6591,16 @@ static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptrreserved[6] = s.read_offset_f2(header_length); } else { - exh.num_osage = s.read_int32_t_reverse_endianness(); - ex->num_osage_node = s.read_int32_t_reverse_endianness(); - s.read(0, 0x08); - exh.osage_node_array_offset = s.read_offset_x(); - exh.osage_name_array_offset = s.read_offset_x(); - exh.block_array_offset = s.read_offset_x(); - exh.num_bone_name = s.read_int32_t_reverse_endianness(); - exh.bone_name_array_offset = s.read_offset_x(); - exh.osage_sibling_info_array_offset = s.read_offset_x(); - exh.cloth_count = s.read_int32_t_reverse_endianness(); + exh.nb_root = s.read_int32_t_reverse_endianness(); + ex->nb_jointX = s.read_int32_t_reverse_endianness(); + exh.osage_root_offset = s.read_offset_x(); + exh.osage_joint_offset = s.read_offset_x(); + exh.root_name_offset = s.read_offset_x(); + exh.ex_node_array_offset = s.read_offset_x(); + exh.nb_node_name = s.read_int32_t_reverse_endianness(); + exh.ex_node_name_offset = s.read_offset_x(); + exh.osage_constraint_tbl_offset = s.read_offset_x(); + exh.nb_cloth = s.read_int32_t_reverse_endianness(); ex->reserved[0] = s.read_offset_x(); ex->reserved[1] = s.read_offset_x(); ex->reserved[2] = s.read_offset_x(); @@ -6598,116 +6610,121 @@ static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptrreserved[6] = s.read_offset_x(); } - ex->bone_name_array = 0; - ex->num_bone_name = 0; - if (!exh.bone_name_array_offset) { + ex->ex_node_name = 0; + ex->nb_node_name = 0; + if (!exh.ex_node_name_offset) { return ex; } - int32_t num_bone_name = exh.num_bone_name; + int32_t nb_node_name = exh.nb_node_name; - const char** bone_name_array = alloc->allocate(num_bone_name); - ex->bone_name_array = bone_name_array; - ex->num_bone_name = num_bone_name; + const char** ex_node_name = alloc->allocate(nb_node_name); + ex->ex_node_name = ex_node_name; + ex->nb_node_name = nb_node_name; - s.set_position(exh.bone_name_array_offset, SEEK_SET); + s.set_position(exh.ex_node_name_offset, SEEK_SET); if (!is_x) - for (int32_t i = 0; i < num_bone_name; i++) { + for (int32_t i = 0; i < nb_node_name; i++) { int64_t string_offset = s.read_offset_f2(header_length); if (string_offset) - bone_name_array[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, string_offset); + ex_node_name[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, string_offset); else - bone_name_array[i] = 0; + ex_node_name[i] = 0; } else - for (int32_t i = 0; i < num_bone_name; i++) { + for (int32_t i = 0; i < nb_node_name; i++) { int64_t string_offset = s.read_offset_x(); if (string_offset) - bone_name_array[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, string_offset); + ex_node_name[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, string_offset); else - bone_name_array[i] = 0; + ex_node_name[i] = 0; } - if (exh.osage_node_array_offset) { - ex->osage_node_array = alloc->allocate(ex->num_osage_node); + if (exh.osage_root_offset) + ex->osage_root = obj_read_utf8_string_null_terminated_offset(alloc, s, exh.osage_root_offset); + else + ex->osage_root = 0; - s.set_position(exh.osage_node_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_node; i++) { - obj_skin_osage_node* osage_node = &ex->osage_node_array[i]; + if (exh.osage_joint_offset) { + ex->osage_joint = alloc->allocate(ex->nb_jointX); - osage_node->name_index = s.read_uint32_t_reverse_endianness(); - osage_node->length = s.read_float_t_reverse_endianness(); + s.set_position(exh.osage_joint_offset, SEEK_SET); + for (int32_t i = 0; i < ex->nb_jointX; i++) { + obj_skin_osage_joint* joint = &ex->osage_joint[i]; + + joint->nid = s.read_uint32_t_reverse_endianness(); + joint->length = s.read_float_t_reverse_endianness(); s.read(0, 0x04); } } - if (exh.block_array_offset) { - ex->num_block = 0; - s.set_position(exh.block_array_offset, SEEK_SET); + if (exh.ex_node_array_offset) { + ex->num_ex_node = 0; + s.set_position(exh.ex_node_array_offset, SEEK_SET); if (!is_x) while (s.read_uint32_t()) { s.read(0, 0x04); - ex->num_block++; + ex->num_ex_node++; } else while (s.read_int64_t()) { s.read(0, 0x08); - ex->num_block++; + ex->num_ex_node++; } - obj_skin_block_header* bhs = force_malloc(ex->num_block); - s.set_position(exh.block_array_offset, SEEK_SET); + obj_skin_ex_node_header* bhs = force_malloc(ex->num_ex_node); + s.set_position(exh.ex_node_array_offset, SEEK_SET); if (!is_x) - for (int32_t i = 0; i < ex->num_block; i++) { - bhs[i].block_signature_offset = s.read_offset_f2(header_length); - bhs[i].block_offset = s.read_offset_f2(header_length); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + bhs[i].ex_node_signature_offset = s.read_offset_f2(header_length); + bhs[i].ex_node_offset = s.read_offset_f2(header_length); } else - for (int32_t i = 0; i < ex->num_block; i++) { - bhs[i].block_signature_offset = s.read_offset_x(); - bhs[i].block_offset = s.read_offset_x(); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + bhs[i].ex_node_signature_offset = s.read_offset_x(); + bhs[i].ex_node_offset = s.read_offset_x(); } - ex->block_array = alloc->allocate(ex->num_block); - for (int32_t i = 0; i < ex->num_block; i++) { - obj_skin_block* block = &ex->block_array[i]; + ex->ex_node_table = alloc->allocate(ex->num_ex_node); + for (int32_t i = 0; i < ex->num_ex_node; i++) { + obj_skin_ex_node* ex_node = &ex->ex_node_table[i]; - std::string block_signature = s.read_string_null_terminated_offset( - bhs[i].block_signature_offset); - if (block_signature.size() != 3) + std::string ex_node_signature = s.read_string_null_terminated_offset( + bhs[i].ex_node_signature_offset); + if (ex_node_signature.size() != 3) continue; - uint32_t signature = load_reverse_endianness_uint32_t(block_signature.c_str()); + uint32_t signature = load_reverse_endianness_uint32_t(ex_node_signature.c_str()); switch (signature) { case 'CLS\0': - block->type = OBJ_SKIN_BLOCK_CLOTH; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->cloth = obj_modern_read_skin_block_cloth( - alloc, s, header_length, bone_name_array, is_x); + ex_node->type = OBJ_SKIN_EX_NODE_CLOTH; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->cloth = obj_modern_read_skin_ex_node_cloth( + alloc, s, header_length, ex_node_name, is_x); break; case 'CNS\0': - block->type = OBJ_SKIN_BLOCK_CONSTRAINT; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->constraint = obj_modern_read_skin_block_constraint( - alloc, s, header_length, bone_name_array, is_x); + ex_node->type = OBJ_SKIN_EX_NODE_CONSTRAINT; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->constraint = obj_modern_read_skin_ex_node_constraint( + alloc, s, header_length, ex_node_name, is_x); break; case 'EXP\0': - block->type = OBJ_SKIN_BLOCK_EXPRESSION; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->expression = obj_modern_read_skin_block_expression( - alloc, s, header_length, bone_name_array, is_x); + ex_node->type = OBJ_SKIN_EX_NODE_EXPRESSION; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->expression = obj_modern_read_skin_ex_node_expression( + alloc, s, header_length, ex_node_name, is_x); break; case 'MOT\0': - block->type = OBJ_SKIN_BLOCK_MOTION; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->motion = obj_modern_read_skin_block_motion( - alloc, s, header_length, bone_name_array, is_x); + ex_node->type = OBJ_SKIN_EX_NODE_MOTION; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->motion = obj_modern_read_skin_ex_node_motion( + alloc, s, header_length, ex_node_name, is_x); break; case 'OSG\0': - block->type = OBJ_SKIN_BLOCK_OSAGE; - s.set_position(bhs[i].block_offset, SEEK_SET); - block->osage = obj_modern_read_skin_block_osage( - alloc, s, header_length, bone_name_array, is_x); + ex_node->type = OBJ_SKIN_EX_NODE_OSAGE; + s.set_position(bhs[i].ex_node_offset, SEEK_SET); + ex_node->osage = obj_modern_read_skin_ex_node_osage( + alloc, s, header_length, ex_node_name, is_x); break; default: break; @@ -6716,68 +6733,68 @@ static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptrnum_osage_sibling_info = 0; - s.set_position(exh.osage_sibling_info_array_offset, SEEK_SET); + if (exh.osage_constraint_tbl_offset) { + ex->num_osage_constraint = 0; + s.set_position(exh.osage_constraint_tbl_offset, SEEK_SET); while (s.read_uint32_t()) { s.read(0, 0x08); - ex->num_osage_sibling_info++; + ex->num_osage_constraint++; } - obj_skin_osage_sibling_info* osi = alloc->allocate< - obj_skin_osage_sibling_info>(ex->num_osage_sibling_info); - ex->osage_sibling_info_array = osi; - s.set_position(exh.osage_sibling_info_array_offset, SEEK_SET); - for (int32_t i = 0; i < ex->num_osage_sibling_info; i++, osi++) { - osi->name_index = s.read_uint32_t_reverse_endianness(); - osi->sibling_name_index = s.read_uint32_t_reverse_endianness(); - osi->max_distance = s.read_float_t_reverse_endianness(); + obj_skin_osage_constraint_info* osage_constraint_tbl = alloc->allocate< + obj_skin_osage_constraint_info>(ex->num_osage_constraint); + ex->osage_constraint_tbl = osage_constraint_tbl; + s.set_position(exh.osage_constraint_tbl_offset, SEEK_SET); + for (int32_t i = 0; i < ex->num_osage_constraint; i++, osage_constraint_tbl++) { + osage_constraint_tbl->dst_joint = s.read_uint32_t_reverse_endianness(); + osage_constraint_tbl->src_joint = s.read_uint32_t_reverse_endianness(); + osage_constraint_tbl->length = s.read_float_t_reverse_endianness(); } } return ex; } -static obj_skin_block_cloth* obj_modern_read_skin_block_cloth( +static obj_skin_ex_node_cloth* obj_modern_read_skin_ex_node_cloth( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { - obj_skin_block_cloth* cls = alloc->allocate(); - int64_t mesh_name_offset = s.read_offset(header_length, is_x); - int64_t backface_mesh_name_offset = s.read_offset(header_length, is_x); - cls->field_8 = s.read_uint32_t_reverse_endianness(); - cls->num_root = s.read_int32_t_reverse_endianness(); - cls->num_node = s.read_int32_t_reverse_endianness(); - cls->loop = s.read_uint32_t_reverse_endianness(); - int64_t mat_array_offset = s.read_offset(header_length, is_x); - int64_t root_array_offset = s.read_offset(header_length, is_x); - int64_t node_array_offset = s.read_offset(header_length, is_x); - int64_t mesh_index_array_offset = s.read_offset(header_length, is_x); - int64_t backface_mesh_index_array_offset = s.read_offset(header_length, is_x); - int64_t skp_root_offset = s.read_uint32_t_reverse_endianness(); - cls->reserved = s.read_uint32_t_reverse_endianness(); + obj_skin_ex_node_cloth* cls = alloc->allocate(); + int64_t omote_name_offset = s.read_offset(header_length, is_x); + int64_t ura_name_offset = s.read_offset(header_length, is_x); + cls->version = s.read_uint32_t_reverse_endianness(); + cls->width = s.read_uint32_t_reverse_endianness(); + cls->height = s.read_uint32_t_reverse_endianness(); + cls->ring_flag = s.read_uint32_t_reverse_endianness(); + int64_t matrix_offset = s.read_offset(header_length, is_x); + int64_t fix_point_offset = s.read_offset(header_length, is_x); + int64_t move_point_offset = s.read_offset(header_length, is_x); + int64_t omote_index_array_offset = s.read_offset(header_length, is_x); + int64_t ura_index_array_offset = s.read_offset(header_length, is_x); + int64_t param_offset = s.read_uint32_t_reverse_endianness(); + cls->dummy = s.read_uint32_t_reverse_endianness(); - cls->mesh_name = obj_read_utf8_string_null_terminated_offset(alloc, s, mesh_name_offset); - cls->backface_mesh_name = obj_read_utf8_string_null_terminated_offset(alloc, s, backface_mesh_name_offset); + cls->omote_name = obj_read_utf8_string_null_terminated_offset(alloc, s, omote_name_offset); + cls->ura_name = obj_read_utf8_string_null_terminated_offset(alloc, s, ura_name_offset); - if (mat_array_offset) { - int32_t max_matrix_index = -1; + if (matrix_offset) { + int32_t max_mat_idx = -1; - s.position_push(root_array_offset, SEEK_SET); - int32_t num_root = cls->num_root; - for (int32_t i = 0; i < num_root; i++) { + s.position_push(fix_point_offset, SEEK_SET); + uint32_t width = cls->width; + for (uint32_t i = 0; i < width; i++) { s.read(0x28); for (uint32_t j = 0; j < 4; j++) { uint32_t name_offset = s.read_uint32_t_reverse_endianness(); - int32_t matrix_index = s.read_int32_t_reverse_endianness(); - if (name_offset&& max_matrix_index < matrix_index) - max_matrix_index = matrix_index; + int32_t mat_idx = s.read_int32_t_reverse_endianness(); + if (name_offset&& max_mat_idx < mat_idx) + max_mat_idx = mat_idx; } } s.position_pop(); - int32_t num_mat = max_matrix_index > -1 ? max_matrix_index + 1 : 0; + uint32_t num_mat = max_mat_idx > -1 ? max_mat_idx + 1 : 0; cls->num_mat = num_mat; cls->mat_array = alloc->allocate(num_mat); - s.position_push(mat_array_offset, SEEK_SET); - for (int32_t i = 0; i < num_mat; i++) { + s.position_push(matrix_offset, SEEK_SET); + for (uint32_t i = 0; i < num_mat; i++) { mat4& mat = cls->mat_array[i]; mat.row0.x = s.read_float_t_reverse_endianness(); mat.row1.x = s.read_float_t_reverse_endianness(); @@ -6799,114 +6816,114 @@ static obj_skin_block_cloth* obj_modern_read_skin_block_cloth( s.position_pop(); } - if (root_array_offset) { - s.position_push(root_array_offset, SEEK_SET); - int32_t num_root = cls->num_root; - obj_skin_block_cloth_root* root_array = alloc->allocate(num_root); - cls->root_array = root_array; - for (int32_t i = 0; i < num_root; i++) - obj_modern_read_skin_block_cloth_root(&root_array[i], + if (fix_point_offset) { + s.position_push(fix_point_offset, SEEK_SET); + uint32_t width = cls->width; + obj_skin_ex_node_cloth_root* fix_point = alloc->allocate(width); + cls->fix_point = fix_point; + for (uint32_t i = 0; i < width; i++) + obj_modern_read_skin_ex_node_cloth_root(&fix_point[i], alloc, s, header_length, str, is_x); s.position_pop(); } - if (node_array_offset) { - s.position_push(node_array_offset, SEEK_SET); - int32_t num_root = cls->num_root; - int32_t num_node = cls->num_node; - obj_skin_block_cloth_node* node_array = alloc->allocate( - num_root * (cls->num_node - 1ULL)); - cls->node_array = node_array; - for (int32_t i = 0; i < num_node - 1; i++) - for (int32_t j = 0; j < num_root; j++) { - obj_skin_block_cloth_node* f = &node_array[(size_t)i * num_root + j]; - f->flags = s.read_uint32_t_reverse_endianness(); + if (move_point_offset) { + s.position_push(move_point_offset, SEEK_SET); + uint32_t width = cls->width; + uint32_t height = cls->height; + obj_skin_ex_node_cloth_point* move_point = alloc->allocate( + width * (cls->height - 1ULL)); + cls->move_point = move_point; + for (uint32_t i = 1; i < height; i++) + for (uint32_t j = 0; j < width; j++) { + obj_skin_ex_node_cloth_point* f = &move_point[(size_t)i * width + j]; + f->link_flag = s.read_uint32_t_reverse_endianness(); f->pos.x = s.read_float_t_reverse_endianness(); f->pos.y = s.read_float_t_reverse_endianness(); f->pos.z = s.read_float_t_reverse_endianness(); - f->delta_pos.x = s.read_float_t_reverse_endianness(); - f->delta_pos.y = s.read_float_t_reverse_endianness(); - f->delta_pos.z = s.read_float_t_reverse_endianness(); - f->dist_top = s.read_float_t_reverse_endianness(); - f->dist_bottom = s.read_float_t_reverse_endianness(); - f->dist_right = s.read_float_t_reverse_endianness(); - f->dist_left = s.read_float_t_reverse_endianness(); + f->vec.x = s.read_float_t_reverse_endianness(); + f->vec.y = s.read_float_t_reverse_endianness(); + f->vec.z = s.read_float_t_reverse_endianness(); + f->length[0] = s.read_float_t_reverse_endianness(); + f->length[1] = s.read_float_t_reverse_endianness(); + f->length[2] = s.read_float_t_reverse_endianness(); + f->length[3] = s.read_float_t_reverse_endianness(); } s.position_pop(); } - if (mesh_index_array_offset) { - s.position_push(mesh_index_array_offset, SEEK_SET); - cls->num_mesh_index = s.read_uint16_t_reverse_endianness(); - cls->mesh_index_array = alloc->allocate(cls->num_mesh_index); - s.read(cls->mesh_index_array, cls->num_mesh_index * sizeof(uint16_t)); + if (omote_index_array_offset) { + s.position_push(omote_index_array_offset, SEEK_SET); + cls->num_omote_index = s.read_uint16_t_reverse_endianness(); + cls->omote_index_array = alloc->allocate(cls->num_omote_index); + s.read(cls->omote_index_array, cls->num_omote_index * sizeof(uint16_t)); if (s.big_endian) { - uint16_t* mesh_index_array = cls->mesh_index_array; - for (int32_t i = cls->num_mesh_index; i > 0; i--, mesh_index_array++) - *mesh_index_array = reverse_endianness_uint16_t(*mesh_index_array); + uint16_t* omote_index_array = cls->omote_index_array; + for (uint32_t i = cls->num_omote_index; i; i--, omote_index_array++) + *omote_index_array = reverse_endianness_uint16_t(*omote_index_array); } s.position_pop(); } - if (backface_mesh_index_array_offset) { - s.position_push(backface_mesh_index_array_offset, SEEK_SET); - cls->num_backface_mesh_index = s.read_uint16_t_reverse_endianness(); - cls->backface_mesh_index_array = alloc->allocate(cls->num_backface_mesh_index); - s.read(cls->backface_mesh_index_array, cls->num_backface_mesh_index * sizeof(uint16_t)); + if (ura_index_array_offset) { + s.position_push(ura_index_array_offset, SEEK_SET); + cls->num_ura_index = s.read_uint16_t_reverse_endianness(); + cls->ura_index_array = alloc->allocate(cls->num_ura_index); + s.read(cls->ura_index_array, cls->num_ura_index * sizeof(uint16_t)); if (s.big_endian) { - uint16_t* backface_mesh_index_array = cls->backface_mesh_index_array; - for (int32_t i = cls->num_mesh_index; i > 0; i--, backface_mesh_index_array++) - *backface_mesh_index_array = reverse_endianness_uint16_t(*backface_mesh_index_array); + uint16_t* ura_index_array = cls->ura_index_array; + for (uint32_t i = cls->num_omote_index; i; i--, ura_index_array++) + *ura_index_array = reverse_endianness_uint16_t(*ura_index_array); } s.position_pop(); } return cls; } -static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, +static void obj_modern_write_skin_ex_node_cloth(obj_skin_ex_node_cloth* cls, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, - int64_t* mat_array_offset, int64_t* root_array_offset, int64_t* node_array_offset, - int64_t* mesh_index_array_offset, int64_t* backface_mesh_index_array_offset) { - int64_t mesh_name_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, cls->mesh_name); - int64_t backface_mesh_name_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, cls->backface_mesh_name); + int64_t* matrix_offset, int64_t* fix_point_offset, int64_t* move_point_offset, + int64_t* omote_index_array_offset, int64_t* ura_index_array_offset) { + int64_t omote_name_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, cls->omote_name); + int64_t ura_name_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, cls->ura_name); if (!is_x) { - s.write_offset_f2(mesh_name_offset, 0x20); - s.write_offset_f2(backface_mesh_name_offset, 0x20); - s.write_int32_t_reverse_endianness(cls->field_8); - s.write_int32_t_reverse_endianness(cls->num_root); - s.write_int32_t_reverse_endianness(cls->num_node); - s.write_int32_t_reverse_endianness(cls->loop); - s.write_offset_f2(cls->num_node ? *mat_array_offset : 0, 0x20); - s.write_offset_f2(cls->root_array ? *root_array_offset : 0, 0x20); - s.write_offset_f2(cls->node_array ? *node_array_offset : 0, 0x20); - s.write_offset_f2(cls->mesh_index_array ? *mesh_index_array_offset : 0, 0x20); - s.write_offset_f2(cls->backface_mesh_index_array ? *backface_mesh_index_array_offset : 0, 0x20); + s.write_offset_f2(omote_name_offset, 0x20); + s.write_offset_f2(ura_name_offset, 0x20); + s.write_uint32_t_reverse_endianness(cls->version); + s.write_uint32_t_reverse_endianness(cls->width); + s.write_uint32_t_reverse_endianness(cls->height); + s.write_uint32_t_reverse_endianness(cls->ring_flag); + s.write_offset_f2(cls->height ? *matrix_offset : 0, 0x20); + s.write_offset_f2(cls->fix_point ? *fix_point_offset : 0, 0x20); + s.write_offset_f2(cls->move_point ? *move_point_offset : 0, 0x20); + s.write_offset_f2(cls->omote_index_array ? *omote_index_array_offset : 0, 0x20); + s.write_offset_f2(cls->ura_index_array ? *ura_index_array_offset : 0, 0x20); s.write_uint32_t_reverse_endianness(0); - s.write_uint32_t_reverse_endianness(cls->reserved); + s.write_uint32_t_reverse_endianness(cls->dummy); } else { - s.write_offset_x(mesh_name_offset); - s.write_offset_x(backface_mesh_name_offset); - s.write_int32_t_reverse_endianness(cls->field_8); - s.write_int32_t_reverse_endianness(cls->num_root); - s.write_int32_t_reverse_endianness(cls->num_node); - s.write_int32_t_reverse_endianness(cls->loop); - s.write_offset_x(cls->num_node ? *mat_array_offset : 0); - s.write_offset_x(cls->root_array ? *root_array_offset : 0); - s.write_offset_x(cls->node_array ? *node_array_offset : 0); - s.write_offset_x(cls->mesh_index_array ? *mesh_index_array_offset : 0); - s.write_offset_x(cls->backface_mesh_index_array ? *backface_mesh_index_array_offset : 0); + s.write_offset_x(omote_name_offset); + s.write_offset_x(ura_name_offset); + s.write_uint32_t_reverse_endianness(cls->version); + s.write_uint32_t_reverse_endianness(cls->width); + s.write_uint32_t_reverse_endianness(cls->height); + s.write_uint32_t_reverse_endianness(cls->ring_flag); + s.write_offset_x(cls->height ? *matrix_offset : 0); + s.write_offset_x(cls->fix_point ? *fix_point_offset : 0); + s.write_offset_x(cls->move_point ? *move_point_offset : 0); + s.write_offset_x(cls->omote_index_array ? *omote_index_array_offset : 0); + s.write_offset_x(cls->ura_index_array ? *ura_index_array_offset : 0); s.write_uint32_t_reverse_endianness(0); - s.write_uint32_t_reverse_endianness(cls->reserved); + s.write_uint32_t_reverse_endianness(cls->dummy); } if (cls->mat_array) { - s.position_push(*mat_array_offset, SEEK_SET); - int32_t num_mat = cls->num_mat; - for (int32_t i = 0; i < num_mat; i++) { + s.position_push(*matrix_offset, SEEK_SET); + uint32_t num_mat = cls->num_mat; + for (uint32_t i = 0; i < num_mat; i++) { mat4& mat = cls->mat_array[i]; s.write_float_t_reverse_endianness(mat.row0.x); s.write_float_t_reverse_endianness(mat.row1.x); @@ -6924,74 +6941,74 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, s.write_float_t_reverse_endianness(mat.row1.w); s.write_float_t_reverse_endianness(mat.row2.w); s.write_float_t_reverse_endianness(mat.row3.w); - *mat_array_offset += sizeof(mat4); + *matrix_offset += sizeof(mat4); } s.position_pop(); } - if (cls->root_array) { - s.position_push(*root_array_offset, SEEK_SET); - int32_t num_root = cls->num_root; - int32_t num_node = cls->num_node; - obj_skin_block_cloth_root* root_array = cls->root_array; - for (int32_t i = 0; i < num_root; i++) - obj_modern_write_skin_block_cloth_root(&root_array[i], + if (cls->fix_point) { + s.position_push(*fix_point_offset, SEEK_SET); + uint32_t width = cls->width; + uint32_t height = cls->height; + obj_skin_ex_node_cloth_root* fix_point = cls->fix_point; + for (uint32_t i = 0; i < width; i++) + obj_modern_write_skin_ex_node_cloth_root(&fix_point[i], s, strings, string_offsets, is_x); s.position_pop(); if (!is_x) - *root_array_offset += (sizeof(int32_t) + 4 * (sizeof(int64_t) + 4 * sizeof(int32_t))) - * cls->num_root * (cls->num_node - 1ULL); + *fix_point_offset += (sizeof(int32_t) + 4 * (sizeof(int64_t) + 4 * sizeof(int32_t))) + * cls->width * (cls->height - 1ULL); else - *root_array_offset += (sizeof(int32_t) + 4 * (sizeof(int32_t) + 3 * sizeof(int32_t))) - * cls->num_root * (cls->num_node - 1ULL); + *fix_point_offset += (sizeof(int32_t) + 4 * (sizeof(int32_t) + 3 * sizeof(int32_t))) + * cls->width * (cls->height - 1ULL); } - if (cls->node_array) { - s.position_push(*node_array_offset, SEEK_SET); - int32_t num_root = cls->num_root; - int32_t num_node = cls->num_node; - obj_skin_block_cloth_node* node_array = cls->node_array; - for (int32_t i = 0; i < num_node - 1; i++) - for (int32_t j = 0; j < num_root; j++) { - obj_skin_block_cloth_node* f = &node_array[(size_t)i * num_root + j]; - s.write_uint32_t_reverse_endianness(f->flags); + if (cls->move_point) { + s.position_push(*move_point_offset, SEEK_SET); + uint32_t width = cls->width; + uint32_t height = cls->height; + obj_skin_ex_node_cloth_point* move_point = cls->move_point; + for (uint32_t i = 1; i < height; i++) + for (uint32_t j = 0; j < width; j++) { + obj_skin_ex_node_cloth_point* f = &move_point[(size_t)i * width + j]; + s.write_uint32_t_reverse_endianness(f->link_flag); s.write_float_t_reverse_endianness(f->pos.x); s.write_float_t_reverse_endianness(f->pos.y); s.write_float_t_reverse_endianness(f->pos.z); - s.write_float_t_reverse_endianness(f->delta_pos.x); - s.write_float_t_reverse_endianness(f->delta_pos.y); - s.write_float_t_reverse_endianness(f->delta_pos.z); - s.write_float_t_reverse_endianness(f->dist_top); - s.write_float_t_reverse_endianness(f->dist_bottom); - s.write_float_t_reverse_endianness(f->dist_right); - s.write_float_t_reverse_endianness(f->dist_left); + s.write_float_t_reverse_endianness(f->vec.x); + s.write_float_t_reverse_endianness(f->vec.y); + s.write_float_t_reverse_endianness(f->vec.z); + s.write_float_t_reverse_endianness(f->length[0]); + s.write_float_t_reverse_endianness(f->length[1]); + s.write_float_t_reverse_endianness(f->length[2]); + s.write_float_t_reverse_endianness(f->length[3]); } s.position_pop(); - *node_array_offset += (11 * sizeof(int32_t)) * cls->num_root * (cls->num_node - 1ULL); + *move_point_offset += (11 * sizeof(int32_t)) * cls->width * (cls->height - 1ULL); } - if (cls->mesh_index_array) { - s.position_push(*mesh_index_array_offset, SEEK_SET); - s.write_uint16_t_reverse_endianness((uint16_t)cls->num_mesh_index); - uint16_t* mesh_index_array = cls->mesh_index_array; - for (int32_t i = cls->num_mesh_index; i > 0; i--, mesh_index_array++) - s.write_uint16_t_reverse_endianness(*mesh_index_array); + if (cls->omote_index_array) { + s.position_push(*omote_index_array_offset, SEEK_SET); + s.write_uint16_t_reverse_endianness((uint16_t)cls->num_omote_index); + uint16_t* omote_index_array = cls->omote_index_array; + for (uint32_t i = cls->num_omote_index; i; i--, omote_index_array++) + s.write_uint16_t_reverse_endianness(*omote_index_array); s.position_pop(); - *mesh_index_array_offset += sizeof(uint16_t) + cls->num_mesh_index * sizeof(uint16_t); + *omote_index_array_offset += sizeof(uint16_t) + cls->num_omote_index * sizeof(uint16_t); } - if (cls->backface_mesh_index_array) { - s.position_push(*backface_mesh_index_array_offset, SEEK_SET); - s.write_uint16_t_reverse_endianness((uint16_t)cls->num_backface_mesh_index); - uint16_t* backface_mesh_index_array = cls->backface_mesh_index_array; - for (int32_t i = cls->num_backface_mesh_index; i > 0; i--, backface_mesh_index_array++) - s.write_uint16_t_reverse_endianness(*backface_mesh_index_array); + if (cls->ura_index_array) { + s.position_push(*ura_index_array_offset, SEEK_SET); + s.write_uint16_t_reverse_endianness((uint16_t)cls->num_ura_index); + uint16_t* ura_index_array = cls->ura_index_array; + for (uint32_t i = cls->num_ura_index; i; i--, ura_index_array++) + s.write_uint16_t_reverse_endianness(*ura_index_array); s.position_pop(); - *backface_mesh_index_array_offset += sizeof(uint16_t) + cls->num_backface_mesh_index * sizeof(uint16_t); + *ura_index_array_offset += sizeof(uint16_t) + cls->num_ura_index * sizeof(uint16_t); } } -static void obj_modern_read_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, +static void obj_modern_read_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { cloth_root->pos.x = s.read_float_t(); cloth_root->pos.y = s.read_float_t(); @@ -6999,17 +7016,17 @@ static void obj_modern_read_skin_block_cloth_root(obj_skin_block_cloth_root* clo cloth_root->normal.x = s.read_float_t(); cloth_root->normal.y = s.read_float_t(); cloth_root->normal.z = s.read_float_t(); - cloth_root->field_18 = s.read_float_t(); - cloth_root->field_1C = s.read_int32_t(); - cloth_root->field_20 = s.read_int32_t(); - cloth_root->field_24 = s.read_int32_t(); + cloth_root->tangent.x = s.read_float_t(); + cloth_root->tangent.y = s.read_float_t(); + cloth_root->tangent.z = s.read_float_t(); + cloth_root->tangent.w = s.read_float_t(); for (uint32_t i = 0; i < 4; i++) - obj_modern_read_skin_block_cloth_root_bone_weight(&cloth_root->bone_weights[i], + obj_modern_read_skin_ex_node_cloth_root_bone_weight(&cloth_root->weight[i], alloc, s, header_length, str, is_x); } -static void obj_modern_write_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, +static void obj_modern_write_skin_ex_node_cloth_root(obj_skin_ex_node_cloth_root* cloth_root, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { s.write_float_t(cloth_root->pos.x); s.write_float_t(cloth_root->pos.y); @@ -7017,43 +7034,43 @@ static void obj_modern_write_skin_block_cloth_root(obj_skin_block_cloth_root* cl s.write_float_t(cloth_root->normal.x); s.write_float_t(cloth_root->normal.y); s.write_float_t(cloth_root->normal.z); - s.write_float_t(cloth_root->field_18); - s.write_int32_t(cloth_root->field_1C); - s.write_int32_t(cloth_root->field_20); - s.write_int32_t(cloth_root->field_24); + s.write_float_t(cloth_root->tangent.x); + s.write_float_t(cloth_root->tangent.y); + s.write_float_t(cloth_root->tangent.z); + s.write_float_t(cloth_root->tangent.w); for (uint32_t j = 0; j < 4; j++) - obj_modern_write_skin_block_cloth_root_bone_weight(&cloth_root->bone_weights[j], + obj_modern_write_skin_ex_node_cloth_root_bone_weight(&cloth_root->weight[j], s, strings, string_offsets, is_x); } -static void obj_modern_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_modern_read_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { int64_t bone_name_offset = s.read_offset(header_length, is_x); bone_weight->bone_name = obj_read_utf8_string_null_terminated_offset(alloc, s, bone_name_offset); bone_weight->weight = s.read_float_t_reverse_endianness(); - bone_weight->matrix_index = s.read_uint32_t_reverse_endianness(); - bone_weight->reserved = s.read_uint32_t_reverse_endianness(); + bone_weight->mat_idx = s.read_uint32_t_reverse_endianness(); + bone_weight->dummy = s.read_uint32_t_reverse_endianness(); if (is_x) s.read(0, 0x04); } -static void obj_modern_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, +static void obj_modern_write_skin_ex_node_cloth_root_bone_weight(obj_skin_ex_node_cloth_weight* bone_weight, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { int64_t bone_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, bone_weight->bone_name); s.write_offset(bone_name_offset, 0x20, is_x); s.write_float_t_reverse_endianness(bone_weight->weight); - s.write_uint32_t_reverse_endianness(bone_weight->matrix_index); - s.write_uint32_t_reverse_endianness(bone_weight->reserved); + s.write_uint32_t_reverse_endianness(bone_weight->mat_idx); + s.write_uint32_t_reverse_endianness(bone_weight->dummy); if (is_x) s.write(0x04); } -static obj_skin_block_constraint* obj_modern_read_skin_block_constraint( +static obj_skin_ex_node_constraint* obj_modern_read_skin_ex_node_constraint( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { - obj_skin_block_constraint* cns = alloc->allocate(); - obj_modern_read_skin_block_node(&cns->node, alloc, s, header_length, str, is_x); + obj_skin_ex_node_constraint* cns = alloc->allocate(); + obj_modern_read_skin_ex_node_transform(&cns->transform, alloc, s, header_length, str, is_x); int64_t type_offset = s.read_offset(header_length, is_x); char* type = s.read_utf8_string_null_terminated_offset(type_offset); @@ -7061,40 +7078,40 @@ static obj_skin_block_constraint* obj_modern_read_skin_block_constraint( int64_t name_offset = s.read_offset(header_length, is_x); char* name = s.read_utf8_string_null_terminated_offset(name_offset); - cns->name_index = 0; + cns->node_name = 0; if (name) for (const char** i = str; *i; i++) if (!str_utils_compare(name, *i)) { - cns->name_index = 0x8000 | (int32_t)(i - str); + cns->node_name = 0x8000 | (int32_t)(i - str); break; } free_def(name); - cns->coupling = (obj_skin_block_constraint_coupling)s.read_uint32_t_reverse_endianness(); + cns->nb_src = s.read_uint32_t_reverse_endianness(); - int64_t source_node_name_offset = s.read_offset(header_length, is_x); - cns->source_node_name = obj_read_utf8_string_null_terminated_offset(alloc, s, source_node_name_offset); + int64_t src_name_offset = s.read_offset(header_length, is_x); + cns->src_name = obj_read_utf8_string_null_terminated_offset(alloc, s, src_name_offset); if (!type) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; cns->data = 0; } else if (!str_utils_compare(type, "Orientation")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION; - obj_skin_block_constraint_orientation* orientation - = alloc->allocate(); + obj_skin_ex_node_constraint_orientation* orientation + = alloc->allocate(); orientation->offset.x = s.read_float_t_reverse_endianness(); orientation->offset.y = s.read_float_t_reverse_endianness(); orientation->offset.z = s.read_float_t_reverse_endianness(); cns->orientation = orientation; } else if (!str_utils_compare(type, "Direction")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION; - obj_skin_block_constraint_direction* direction - = alloc->allocate(); - obj_modern_read_skin_block_constraint_up_vector(&direction->up_vector, + obj_skin_ex_node_constraint_direction* direction + = alloc->allocate(); + obj_modern_read_skin_ex_node_constraint_up_vector(&direction->up_vector, alloc, s, header_length, str, is_x); direction->align_axis.x = s.read_float_t_reverse_endianness(); direction->align_axis.y = s.read_float_t_reverse_endianness(); @@ -7105,80 +7122,80 @@ static obj_skin_block_constraint* obj_modern_read_skin_block_constraint( cns->direction = direction; } else if (!str_utils_compare(type, "Position")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_POSITION; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION; - obj_skin_block_constraint_position* position - = alloc->allocate(); - obj_modern_read_skin_block_constraint_up_vector(&position->up_vector, + obj_skin_ex_node_constraint_position* position + = alloc->allocate(); + obj_modern_read_skin_ex_node_constraint_up_vector(&position->up_vector, alloc, s, header_length, str, is_x); - obj_modern_read_skin_block_constraint_attach_point(&position->constrained_object, + obj_modern_read_skin_ex_node_constraint_attach_point(&position->constrained_object, s, header_length, str, is_x); - obj_modern_read_skin_block_constraint_attach_point(&position->constraining_object, + obj_modern_read_skin_ex_node_constraint_attach_point(&position->constraining_object, s, header_length, str, is_x); cns->position = position; } else if (!str_utils_compare(type, "Distance")) { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE; - obj_skin_block_constraint_distance* distance - = alloc->allocate(); - obj_modern_read_skin_block_constraint_up_vector(&distance->up_vector, + obj_skin_ex_node_constraint_distance* distance + = alloc->allocate(); + obj_modern_read_skin_ex_node_constraint_up_vector(&distance->up_vector, alloc, s, header_length, str, is_x); distance->distance = s.read_float_t_reverse_endianness(); - obj_modern_read_skin_block_constraint_attach_point(&distance->constrained_object, + obj_modern_read_skin_ex_node_constraint_attach_point(&distance->constrained_object, s, header_length, str, is_x); - obj_modern_read_skin_block_constraint_attach_point(&distance->constraining_object, + obj_modern_read_skin_ex_node_constraint_attach_point(&distance->constraining_object, s, header_length, str, is_x); cns->distance = distance; } else { - cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns->type = OBJ_SKIN_EX_NODE_CONSTRAINT_NONE; cns->data = 0; } free_def(type); return cns; } -static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* cns, - stream& s, std::vector& strings, std::vector& string_offsets, const char** bone_name_array, +static void obj_modern_write_skin_ex_node_constraint(obj_skin_ex_node_constraint* cns, + stream& s, std::vector& strings, std::vector& string_offsets, const char** ex_node_name, bool is_x, int64_t* offsets) { - obj_modern_write_skin_block_node(&cns->node, s, strings, string_offsets, is_x); + obj_modern_write_skin_ex_node_transform(&cns->transform, s, strings, string_offsets, is_x); int64_t type_offset = 0; switch (cns->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: type_offset = offsets[0]; break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: type_offset = offsets[1]; break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: type_offset = offsets[2]; break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: type_offset = offsets[3]; break; } s.write_offset(type_offset, 0x20, is_x); int64_t name_offset = obj_skin_strings_get_string_offset_by_index(strings, - string_offsets, bone_name_array, cns->name_index); + string_offsets, ex_node_name, cns->node_name); s.write_offset(name_offset, 0x20, is_x); - s.write_int32_t_reverse_endianness(cns->coupling); + s.write_uint32_t_reverse_endianness(cns->nb_src); - int64_t source_node_name_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, cns->source_node_name); - s.write_offset(source_node_name_offset, 0x20, is_x); + int64_t src_name_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, cns->src_name); + s.write_offset(src_name_offset, 0x20, is_x); switch (cns->type) { - case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: + case OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION: s.write_float_t_reverse_endianness(cns->orientation->offset.x); s.write_float_t_reverse_endianness(cns->orientation->offset.y); s.write_float_t_reverse_endianness(cns->orientation->offset.z); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: - obj_modern_write_skin_block_constraint_up_vector(&cns->direction->up_vector, + case OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION: + obj_modern_write_skin_ex_node_constraint_up_vector(&cns->direction->up_vector, s, strings, string_offsets, is_x); s.write_float_t_reverse_endianness(cns->direction->align_axis.x); s.write_float_t_reverse_endianness(cns->direction->align_axis.y); @@ -7187,27 +7204,27 @@ static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* cn s.write_float_t_reverse_endianness(cns->direction->target_offset.y); s.write_float_t_reverse_endianness(cns->direction->target_offset.z); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: - obj_modern_write_skin_block_constraint_up_vector(&cns->position->up_vector, + case OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION: + obj_modern_write_skin_ex_node_constraint_up_vector(&cns->position->up_vector, s, strings, string_offsets, is_x); - obj_modern_write_skin_block_constraint_attach_point(&cns->position->constrained_object, + obj_modern_write_skin_ex_node_constraint_attach_point(&cns->position->constrained_object, s, strings, string_offsets, is_x); - obj_modern_write_skin_block_constraint_attach_point(&cns->position->constraining_object, + obj_modern_write_skin_ex_node_constraint_attach_point(&cns->position->constraining_object, s, strings, string_offsets, is_x); break; - case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: - obj_modern_write_skin_block_constraint_up_vector(&cns->distance->up_vector, + case OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE: + obj_modern_write_skin_ex_node_constraint_up_vector(&cns->distance->up_vector, s, strings, string_offsets, is_x); s.write_float_t_reverse_endianness(cns->distance->distance); - obj_modern_write_skin_block_constraint_attach_point(&cns->distance->constrained_object, + obj_modern_write_skin_ex_node_constraint_attach_point(&cns->distance->constrained_object, s, strings, string_offsets, is_x); - obj_modern_write_skin_block_constraint_attach_point(&cns->distance->constraining_object, + obj_modern_write_skin_ex_node_constraint_attach_point(&cns->distance->constraining_object, s, strings, string_offsets, is_x); break; } } -static void obj_modern_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, +static void obj_modern_read_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, uint32_t header_length, const char** str, bool is_x) { attach_point->affected_by_orientation = s.read_uint32_t_reverse_endianness() != 0; attach_point->affected_by_scaling = s.read_uint32_t_reverse_endianness() != 0; @@ -7216,7 +7233,7 @@ static void obj_modern_read_skin_block_constraint_attach_point(obj_skin_block_co attach_point->offset.z = s.read_float_t_reverse_endianness(); } -static void obj_modern_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, +static void obj_modern_write_skin_ex_node_constraint_attach_point(obj_skin_ex_node_constraint_attach_point* attach_point, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { s.write_int32_t_reverse_endianness(attach_point->affected_by_orientation ? 1 : 0); s.write_int32_t_reverse_endianness(attach_point->affected_by_scaling ? 1 : 0); @@ -7225,7 +7242,7 @@ static void obj_modern_write_skin_block_constraint_attach_point(obj_skin_block_c s.write_float_t_reverse_endianness(attach_point->offset.z); } -static void obj_modern_read_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_modern_read_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { up_vector->active = !!s.read_uint32_t_reverse_endianness(); up_vector->roll = s.read_float_t_reverse_endianness(); @@ -7240,7 +7257,7 @@ static void obj_modern_read_skin_block_constraint_up_vector(obj_skin_block_const up_vector->name = obj_read_utf8_string_null_terminated_offset(alloc, s, name_offset); } -static void obj_modern_write_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, +static void obj_modern_write_skin_ex_node_constraint_up_vector(obj_skin_ex_node_constraint_up_vector* up_vector, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { s.write_int32_t_reverse_endianness(up_vector->active ? 1 : 0); s.write_float_t_reverse_endianness(up_vector->roll); @@ -7256,84 +7273,82 @@ static void obj_modern_write_skin_block_constraint_up_vector(obj_skin_block_cons s.write_offset(name_offset, 0x20, is_x); } -static obj_skin_block_expression* obj_modern_read_skin_block_expression( +static obj_skin_ex_node_expression* obj_modern_read_skin_ex_node_expression( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { - obj_skin_block_expression* exp = alloc->allocate(); - obj_modern_read_skin_block_node(&exp->node, alloc, s, header_length, str, is_x); + obj_skin_ex_node_expression* exp = alloc->allocate(); + obj_modern_read_skin_ex_node_transform(&exp->transform, alloc, s, header_length, str, is_x); int64_t name_offset = s.read_offset(header_length, is_x); char* name = s.read_utf8_string_null_terminated_offset(name_offset); - exp->name_index = 0; + exp->node_name = 0; if (name) for (const char** i = str; *i; i++) if (!str_utils_compare(name, *i)) { - exp->name_index = 0x8000 | (int32_t)(i - str); + exp->node_name = 0x8000 | (int32_t)(i - str); break; } free_def(name); - int32_t num_expression = s.read_int32_t_reverse_endianness(); - num_expression = min_def(num_expression, 9); - exp->num_expression = num_expression; + int32_t nb_src = s.read_int32_t_reverse_endianness(); + nb_src = min_def(nb_src, 9); + exp->nb_src = nb_src; if (!is_x) - for (int32_t i = 0; i < num_expression; i++) { - int64_t expression_offset = s.read_offset_f2(header_length); - if (expression_offset) - exp->expression_array[i] - = obj_read_utf8_string_null_terminated_offset(alloc, s, expression_offset); + for (int32_t i = 0; i < nb_src; i++) { + int64_t script_offset = s.read_offset_f2(header_length); + if (script_offset) + exp->script[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, script_offset); } else - for (int32_t i = 0; i < num_expression; i++) { - int64_t expression_offset = s.read_offset_x(); - if (expression_offset) - exp->expression_array[i] - = obj_read_utf8_string_null_terminated_offset(alloc, s, expression_offset); + for (int32_t i = 0; i < nb_src; i++) { + int64_t script_offset = s.read_offset_x(); + if (script_offset) + exp->script[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, script_offset); } - for (int32_t i = num_expression; i < 9; i++) - exp->expression_array[i] = 0; + for (int32_t i = nb_src; i < 9; i++) + exp->script[i] = 0; return exp; } -static void obj_modern_write_skin_block_expression(obj_skin_block_expression* exp, +static void obj_modern_write_skin_ex_node_expression(obj_skin_ex_node_expression* exp, stream& s, std::vector& strings, std::vector& string_offsets, - const char** bone_name_array, bool is_x) { - obj_modern_write_skin_block_node(&exp->node, s, strings, string_offsets, is_x); + const char** ex_node_name, bool is_x) { + obj_modern_write_skin_ex_node_transform(&exp->transform, s, strings, string_offsets, is_x); int64_t name_offset = obj_skin_strings_get_string_offset_by_index(strings, - string_offsets, bone_name_array, exp->name_index); + string_offsets, ex_node_name, exp->node_name); s.write_offset(name_offset, 0x20, is_x); - int32_t num_expression = exp->num_expression; - num_expression = min_def(num_expression, 9); - s.write_int32_t_reverse_endianness(num_expression); + int32_t nb_src = exp->nb_src; + nb_src = min_def(nb_src, 9); + s.write_int32_t_reverse_endianness(nb_src); if (!is_x) { - for (int32_t i = 0; i < num_expression; i++) { - int64_t expression_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, exp->expression_array[i]); - s.write_offset_f2((int32_t)expression_offset, 0x20); + for (int32_t i = 0; i < nb_src; i++) { + int64_t script_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, exp->script[i]); + s.write_offset_f2((int32_t)script_offset, 0x20); } - for (int32_t i = num_expression; i < 9; i++) + for (int32_t i = nb_src; i < 9; i++) s.write_offset_f2(0, 0x20); } else { - for (int32_t i = 0; i < num_expression; i++) { - int64_t expression_offset = obj_skin_strings_get_string_offset(strings, - string_offsets, exp->expression_array[i]); - s.write_offset_x(expression_offset); + for (int32_t i = 0; i < nb_src; i++) { + int64_t script_offset = obj_skin_strings_get_string_offset(strings, + string_offsets, exp->script[i]); + s.write_offset_x(script_offset); } - for (int32_t i = num_expression; i < 9; i++) + for (int32_t i = nb_src; i < 9; i++) s.write_offset_x(0); } } -static obj_skin_block_motion* obj_modern_read_skin_block_motion( +static obj_skin_ex_node_motion* obj_modern_read_skin_ex_node_motion( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { - obj_skin_block_motion* mot = alloc->allocate(); - obj_modern_read_skin_block_node(&mot->node, alloc, s, header_length, str, is_x); + obj_skin_ex_node_motion* mot = alloc->allocate(); + obj_modern_read_skin_ex_node_transform(&mot->transform, alloc, s, header_length, str, is_x); int64_t name_offset = s.read_offset(header_length, is_x); mot->num_node = s.read_int32_t_reverse_endianness(); @@ -7341,12 +7356,12 @@ static obj_skin_block_motion* obj_modern_read_skin_block_motion( int64_t bone_matrix_array_offset = s.read_offset(header_length, is_x); if (!is_x) { - mot->name_index = 0; + mot->node_name = 0; char* name = s.read_utf8_string_null_terminated_offset(name_offset); if (name) for (const char** i = str; *i; i++) if (!str_utils_compare(name, *i)) { - mot->name_index = 0x8000 | (int32_t)(i - str); + mot->node_name = 0x8000 | (int32_t)(i - str); break; } free_def(name); @@ -7364,7 +7379,7 @@ static obj_skin_block_motion* obj_modern_read_skin_block_motion( if (bone_name_array_offset) { s.position_push(bone_name_array_offset, SEEK_SET); for (int32_t i = 0; i < mot->num_node; i++) - mot->node_array[i].name_index = s.read_uint32_t_reverse_endianness(); + mot->node_array[i].node_name = s.read_uint32_t_reverse_endianness(); s.position_pop(); } @@ -7394,15 +7409,15 @@ static obj_skin_block_motion* obj_modern_read_skin_block_motion( return mot; } -static void obj_modern_write_skin_block_motion(obj_skin_block_motion* mot, +static void obj_modern_write_skin_ex_node_motion(obj_skin_ex_node_motion* mot, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, - const char** bone_name_array, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset) { - obj_modern_write_skin_block_node(&mot->node, s, strings, string_offsets, is_x); + const char** ex_node_name, int64_t* bone_name_array_offset, int64_t* bone_matrix_array_offset) { + obj_modern_write_skin_ex_node_transform(&mot->transform, s, strings, string_offsets, is_x); int64_t name_offset; if (!is_x) name_offset = obj_skin_strings_get_string_offset_by_index(strings, - string_offsets, bone_name_array, mot->name_index); + string_offsets, ex_node_name, mot->node_name); else name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, mot->name); @@ -7414,7 +7429,7 @@ static void obj_modern_write_skin_block_motion(obj_skin_block_motion* mot, if (mot->node_array) { s.position_push(*bone_name_array_offset, SEEK_SET); for (int32_t i = 0; i < mot->num_node; i++) - s.write_uint32_t_reverse_endianness(mot->node_array[i].name_index); + s.write_uint32_t_reverse_endianness(mot->node_array[i].node_name); s.position_pop(); *bone_name_array_offset += mot->num_node * sizeof(uint32_t); @@ -7443,7 +7458,7 @@ static void obj_modern_write_skin_block_motion(obj_skin_block_motion* mot, } } -static void obj_modern_read_skin_block_node(obj_skin_block_node* node, +static void obj_modern_read_skin_ex_node_transform(obj_skin_ex_node_transform* node, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { int64_t parent_name = s.read_offset(header_length, is_x); node->parent_name = obj_read_utf8_string_null_terminated_offset(alloc, s, parent_name); @@ -7461,7 +7476,7 @@ static void obj_modern_read_skin_block_node(obj_skin_block_node* node, s.read(0, 0x04); } -static void obj_modern_write_skin_block_node(obj_skin_block_node* node, +static void obj_modern_write_skin_ex_node_transform(obj_skin_ex_node_transform* node, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { int64_t parent_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, node->parent_name); @@ -7480,15 +7495,15 @@ static void obj_modern_write_skin_block_node(obj_skin_block_node* node, s.write(0x04); } -static obj_skin_block_osage* obj_modern_read_skin_block_osage( +static obj_skin_ex_node_osage* obj_modern_read_skin_ex_node_osage( prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { - obj_skin_block_osage* osg = alloc->allocate(); - obj_modern_read_skin_block_node(&osg->node, alloc, s, header_length, str, is_x); + obj_skin_ex_node_osage* osg = alloc->allocate(); + obj_modern_read_skin_ex_node_transform(&osg->transform, alloc, s, header_length, str, is_x); - osg->start_index = s.read_uint32_t_reverse_endianness(); - osg->count = s.read_uint32_t_reverse_endianness(); - osg->name_index = s.read_uint32_t_reverse_endianness(); - osg->end_name_index = s.read_uint32_t_reverse_endianness(); + osg->joint_ofs = s.read_uint32_t_reverse_endianness(); + osg->nb_joint = s.read_uint32_t_reverse_endianness(); + osg->root_idx = s.read_uint32_t_reverse_endianness(); + osg->efc_idx = s.read_uint32_t_reverse_endianness(); if (!is_x) s.read(0, 0x14); @@ -7499,19 +7514,19 @@ static obj_skin_block_osage* obj_modern_read_skin_block_osage( s.read(0, 0x18); } - osg->node_array = 0; - osg->num_node = 0; + osg->joint_rotation_array = 0; + osg->num_joint_rotation = 0; return osg; } -static void obj_modern_write_skin_block_osage(obj_skin_block_osage* osg, +static void obj_modern_write_skin_ex_node_osage(obj_skin_ex_node_osage* osg, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { - obj_modern_write_skin_block_node(&osg->node, s, strings, string_offsets, is_x); + obj_modern_write_skin_ex_node_transform(&osg->transform, s, strings, string_offsets, is_x); - s.write_int32_t_reverse_endianness(osg->start_index); - s.write_int32_t_reverse_endianness(osg->count); - s.write_uint32_t_reverse_endianness(osg->name_index); - s.write_uint32_t_reverse_endianness(osg->end_name_index); + s.write_uint32_t_reverse_endianness(osg->joint_ofs); + s.write_uint32_t_reverse_endianness(osg->nb_joint); + s.write_uint32_t_reverse_endianness(osg->root_idx); + s.write_uint32_t_reverse_endianness(osg->efc_idx); if (!is_x) s.write(0x14); diff --git a/src/KKdLib/obj.hpp b/src/KKdLib/obj.hpp index 63cadd34..8bf38d65 100644 --- a/src/KKdLib/obj.hpp +++ b/src/KKdLib/obj.hpp @@ -100,26 +100,21 @@ enum obj_primitive_type : uint32_t { OBJ_PRIMITIVE_POLYGON = 0x09, }; -enum obj_skin_block_constraint_type : uint32_t { - OBJ_SKIN_BLOCK_CONSTRAINT_NONE = 0, - OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION, - OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION, - OBJ_SKIN_BLOCK_CONSTRAINT_POSITION, - OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE, +enum obj_skin_ex_node_constraint_type : uint32_t { + OBJ_SKIN_EX_NODE_CONSTRAINT_NONE = 0, + OBJ_SKIN_EX_NODE_CONSTRAINT_ORIENTATION, + OBJ_SKIN_EX_NODE_CONSTRAINT_DIRECTION, + OBJ_SKIN_EX_NODE_CONSTRAINT_POSITION, + OBJ_SKIN_EX_NODE_CONSTRAINT_DISTANCE, }; -enum obj_skin_block_constraint_coupling : uint32_t { - OBJ_SKIN_BLOCK_CONSTRAINT_COUPLING_RIGID = 0x01, - OBJ_SKIN_BLOCK_CONSTRAINT_COUPLING_SOFT = 0x03, -}; - -enum obj_skin_block_type : uint32_t { - OBJ_SKIN_BLOCK_NONE = 0, - OBJ_SKIN_BLOCK_CLOTH, - OBJ_SKIN_BLOCK_CONSTRAINT, - OBJ_SKIN_BLOCK_EXPRESSION, - OBJ_SKIN_BLOCK_MOTION, - OBJ_SKIN_BLOCK_OSAGE, +enum obj_skin_ex_node_type : uint32_t { + OBJ_SKIN_EX_NODE_NONE = 0, + OBJ_SKIN_EX_NODE_CLOTH, + OBJ_SKIN_EX_NODE_CONSTRAINT, + OBJ_SKIN_EX_NODE_EXPRESSION, + OBJ_SKIN_EX_NODE_MOTION, + OBJ_SKIN_EX_NODE_OSAGE, }; enum obj_skin_skin_param_coli_type { @@ -146,6 +141,11 @@ enum obj_vertex_format : uint32_t { OBJ_VERTEX_UNKNOWN = 0x800, }; +enum ROTTYPE { + ROTTYPE_YZ = 0x00, + ROTTYPE_ZY = 0x01, +}; + struct obj_axis_aligned_bounding_box { vec3 center; vec3 size; @@ -414,247 +414,247 @@ struct obj_mesh { obj_mesh(); }; -struct obj_skin_block_node { +struct obj_skin_ex_node_transform { const char* parent_name; vec3 position; vec3 rotation; vec3 scale; - obj_skin_block_node(); + obj_skin_ex_node_transform(); }; struct obj_skin_skin_param_coli { obj_skin_skin_param_coli_type type; - int32_t bone0_index; - int32_t bone1_index; + int32_t nid0; + int32_t nid1; float_t radius; - vec3 bone0_pos; - vec3 bone1_pos; + vec3 pos0; + vec3 pos1; obj_skin_skin_param_coli(); }; struct obj_skin_skin_param { - int32_t unk0; + int32_t root_nid; float_t force; float_t force_gain; float_t air_res; - float_t rot_y; - float_t rot_z; - float_t hinge_y; - float_t hinge_z; + float_t angle[2]; + float_t limit[2]; const char* name; - obj_skin_skin_param_coli* coli; - int32_t coli_count; + obj_skin_skin_param_coli* coli_array; + int32_t num_coli; float_t coli_r; float_t friction; float_t wind_afc; - int32_t unk44; + ROTTYPE rottype; obj_skin_skin_param(); }; -struct obj_skin_block_cloth_root_bone_weight { +struct obj_skin_ex_node_cloth_weight { const char* bone_name; float_t weight; - int32_t matrix_index; - int32_t reserved; + int32_t mat_idx; + int32_t dummy; - obj_skin_block_cloth_root_bone_weight(); + obj_skin_ex_node_cloth_weight(); }; -struct obj_skin_block_cloth_root { +struct obj_skin_ex_node_cloth_root { vec3 pos; vec3 normal; - float_t field_18; - int32_t field_1C; - int32_t field_20; - int32_t field_24; - obj_skin_block_cloth_root_bone_weight bone_weights[4]; + vec4 tangent; + obj_skin_ex_node_cloth_weight weight[4]; - obj_skin_block_cloth_root(); + obj_skin_ex_node_cloth_root(); }; -struct obj_skin_block_cloth_node { - uint32_t flags; +struct obj_skin_ex_node_cloth_point { + uint32_t link_flag; vec3 pos; - vec3 delta_pos; - float_t dist_top; - float_t dist_bottom; - float_t dist_right; - float_t dist_left; + vec3 vec; + float_t length[4]; - obj_skin_block_cloth_node(); + obj_skin_ex_node_cloth_point(); }; -struct obj_skin_block_cloth { - const char* mesh_name; - const char* backface_mesh_name; - uint32_t field_8; - int32_t num_root; - int32_t num_node; - uint32_t loop; +struct obj_skin_ex_node_cloth { + const char* omote_name; + const char* ura_name; + uint32_t version; + uint32_t width; + uint32_t height; + uint32_t ring_flag; mat4* mat_array; - int32_t num_mat; - obj_skin_block_cloth_root* root_array; - obj_skin_block_cloth_node* node_array; - uint16_t* mesh_index_array; - int32_t num_mesh_index; - uint16_t* backface_mesh_index_array; - int32_t num_backface_mesh_index; - obj_skin_skin_param* skin_param; - uint32_t reserved; + uint32_t num_mat; + obj_skin_ex_node_cloth_root* fix_point; + obj_skin_ex_node_cloth_point* move_point; + uint16_t* omote_index_array; + uint32_t num_omote_index; + uint16_t* ura_index_array; + uint32_t num_ura_index; + obj_skin_skin_param* param; + uint32_t dummy; - obj_skin_block_cloth(); + obj_skin_ex_node_cloth(); }; -struct obj_skin_block_constraint_attach_point { +struct obj_skin_ex_node_constraint_attach_point { bool affected_by_orientation; bool affected_by_scaling; vec3 offset; - obj_skin_block_constraint_attach_point(); + obj_skin_ex_node_constraint_attach_point(); }; -struct obj_skin_block_constraint_up_vector { +struct obj_skin_ex_node_constraint_up_vector { bool active; float_t roll; vec3 affected_axis; vec3 point_at; const char* name; - obj_skin_block_constraint_up_vector(); + obj_skin_ex_node_constraint_up_vector(); }; -struct obj_skin_block_constraint_direction { - obj_skin_block_constraint_up_vector up_vector; +struct obj_skin_ex_node_constraint_direction { + obj_skin_ex_node_constraint_up_vector up_vector; vec3 align_axis; vec3 target_offset; - obj_skin_block_constraint_direction(); + obj_skin_ex_node_constraint_direction(); }; -struct obj_skin_block_constraint_distance { - obj_skin_block_constraint_up_vector up_vector; +struct obj_skin_ex_node_constraint_distance { + obj_skin_ex_node_constraint_up_vector up_vector; float_t distance; - obj_skin_block_constraint_attach_point constrained_object; - obj_skin_block_constraint_attach_point constraining_object; + obj_skin_ex_node_constraint_attach_point constrained_object; + obj_skin_ex_node_constraint_attach_point constraining_object; - obj_skin_block_constraint_distance(); + obj_skin_ex_node_constraint_distance(); }; -struct obj_skin_block_constraint_orientation { +struct obj_skin_ex_node_constraint_orientation { vec3 offset; - obj_skin_block_constraint_orientation(); + obj_skin_ex_node_constraint_orientation(); }; -struct obj_skin_block_constraint_position { - obj_skin_block_constraint_up_vector up_vector; - obj_skin_block_constraint_attach_point constrained_object; - obj_skin_block_constraint_attach_point constraining_object; +struct obj_skin_ex_node_constraint_position { + obj_skin_ex_node_constraint_up_vector up_vector; + obj_skin_ex_node_constraint_attach_point constrained_object; + obj_skin_ex_node_constraint_attach_point constraining_object; - obj_skin_block_constraint_position(); + obj_skin_ex_node_constraint_position(); }; -struct obj_skin_block_constraint { - obj_skin_block_node node; - uint32_t name_index; - const char* source_node_name; - obj_skin_block_constraint_coupling coupling; - obj_skin_block_constraint_type type; +struct obj_skin_ex_node_constraint { + obj_skin_ex_node_transform transform; + uint32_t node_name; + uint32_t nb_src; + const char* src_name; + obj_skin_ex_node_constraint_type type; union { void* data; - obj_skin_block_constraint_direction* direction; - obj_skin_block_constraint_distance* distance; - obj_skin_block_constraint_orientation* orientation; - obj_skin_block_constraint_position* position; + obj_skin_ex_node_constraint_direction* direction; + obj_skin_ex_node_constraint_distance* distance; + obj_skin_ex_node_constraint_orientation* orientation; + obj_skin_ex_node_constraint_position* position; }; - obj_skin_block_constraint(); + obj_skin_ex_node_constraint(); }; -struct obj_skin_block_expression { - obj_skin_block_node node; - uint32_t name_index; - int32_t num_expression; - const char* expression_array[9]; +struct obj_skin_ex_node_expression { + obj_skin_ex_node_transform transform; + uint32_t node_name; + int32_t nb_src; + const char* script[9]; - obj_skin_block_expression(); + obj_skin_ex_node_expression(); }; struct obj_skin_motion_node { - uint32_t name_index; + uint32_t node_name; mat4 inv_bind_pose_mat; obj_skin_motion_node(); }; -struct obj_skin_block_motion { - obj_skin_block_node node; +struct obj_skin_ex_node_motion { + obj_skin_ex_node_transform transform; union { const char* name; - uint32_t name_index; + uint32_t node_name; }; obj_skin_motion_node* node_array; int32_t num_node; - obj_skin_block_motion(); + obj_skin_ex_node_motion(); }; -struct obj_skin_osage_node { - uint32_t name_index; +struct obj_skin_osage_joint_rotation { + uint32_t nid; float_t length; vec3 rotation; - obj_skin_osage_node(); + obj_skin_osage_joint_rotation(); }; -struct obj_skin_block_osage { - obj_skin_block_node node; - uint32_t start_index; - int32_t count; - obj_skin_osage_node* node_array; - int32_t num_node; +struct obj_skin_ex_node_osage { + obj_skin_ex_node_transform transform; + uint32_t joint_ofs; + uint32_t nb_joint; + obj_skin_osage_joint_rotation* joint_rotation_array; + int32_t num_joint_rotation; obj_skin_skin_param* skin_param; - uint32_t name_index; - uint32_t end_name_index; + uint32_t root_idx; + uint32_t efc_idx; const char* motion_node_name; - obj_skin_block_osage(); + obj_skin_ex_node_osage(); }; -struct obj_skin_block { - obj_skin_block_type type; +struct obj_skin_ex_node { + obj_skin_ex_node_type type; union { - obj_skin_block_node* node; - obj_skin_block_cloth* cloth; - obj_skin_block_constraint* constraint; - obj_skin_block_expression* expression; - obj_skin_block_motion* motion; - obj_skin_block_osage* osage; + obj_skin_ex_node_transform* transform; + obj_skin_ex_node_cloth* cloth; + obj_skin_ex_node_constraint* constraint; + obj_skin_ex_node_expression* expression; + obj_skin_ex_node_motion* motion; + obj_skin_ex_node_osage* osage; }; - obj_skin_block(); + obj_skin_ex_node(); }; -struct obj_skin_osage_sibling_info { - uint32_t name_index; - uint32_t sibling_name_index; - float_t max_distance; +struct obj_skin_osage_constraint_info { + uint32_t dst_joint; + uint32_t src_joint; + float_t length; - obj_skin_osage_sibling_info(); + obj_skin_osage_constraint_info(); +}; + +struct obj_skin_osage_joint { + uint32_t nid; + float_t length; + + obj_skin_osage_joint(); }; struct obj_skin_ex_data { - obj_skin_osage_node* osage_node_array; - int32_t num_osage_node; - obj_skin_block* block_array; - int32_t num_block; - const char** bone_name_array; - int32_t num_bone_name; - obj_skin_osage_sibling_info* osage_sibling_info_array; - int32_t num_osage_sibling_info; + int32_t nb_jointX; + const char* osage_root; + obj_skin_osage_joint* osage_joint; + obj_skin_ex_node* ex_node_table; + int32_t num_ex_node; + int32_t nb_node_name; + const char** ex_node_name; + obj_skin_osage_constraint_info* osage_constraint_tbl; + int32_t num_osage_constraint; int64_t reserved[7]; obj_skin_ex_data(); diff --git a/src/ReDIVA/data_test/rob_osage_test.cpp b/src/ReDIVA/data_test/rob_osage_test.cpp index faf243e2..0e4a5fb2 100644 --- a/src/ReDIVA/data_test/rob_osage_test.cpp +++ b/src/ReDIVA/data_test/rob_osage_test.cpp @@ -491,7 +491,7 @@ bool RobOsageTest::ctrl() { for (int32_t i = 0; i < ITEM_MAX; i++) { rob_chara_item_equip_object* itm_eq_obj = rob_itm_equip->get_item_equip_object((::item_id)i); ::obj* obj = objset_info_storage_get_obj(itm_eq_obj->obj_info); - if (!obj || !itm_eq_obj->osage_blocks.size() && !itm_eq_obj->cloth_blocks.size()) + if (!obj || !itm_eq_obj->osage_blk.size() && !itm_eq_obj->cloth.size()) continue; objects.push_back((::item_id)i, itm_eq_obj->obj_info); @@ -511,21 +511,21 @@ bool RobOsageTest::ctrl() { itm_eq_obj->skp_load(&kv, aft_bone_data); std::vector> ex_nodes; - ex_nodes.reserve(itm_eq_obj->osage_blocks.size() + itm_eq_obj->cloth_blocks.size()); + ex_nodes.reserve(itm_eq_obj->osage_blk.size() + itm_eq_obj->cloth.size()); - for (ExOsageBlock*& j : itm_eq_obj->osage_blocks) { + for (ExOsageBlock*& j : itm_eq_obj->osage_blk) { ExOsageBlock* osg = j; ex_nodes.push_back({ osg->name, osg }); } - for (ExClothBlock*& j : itm_eq_obj->cloth_blocks) { + for (ExClothBlock*& j : itm_eq_obj->cloth) { ExClothBlock* cls = j; ex_nodes.push_back({ cls->name, cls }); } prj::sort(ex_nodes); - for (ExOsageBlock*& j : itm_eq_obj->osage_blocks) { + for (ExOsageBlock*& j : itm_eq_obj->osage_blk) { ExOsageBlock* osg = j; if (!kv.open_scope(osg->name)) continue; @@ -646,7 +646,7 @@ bool RobOsageTest::ctrl() { for (int32_t i = 0; i < ITEM_MAX; i++) { rob_chara_item_equip_object* itm_eq_obj = rob_itm_equip->get_item_equip_object((::item_id)i); ::obj* obj = objset_info_storage_get_obj(itm_eq_obj->obj_info); - if (!obj || !itm_eq_obj->osage_blocks.size() && !itm_eq_obj->cloth_blocks.size()) + if (!obj || !itm_eq_obj->osage_blk.size() && !itm_eq_obj->cloth.size()) continue; path_create_directory("ram/skin_param/"); @@ -655,14 +655,14 @@ bool RobOsageTest::ctrl() { "ext_skp_%s.txt", aft_obj_db->get_object_name(itm_eq_obj->obj_info))); std::vector> ex_nodes; - ex_nodes.reserve(itm_eq_obj->osage_blocks.size() + itm_eq_obj->cloth_blocks.size()); + ex_nodes.reserve(itm_eq_obj->osage_blk.size() + itm_eq_obj->cloth.size()); - for (ExOsageBlock*& i : itm_eq_obj->osage_blocks) { + for (ExOsageBlock*& i : itm_eq_obj->osage_blk) { ExOsageBlock* osg = i; ex_nodes.push_back({ osg->name, osg }); } - for (ExClothBlock*& i : itm_eq_obj->cloth_blocks) { + for (ExClothBlock*& i : itm_eq_obj->cloth) { ExClothBlock* cls = i; ex_nodes.push_back({ cls->name, cls }); } @@ -681,26 +681,26 @@ bool RobOsageTest::ctrl() { for (auto& j : ex_nodes) { kv.open_scope(j.first); - skin_param* skp = j.second->type == EX_OSAGE - ? ((ExOsageBlock*)j.second)->rob.skin_param_ptr - : ((ExClothBlock*)j.second)->rob.skin_param_ptr; + skin_param* skp = j.second->type == EX_NODE_TYPE_OSAGE + ? ((ExOsageBlock*)j.second)->osage_work.skin_param_ptr + : ((ExClothBlock*)j.second)->cloth_work.skin_param_ptr; - ExOsageBlock* osg = j.second->type == EX_OSAGE + ExOsageBlock* osg = j.second->type == EX_NODE_TYPE_OSAGE ? (ExOsageBlock*)j.second : 0; std::vector sort_index; int32_t* sort_index_data = 0; - if (osg && osg->rob.nodes.size() > 1) { - RobOsageNode* rob_osg_node = osg->rob.nodes.data() + 1; - int32_t node_count = (int32_t)(osg->rob.nodes.size() - 1); + if (osg && osg->osage_work.joint_node_vec.size() > 1) { + RobJointNode* rob_joint_node = osg->osage_work.joint_node_vec.data() + 1; + int32_t node_count = (int32_t)(osg->osage_work.joint_node_vec.size() - 1); key_val_out::get_lexicographic_order(sort_index, node_count); sort_index_data = sort_index.data(); kv.open_scope("node"); for (int32_t k = 0; k < node_count; k++) { kv.open_scope_fmt(sort_index_data[k]); - skin_param_osage_node* node = &rob_osg_node[sort_index_data[k]].data_ptr->skp_osg_node; + skin_param_osage_node* node = &rob_joint_node[sort_index_data[k]].data_ptr->skp_osg_node; kv.write(s, "coli_r", node->coli_r, flt_fmt); kv.write(s, "hinge_ymax", node->hinge.ymax* RAD_TO_DEG_FLOAT, flt_fmt); @@ -803,8 +803,8 @@ bool RobOsageTest::ctrl() { kv.write(s, "coli_type", skp->coli_type); if (skp->colli_tgt_osg) - for (ExOsageBlock*& k : itm_eq_obj->osage_blocks) - if (skp->colli_tgt_osg == &k->rob.nodes) { + for (ExOsageBlock*& k : itm_eq_obj->osage_blk) + if (skp->colli_tgt_osg == &k->osage_work.joint_node_vec) { kv.write(s, "colli_tgt_osg", k->name); break; } @@ -910,18 +910,18 @@ void RobOsageTest::basic() { ExOsageBlock* osg = get_osage_block(itm_eq_obj); if (osg) { - osg->rob.SetForce(root.force, root.gain); - osg->rob.SetAirRes(root.air_res); - osg->rob.SetRot(root.root_y_rot, root.root_z_rot); - osg->rob.skin_param_ptr->friction = root.fric; - osg->rob.skin_param_ptr->wind_afc = root.wind_afc; - osg->rob.skin_param_ptr->coli_type = root.coli_type; - osg->rob.SetInitRot(root.init_y_rot, root.init_z_rot); + osg->osage_work.set_force(root.force, root.gain); + osg->osage_work.set_air_res(root.air_res); + osg->osage_work.set_angle(root.root_y_rot, root.root_z_rot); + osg->osage_work.skin_param_ptr->friction = root.fric; + osg->osage_work.skin_param_ptr->wind_afc = root.wind_afc; + osg->osage_work.skin_param_ptr->coli_type = root.coli_type; + osg->osage_work.set_init_angle(root.init_y_rot, root.init_z_rot); } ExClothBlock* cls = get_cloth_block(itm_eq_obj); if (cls) { - skin_param* skp = cls->rob.skin_param_ptr; + skin_param* skp = cls->cloth_work.skin_param_ptr; skp->force = root.force; skp->force_gain = root.gain; skp->air_res = root.air_res; @@ -950,23 +950,23 @@ void RobOsageTest::disp_coli() { ExOsageBlock* osg = 0; ExClothBlock* cls = 0; SkinParam::CollisionParam* cls_param = 0; - if (ex_node->type == EX_OSAGE) { + if (ex_node->type == EX_NODE_TYPE_OSAGE) { osg = (ExOsageBlock*)ex_node; - cls_param = get_cls_param(&osg->rob.skin_param_ptr->coli); + cls_param = get_cls_param(&osg->osage_work.skin_param_ptr->coli); } - else if (ex_node->type == EX_CLOTH) { + else if (ex_node->type == EX_NODE_TYPE_CLOTH) { cls = (ExClothBlock*)ex_node; - cls_param = get_cls_param(&cls->rob.skin_param_ptr->coli); + cls_param = get_cls_param(&cls->cloth_work.skin_param_ptr->coli); } else return; disp_coli_cls_list(ex_node, cls_param); - if (osg && osg->rob.nodes.size() >= 1) { - RobOsageNode* j_begin = osg->rob.nodes.data() + 1; - RobOsageNode* j_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* j = j_begin; j != j_end; j++) { + if (osg && osg->osage_work.joint_node_vec.size() >= 1) { + RobJointNode* j_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* j_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* j = j_begin; j != j_end; j++) { mdl::EtcObj etc(mdl::ETC_OBJ_CAPSULE); etc.color = color_cyan; etc.color.a = 0xCF; @@ -981,22 +981,22 @@ void RobOsageTest::disp_coli() { rctx_ptr->disp_manager->entry_obj_etc(mat4_identity, etc); } } - else if (cls && cls->rob.nodes.size() >= cls->rob.root_count) { - CLOTHNode* j_begin = cls->rob.nodes.data() + cls->rob.root_count; - CLOTHNode* j_end = cls->rob.nodes.data() + cls->rob.nodes.size(); - for (CLOTHNode* j = j_begin; j != j_end; j++) { + else if (cls && cls->cloth_work.vtxarg.size() >= cls->cloth_work.width) { + CLOTH_VERTEX* j_begin = cls->cloth_work.vtxarg.data() + cls->cloth_work.width; + CLOTH_VERTEX* j_end = cls->cloth_work.vtxarg.data() + cls->cloth_work.vtxarg.size(); + for (CLOTH_VERTEX* j = j_begin; j != j_end; j++) { mdl::EtcObj etc(mdl::ETC_OBJ_SPHERE); etc.color = color_cyan; etc.color.a = 0xCF; etc.constant = true; - etc.data.sphere.radius = max_def(cls->rob.skin_param_ptr->coli_r, 0.005f); + etc.data.sphere.radius = max_def(cls->cloth_work.skin_param_ptr->coli_r, 0.005f); etc.data.sphere.slices = 16; etc.data.sphere.stacks = 16; etc.data.sphere.wire = false; vec3 pos; - mat4_transform_point(&itm_eq_obj->item_equip->mat, &j->pos, &pos); + mat4_transform_point(&itm_eq_obj->rob_disp->mat, &j->pos, &pos); mat4 mat; mat4_translate(&pos, &mat); @@ -1010,16 +1010,16 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision return; std::vector* cls_list = 0; - mat4* transform = 0; - if (ex_node->type == EX_OSAGE) { + const mat4* motion_matrix = 0; + if (ex_node->type == EX_NODE_TYPE_OSAGE) { ExOsageBlock* osg = (ExOsageBlock*)ex_node; - cls_list = &osg->rob.skin_param_ptr->coli; - transform = osg->mats; + cls_list = &osg->osage_work.skin_param_ptr->coli; + motion_matrix = osg->motion_matrix; } - else if (ex_node->type == EX_CLOTH) { + else if (ex_node->type == EX_NODE_TYPE_CLOTH) { ExClothBlock* cls = (ExClothBlock*)ex_node; - cls_list = &cls->rob.skin_param_ptr->coli; - transform = cls->mats; + cls_list = &cls->cloth_work.skin_param_ptr->coli; + motion_matrix = cls->motion_matrix; } else return; @@ -1040,7 +1040,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision etc.data.sphere.wire = false; vec3 pos; - mat4_transform_point(&transform[i.node_idx[0]], &i.pos[0], &pos); + mat4_transform_point(&motion_matrix[i.node_idx[0]], &i.pos[0], &pos); mat4 mat; mat4_translate(&pos, &mat); @@ -1056,8 +1056,8 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision etc.data.capsule.stacks = 16; etc.data.capsule.wire = false; - mat4_transform_point(&transform[i.node_idx[0]], &i.pos[0], &etc.data.capsule.pos[0]); - mat4_transform_point(&transform[i.node_idx[1]], &i.pos[1], &etc.data.capsule.pos[1]); + mat4_transform_point(&motion_matrix[i.node_idx[0]], &i.pos[0], &etc.data.capsule.pos[0]); + mat4_transform_point(&motion_matrix[i.node_idx[1]], &i.pos[1], &etc.data.capsule.pos[1]); rctx_ptr->disp_manager->entry_obj_etc(mat4_identity, etc); } break; case SkinParam::CollisionTypePlane: { @@ -1069,7 +1069,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision etc.data.plane.h = 2; vec3 pos; - mat4_transform_point(&transform[i.node_idx[0]], &i.pos[0], &pos); + mat4_transform_point(&motion_matrix[i.node_idx[0]], &i.pos[0], &pos); const vec3 dir = vec3::normalize(i.pos[1]); const vec3 up = { 0.0f, 1.0f, 0.0f }; @@ -1097,8 +1097,8 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision etc.data.sphere.wire = false; vec3 pos[2]; - mat4_transform_point(&transform[i.node_idx[0]], &i.pos[0], &pos[0]); - mat4_transform_point(&transform[i.node_idx[1]], &i.pos[1], &pos[1]); + mat4_transform_point(&motion_matrix[i.node_idx[0]], &i.pos[0], &pos[0]); + mat4_transform_point(&motion_matrix[i.node_idx[1]], &i.pos[1], &pos[1]); vec3 origin = (pos[0] + pos[1]) * 0.5f; mat4 mat; @@ -1126,7 +1126,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision etc.constant = true; vec3 pos; - mat4_transform_point(&transform[i.node_idx[0]], &i.pos[0], &pos); + mat4_transform_point(&motion_matrix[i.node_idx[0]], &i.pos[0], &pos); pos += i.pos[1] * 0.5f; etc.data.cube.size = i.pos[1]; @@ -1150,12 +1150,12 @@ void RobOsageTest::disp_line() { ExNodeBlock* ex_node = get_node_block(itm_eq_obj); - for (ExOsageBlock*& i : itm_eq_obj->osage_blocks) { - if (!i || i->rob.nodes.size() < 1) + for (ExOsageBlock*& i : itm_eq_obj->osage_blk) { + if (!i || i->osage_work.joint_node_vec.size() < 1) continue; mat4 mat; - mat4_scale_rot(i->rob.nodes.data()[0].bone_node_mat, 0.05f, &mat); + mat4_scale_rot(i->osage_work.joint_node_vec.data()[0].bone_node_mat, 0.05f, &mat); if (i == ex_node) spr::put_cross(mat, color_red, color_green, color_blue); else @@ -1164,36 +1164,36 @@ void RobOsageTest::disp_line() { const color4u8 line_color = i == ex_node ? color_white : color_dark_cyan; const color4u8 rect_color = i == ex_node ? color_red : color_dark_red; - const RobOsageNode* j_begin = i->rob.nodes.data() + 1; - const RobOsageNode* j_end = i->rob.nodes.data() + i->rob.nodes.size(); - for (const RobOsageNode* j = j_begin; j != j_end; j++) + const RobJointNode* j_begin = i->osage_work.joint_node_vec.data() + 1; + const RobJointNode* j_end = i->osage_work.joint_node_vec.data() + i->osage_work.joint_node_vec.size(); + for (const RobJointNode* j = j_begin; j != j_end; j++) spr::put_sprite_3d_line(j[-1].pos, j[0].pos, line_color); - for (const RobOsageNode* j = j_begin; j != j_end; j++) + for (const RobJointNode* j = j_begin; j != j_end; j++) spr::put_sprite_rect({ spr::proj_sprite_3d_line(j->pos, true) - 2.0f, 4.0f }, SCREEN_MODE_MAX, spr::SPR_PRIO_DW, rect_color); - mat4_scale_rot(i->rob.end_node.bone_node_mat, 0.05f, &mat); + mat4_scale_rot(i->osage_work.effector.bone_node_mat, 0.05f, &mat); spr::put_cross(mat, color_dark_red, color_dark_green, color_dark_blue); } - for (ExClothBlock*& i : itm_eq_obj->cloth_blocks) { - if (!i || i->rob.nodes.size() < i->rob.root_count) + for (ExClothBlock*& i : itm_eq_obj->cloth) { + if (!i || i->cloth_work.vtxarg.size() < i->cloth_work.width) continue; - const color4u8 color_line = i == ex_node ? color_red : color_dark_red; + const color4u8 color_spring = i == ex_node ? color_red : color_dark_red; const color4u8 color_tangent = i == ex_node ? color_green : color_dark_green; const color4u8 color_binormal = i == ex_node ? color_cyan : color_dark_cyan; const color4u8 color_normal = i == ex_node ? color_white : color_grey; - const CLOTHNode* nodes = i->rob.nodes.data(); - for (const CLOTHLine& j : i->rob.lines) - spr::put_sprite_3d_line(nodes[j.idx[0]].pos, nodes[j.idx[1]].pos, color_line); + const CLOTH_VERTEX* vtxarg = i->cloth_work.vtxarg.data(); + for (const CLOTH_SPRING& j : i->cloth_work.spring) + spr::put_sprite_3d_line(vtxarg[j.index0].pos, vtxarg[j.index1].pos, color_spring); - const CLOTHNode* j_begin = i->rob.nodes.data() + i->rob.root_count; - const CLOTHNode* j_end = i->rob.nodes.data() + i->rob.nodes.size(); - for (const CLOTHNode* j = j_begin; j != j_end; j++) { + const CLOTH_VERTEX* j_begin = i->cloth_work.vtxarg.data() + i->cloth_work.width; + const CLOTH_VERTEX* j_end = i->cloth_work.vtxarg.data() + i->cloth_work.vtxarg.size(); + for (const CLOTH_VERTEX* j = j_begin; j != j_end; j++) { spr::put_sprite_3d_line(j->pos, j->tangent * 0.05f + j->pos, color_tangent); spr::put_sprite_3d_line(j->pos, j->binormal * 0.05f + j->pos, color_binormal); spr::put_sprite_3d_line(j->pos, j->normal * 0.05f + j->pos, color_normal); @@ -1206,16 +1206,16 @@ void RobOsageTest::disp_line() { const ExOsageBlock* osg = 0; const ExClothBlock* cls = 0; const SkinParam::CollisionParam* cls_param = 0; - const mat4* transform = 0; - if (ex_node->type == EX_OSAGE) { + const mat4* motion_matrix = 0; + if (ex_node->type == EX_NODE_TYPE_OSAGE) { osg = (ExOsageBlock*)ex_node; - cls_param = get_cls_param(&osg->rob.skin_param_ptr->coli); - transform = osg->mats; + cls_param = get_cls_param(&osg->osage_work.skin_param_ptr->coli); + motion_matrix = osg->motion_matrix; } - else if (ex_node->type == EX_CLOTH) { + else if (ex_node->type == EX_NODE_TYPE_CLOTH) { cls = (ExClothBlock*)ex_node; - cls_param = get_cls_param(&cls->rob.skin_param_ptr->coli); - transform = cls->mats; + cls_param = get_cls_param(&cls->cloth_work.skin_param_ptr->coli); + motion_matrix = cls->motion_matrix; } else return; @@ -1223,35 +1223,35 @@ void RobOsageTest::disp_line() { if (cls_param) switch (cls_param->type) { case SkinParam::CollisionTypeBall: - disp_line_cls_param(transform[cls_param->node_idx[0]], cls_param->pos[0]); + disp_line_cls_param(motion_matrix[cls_param->node_idx[0]], cls_param->pos[0]); break; case SkinParam::CollisionTypeCapsule: - disp_line_cls_param(transform[cls_param->node_idx[0]], cls_param->pos[0]); - disp_line_cls_param(transform[cls_param->node_idx[1]], cls_param->pos[1]); + disp_line_cls_param(motion_matrix[cls_param->node_idx[0]], cls_param->pos[0]); + disp_line_cls_param(motion_matrix[cls_param->node_idx[1]], cls_param->pos[1]); break; case SkinParam::CollisionTypePlane: - disp_line_cls_param(transform[cls_param->node_idx[0]], cls_param->pos[0]); + disp_line_cls_param(motion_matrix[cls_param->node_idx[0]], cls_param->pos[0]); break; case SkinParam::CollisionTypeEllipse: - disp_line_cls_param(transform[cls_param->node_idx[0]], cls_param->pos[0]); - disp_line_cls_param(transform[cls_param->node_idx[1]], cls_param->pos[1]); + disp_line_cls_param(motion_matrix[cls_param->node_idx[0]], cls_param->pos[0]); + disp_line_cls_param(motion_matrix[cls_param->node_idx[1]], cls_param->pos[1]); break; case SkinParam::CollisionTypeAABB: - disp_line_cls_param(transform[cls_param->node_idx[0]], cls_param->pos[0]); + disp_line_cls_param(motion_matrix[cls_param->node_idx[0]], cls_param->pos[0]); break; } } -void RobOsageTest::disp_line_cls_param(const mat4& transform, const vec3& pos) { +void RobOsageTest::disp_line_cls_param(const mat4& motion_matrix, const vec3& pos) { mat4 mat; - mat4_scale_rot(&transform, 0.1f, &mat); + mat4_scale_rot(&motion_matrix, 0.1f, &mat); spr::put_cross(mat, color_red, color_green, color_blue); vec3 p; - mat4_transform_point(&transform, &pos, &p); + mat4_transform_point(&motion_matrix, &pos, &p); vec3 p_node; - mat4_get_translation(&transform, &p_node); + mat4_get_translation(&motion_matrix, &p_node); spr::put_sprite_3d_line(p, p_node, color_grey); spr::put_sprite_rect({ spr::proj_sprite_3d_line(p, true) - 1.0f, 2.0f }, @@ -1259,9 +1259,9 @@ void RobOsageTest::disp_line_cls_param(const mat4& transform, const vec3& pos) { } inline ExClothBlock* RobOsageTest::get_cloth_block(rob_chara_item_equip_object* itm_eq_obj) const { - if (itm_eq_obj && itm_eq_obj->obj_info == obj_info && osage_index >= itm_eq_obj->osage_blocks.size() - && osage_index - itm_eq_obj->osage_blocks.size() < itm_eq_obj->cloth_blocks.size()) - return itm_eq_obj->cloth_blocks[osage_index - itm_eq_obj->osage_blocks.size()]; + if (itm_eq_obj && itm_eq_obj->obj_info == obj_info && osage_index >= itm_eq_obj->osage_blk.size() + && osage_index - itm_eq_obj->osage_blk.size() < itm_eq_obj->cloth.size()) + return itm_eq_obj->cloth[osage_index - itm_eq_obj->osage_blk.size()]; return 0; } @@ -1269,10 +1269,10 @@ inline std::vector* RobOsageTest::get_cls_list(ExNode if (!ex_node) return 0; - if (ex_node->type == EX_OSAGE) - return &((ExOsageBlock*)ex_node)->rob.skin_param_ptr->coli; - else if (ex_node->type == EX_CLOTH) - return &((ExClothBlock*)ex_node)->rob.skin_param_ptr->coli; + if (ex_node->type == EX_NODE_TYPE_OSAGE) + return &((ExOsageBlock*)ex_node)->osage_work.skin_param_ptr->coli; + else if (ex_node->type == EX_NODE_TYPE_CLOTH) + return &((ExClothBlock*)ex_node)->cloth_work.skin_param_ptr->coli; return 0; } @@ -1295,17 +1295,17 @@ inline rob_chara_item_equip_object* RobOsageTest::get_item_equip_object() const inline ExNodeBlock* RobOsageTest::get_node_block(rob_chara_item_equip_object* itm_eq_obj) const { if (itm_eq_obj && itm_eq_obj->obj_info == obj_info) - if (osage_index < itm_eq_obj->osage_blocks.size()) - return itm_eq_obj->osage_blocks[osage_index]; - else if (osage_index >= itm_eq_obj->osage_blocks.size() - && osage_index - itm_eq_obj->osage_blocks.size() < itm_eq_obj->cloth_blocks.size()) - return itm_eq_obj->cloth_blocks[osage_index - itm_eq_obj->osage_blocks.size()]; + if (osage_index < itm_eq_obj->osage_blk.size()) + return itm_eq_obj->osage_blk[osage_index]; + else if (osage_index >= itm_eq_obj->osage_blk.size() + && osage_index - itm_eq_obj->osage_blk.size() < itm_eq_obj->cloth.size()) + return itm_eq_obj->cloth[osage_index - itm_eq_obj->osage_blk.size()]; return 0; } inline ExOsageBlock* RobOsageTest::get_osage_block(rob_chara_item_equip_object* itm_eq_obj) const { - if (itm_eq_obj && itm_eq_obj->obj_info == obj_info && osage_index < itm_eq_obj->osage_blocks.size()) - return itm_eq_obj->osage_blocks[osage_index]; + if (itm_eq_obj && itm_eq_obj->obj_info == obj_info && osage_index < itm_eq_obj->osage_blk.size()) + return itm_eq_obj->osage_blk[osage_index]; return 0; } @@ -1430,10 +1430,10 @@ void RobOsageTestDw::Rob::ObjectCallback(dw::Widget* data) { rob_chara_item_equip_object* itm_eq_obj = rob_osage_test->get_item_equip_object(); if (itm_eq_obj) { - for (ExOsageBlock*& i : itm_eq_obj->osage_blocks) + for (ExOsageBlock*& i : itm_eq_obj->osage_blk) rob_osage_test_dw->root.list_box->AddItem(i->name); - for (ExClothBlock*& i : itm_eq_obj->cloth_blocks) + for (ExClothBlock*& i : itm_eq_obj->cloth) rob_osage_test_dw->root.list_box->AddItem(i->name); } } @@ -2227,9 +2227,9 @@ void RobOsageTestDw::Node::CollisionRadius::Callback(dw::Widget* data) { ExOsageBlock* osg = rob_osage_test->get_osage_block(itm_eq_obj); if (osg) { float_t value = slider->GetValue(); - RobOsageNode* i_begin = osg->rob.nodes.data() + 1; - RobOsageNode* i_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* i_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.coli_r = value; } } @@ -2326,9 +2326,9 @@ void RobOsageTestDw::Node::Hinge::YMinCallback(dw::Widget* data) { ExOsageBlock* osg = rob_osage_test->get_osage_block(itm_eq_obj); if (osg) { float_t value = slider->GetValue() * DEG_TO_RAD_FLOAT; - RobOsageNode* i_begin = osg->rob.nodes.data() + 1; - RobOsageNode* i_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* i_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.hinge.ymin = value; } } @@ -2341,9 +2341,9 @@ void RobOsageTestDw::Node::Hinge::YMaxCallback(dw::Widget* data) { ExOsageBlock* osg = rob_osage_test->get_osage_block(itm_eq_obj); if (osg) { float_t value = slider->GetValue() * DEG_TO_RAD_FLOAT; - RobOsageNode* i_begin = osg->rob.nodes.data() + 1; - RobOsageNode* i_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* i_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.hinge.ymax = value; } } @@ -2356,9 +2356,9 @@ void RobOsageTestDw::Node::Hinge::ZMinCallback(dw::Widget* data) { ExOsageBlock* osg = rob_osage_test->get_osage_block(itm_eq_obj); if (osg) { float_t value = slider->GetValue() * DEG_TO_RAD_FLOAT; - RobOsageNode* i_begin = osg->rob.nodes.data() + 1; - RobOsageNode* i_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* i_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.hinge.zmin = value; } } @@ -2371,9 +2371,9 @@ void RobOsageTestDw::Node::Hinge::ZMaxCallback(dw::Widget* data) { ExOsageBlock* osg = rob_osage_test->get_osage_block(itm_eq_obj); if (osg) { float_t value = slider->GetValue() * DEG_TO_RAD_FLOAT; - RobOsageNode* i_begin = osg->rob.nodes.data() + 1; - RobOsageNode* i_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* i_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.hinge.zmax = value; } } @@ -2430,9 +2430,9 @@ void RobOsageTestDw::Node::InertialCancel::Callback(dw::Widget* data) { ExOsageBlock* osg = rob_osage_test->get_osage_block(itm_eq_obj); if (osg) { float_t value = slider->GetValue(); - RobOsageNode* i_begin = osg->rob.nodes.data() + 1; - RobOsageNode* i_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* i_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.inertial_cancel = value; } } @@ -2489,9 +2489,9 @@ void RobOsageTestDw::Node::Weight::Callback(dw::Widget* data) { ExOsageBlock* osg = rob_osage_test->get_osage_block(itm_eq_obj); if (osg) { float_t value = slider->GetValue(); - RobOsageNode* i_begin = osg->rob.nodes.data() + 1; - RobOsageNode* i_end = osg->rob.nodes.data() + osg->rob.nodes.size(); - for (RobOsageNode* i = i_begin; i != i_end; i++) + RobJointNode* i_begin = osg->osage_work.joint_node_vec.data() + 1; + RobJointNode* i_end = osg->osage_work.joint_node_vec.data() + osg->osage_work.joint_node_vec.size(); + for (RobJointNode* i = i_begin; i != i_end; i++) i->data_ptr->skp_osg_node.weight = value; } } diff --git a/src/ReDIVA/data_test/rob_osage_test.hpp b/src/ReDIVA/data_test/rob_osage_test.hpp index 93b7caca..1c371a74 100644 --- a/src/ReDIVA/data_test/rob_osage_test.hpp +++ b/src/ReDIVA/data_test/rob_osage_test.hpp @@ -134,18 +134,18 @@ public: if (!ex_node) return 0; - if (ex_node->type == EX_OSAGE) - return ((ExOsageBlock*)ex_node)->rob.skin_param_ptr; - else if (ex_node->type == EX_CLOTH) - return ((ExClothBlock*)ex_node)->rob.skin_param_ptr; + if (ex_node->type == EX_NODE_TYPE_OSAGE) + return ((ExOsageBlock*)ex_node)->osage_work.skin_param_ptr; + else if (ex_node->type == EX_NODE_TYPE_CLOTH) + return ((ExClothBlock*)ex_node)->cloth_work.skin_param_ptr; return 0; } inline skin_param_osage_node* get_skin_param_osage_node() const { rob_chara_item_equip_object* itm_eq_obj = get_item_equip_object(); ExOsageBlock* osg = get_osage_block(itm_eq_obj); - if (osg && osg->rob.nodes.size() > 1) - return &osg->rob.nodes.data()[1].data_ptr->skp_osg_node; + if (osg && osg->osage_work.joint_node_vec.size() > 1) + return &osg->osage_work.joint_node_vec.data()[1].data_ptr->skp_osg_node; return 0; }