1234 lines
39 KiB
C++
1234 lines
39 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
*/
|
|
|
|
#include "rob.hpp"
|
|
#include "../../KKdLib/str_utils.hpp"
|
|
#include "../mdl/disp_manager.hpp"
|
|
#include "../gl_state.hpp"
|
|
#include "../object.hpp"
|
|
#include "../render_manager.hpp"
|
|
#include <Helpers.h>
|
|
#include <algorithm>
|
|
|
|
enum ExNodeType {
|
|
EX_NONE = 0x00,
|
|
EX_OSAGE = 0x01,
|
|
EX_EXPRESSION = 0x02,
|
|
EX_CONSTRAINT = 0x03,
|
|
EX_CLOTH = 0x04,
|
|
};
|
|
|
|
enum rob_chara_data_hand_adjust_type : uint16_t {
|
|
ROB_CHARA_DATA_HAND_ADJUST_NONE = (uint16_t)-1,
|
|
ROB_CHARA_DATA_HAND_ADJUST_NORMAL = 0x00,
|
|
ROB_CHARA_DATA_HAND_ADJUST_SHORT = 0x01,
|
|
ROB_CHARA_DATA_HAND_ADJUST_TALL = 0x02,
|
|
ROB_CHARA_DATA_HAND_ADJUST_MIN = 0x03,
|
|
ROB_CHARA_DATA_HAND_ADJUST_MAX = 0x04,
|
|
ROB_CHARA_DATA_HAND_ADJUST_OPPOSITE_CHARA = 0x05,
|
|
ROB_CHARA_DATA_HAND_ADJUST_CUSTOM = 0x06,
|
|
ROB_CHARA_DATA_HAND_ADJUST_1P = 0x07,
|
|
ROB_CHARA_DATA_HAND_ADJUST_2P = 0x08,
|
|
ROB_CHARA_DATA_HAND_ADJUST_3P = 0x09,
|
|
ROB_CHARA_DATA_HAND_ADJUST_4P = 0x0A,
|
|
ROB_CHARA_DATA_HAND_ADJUST_ITEM = 0x0F, // X
|
|
};
|
|
|
|
struct rob_chara_age_age_object_vertex {
|
|
vec3 position;
|
|
vec3 normal;
|
|
vec4 tangent;
|
|
vec2 texcoord;
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_age_age_object_vertex) == 0x30, "\"rob_chara_age_age_object_vertex\" struct should have a size of 0x30");
|
|
|
|
struct rob_chara_age_age_object {
|
|
void* objset_info; // ObjsetInfo
|
|
int32_t obj_index;
|
|
int32_t field_C;
|
|
int32_t num_vertex;
|
|
int32_t num_index;
|
|
obj obj;
|
|
obj_mesh mesh;
|
|
obj_sub_mesh sub_mesh;
|
|
obj_material_data material[2];
|
|
obj_axis_aligned_bounding_box axis_aligned_bounding_box;
|
|
rob_chara_age_age_object_vertex* vertex_data;
|
|
int32_t vertex_data_size;
|
|
int32_t vertex_array_size;
|
|
#if SHARED_OBJECT_BUFFER
|
|
obj_mesh_vertex_buffer_aft obj_vert_buf;
|
|
#else
|
|
obj_mesh_vertex_buffer obj_vert_buf;
|
|
#endif
|
|
obj_mesh_index_buffer obj_index_buf;
|
|
vec3 trans[10];
|
|
int32_t disp_count;
|
|
int32_t count;
|
|
bool field_C3C;
|
|
|
|
void disp(size_t chara_index,
|
|
bool npr, bool reflect, const vec3& a5, bool chara_color);
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_age_age_object) == 0xC40, "\"rob_chara_age_age_object\" struct should have a size of 0xC40");
|
|
|
|
struct rob_chara_age_age_data {
|
|
int32_t index;
|
|
int32_t part_id;
|
|
vec3 trans;
|
|
float_t field_14;
|
|
float_t rot_z;
|
|
int32_t field_1C;
|
|
float_t rot_speed;
|
|
float_t gravity;
|
|
float_t scale;
|
|
float_t alpha;
|
|
mat4 mat_scale;
|
|
mat4 mat;
|
|
mat4 prev_parent_mat;
|
|
float_t remaining;
|
|
bool alive;
|
|
};
|
|
static_assert(sizeof(rob_chara_age_age_data) == 0xF8, "\"rob_chara_age_age_data\" struct should have a size of 0xF8");
|
|
|
|
struct rob_chara_age_age {
|
|
rob_chara_age_age_data data[10];
|
|
float_t frame;
|
|
float_t field_9B4;
|
|
mat4 mat;
|
|
float_t step;
|
|
bool visible;
|
|
bool skip;
|
|
float_t move_cancel;
|
|
float_t alpha;
|
|
rob_chara_age_age_object object;
|
|
bool npr;
|
|
float_t rot_speed;
|
|
bool step_full;
|
|
|
|
void disp(size_t chara_id,
|
|
bool npr, bool reflect, const vec3& a5, bool chara_color);
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_age_age) == 0x1658, "\"rob_chara_age_age\" struct should have a size of 0x1658");
|
|
|
|
struct bone_node_expression_data {
|
|
vec3 position;
|
|
vec3 rotation;
|
|
vec3 scale;
|
|
vec3 parent_scale;
|
|
};
|
|
|
|
static_assert(sizeof(bone_node_expression_data) == 0x30, "\"bone_node_expression_data\" struct should have a size of 0x30");
|
|
|
|
struct bone_node {
|
|
const char* name;
|
|
mat4* mat;
|
|
bone_node* parent;
|
|
bone_node_expression_data exp_data;
|
|
mat4* ex_data_mat;
|
|
};
|
|
|
|
static_assert(sizeof(bone_node) == 0x50, "\"bone_node\" struct should have a size of 0x50");
|
|
|
|
struct opd_blend_data {
|
|
int32_t motion_id;
|
|
float_t frame;
|
|
float_t frame_count;
|
|
bool use_blend;
|
|
int32_t type; // MotionBlendType
|
|
float_t blend;
|
|
};
|
|
|
|
static_assert(sizeof(opd_blend_data) == 0x18, "\"opd_blend_data\" struct should have a size of 0x18");
|
|
|
|
struct ExNodeBlock;
|
|
|
|
struct ExNodeBlock_vtbl {
|
|
ExNodeBlock* (FASTCALL* Dispose)(ExNodeBlock* node, uint8_t);
|
|
void(FASTCALL* Field8)(ExNodeBlock* node);
|
|
void(FASTCALL* Field10)(ExNodeBlock* node);
|
|
void(FASTCALL* Field18)(ExNodeBlock* node, int32_t stage, bool disable_external_force);
|
|
void(FASTCALL* Field20)(ExNodeBlock* node);
|
|
void(FASTCALL* SetOsagePlayData)(ExNodeBlock* node);
|
|
void(FASTCALL* Disp)(ExNodeBlock* node);
|
|
void(FASTCALL* Reset)(ExNodeBlock* node);
|
|
void(FASTCALL* Field40)(ExNodeBlock* node);
|
|
void(FASTCALL* Field48)(ExNodeBlock* node);
|
|
void(FASTCALL* Field50)(ExNodeBlock* node);
|
|
void(FASTCALL* Field58)(ExNodeBlock* node);
|
|
};
|
|
|
|
struct rob_chara_item_equip_object;
|
|
|
|
struct ExNodeBlock {
|
|
ExNodeBlock_vtbl* __vftable;
|
|
bone_node* bone_node_ptr;
|
|
ExNodeType type;
|
|
const char* name;
|
|
bone_node* parent_bone_node;
|
|
prj::string parent_name;
|
|
ExNodeBlock* parent_node;
|
|
rob_chara_item_equip_object* item_equip_object;
|
|
bool field_58;
|
|
bool field_59;
|
|
bool has_children_node;
|
|
};
|
|
|
|
struct rob_chara_item_equip;
|
|
|
|
struct rob_chara_item_equip_object {
|
|
size_t index;
|
|
mat4* mats;
|
|
object_info obj_info;
|
|
int32_t field_14;
|
|
prj::vector<texture_pattern_struct> texture_pattern;
|
|
texture_data_struct texture_data;
|
|
bool null_blocks_data_set;
|
|
bone_node_expression_data exp_data;
|
|
float_t alpha;
|
|
mdl::ObjFlags obj_flags;
|
|
bool can_disp;
|
|
int32_t field_A4;
|
|
mat4* mat;
|
|
int32_t osage_iterations;
|
|
bone_node* bone_nodes;
|
|
prj::vector<ExNodeBlock*> node_blocks;
|
|
prj::vector<bone_node> ex_data_bone_nodes;
|
|
prj::vector<mat4> ex_data_bone_mats;
|
|
prj::vector<mat4> ex_data_mats;
|
|
prj::vector<std::pair<const char*, uint32_t>> ex_bones;
|
|
int64_t field_138;
|
|
prj::vector<void*> null_blocks; // ExNullBlock
|
|
prj::vector<void*> osage_blocks; // ExOsageBlock
|
|
prj::vector<void*> constraint_blocks; // ExConstraintBlock
|
|
prj::vector<void*> expression_blocks; // ExExpressionBlock
|
|
prj::vector<void*> cloth_blocks; // ExClothBlock
|
|
bool field_1B8;
|
|
size_t osage_nodes_count;
|
|
bool use_opd;
|
|
obj_skin_ex_data* skin_ex_data;
|
|
obj_skin* skin;
|
|
rob_chara_item_equip* item_equip;
|
|
|
|
void disp(const mat4* mat);
|
|
int32_t get_bone_index(const char* name);
|
|
bone_node* get_bone_node(int32_t bone_index);
|
|
bone_node* get_bone_node(const char* name);
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_item_equip_object) == 0x1E8, "\"rob_chara_item_equip_object\" struct should have a size of 0x1E8");
|
|
|
|
struct rob_chara_item_equip {
|
|
bone_node* bone_nodes;
|
|
mat4* matrices;
|
|
rob_chara_item_equip_object* item_equip_object;
|
|
int32_t field_18[31];
|
|
bool item_equip_range;
|
|
item_id first_item_equip_object;
|
|
item_id max_item_equip_object;
|
|
int32_t field_A0;
|
|
shadow_type_enum shadow_type;
|
|
vec3 position;
|
|
prj::vector<texture_pattern_struct> texture_pattern;
|
|
object_info field_D0;
|
|
item_id field_D4;
|
|
bool disable_update;
|
|
int32_t field_DC;
|
|
vec4 texture_color_coefficients;
|
|
float_t wet;
|
|
float_t wind_strength;
|
|
bool chara_color;
|
|
bool npr_flag;
|
|
mat4 mat;
|
|
mat4 field_13C[30];
|
|
int32_t field_8BC;
|
|
int32_t field_8C0;
|
|
int32_t field_8C4;
|
|
int32_t field_8C8;
|
|
int32_t field_8CC;
|
|
int32_t field_8D0;
|
|
int32_t field_8D4;
|
|
int32_t field_8D8;
|
|
int32_t field_8DC;
|
|
int32_t field_8E0;
|
|
int32_t field_8E4;
|
|
int32_t field_8E8;
|
|
int32_t field_8EC;
|
|
int32_t field_8F0;
|
|
int32_t field_8F4;
|
|
int32_t field_8F8;
|
|
int32_t field_8FC;
|
|
int64_t field_900;
|
|
int64_t field_908;
|
|
int64_t field_910;
|
|
int64_t field_918;
|
|
int64_t field_920;
|
|
int64_t field_928;
|
|
int64_t field_930;
|
|
float_t osage_step;
|
|
bool use_opd;
|
|
prj::vector<opd_blend_data> opd_blend_data;
|
|
bool parts_short;
|
|
bool parts_append;
|
|
bool parts_white_one_l;
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_item_equip) == 0x960, "\"rob_chara_item_equip\" struct should have a size of 0x960");
|
|
|
|
struct rob_chara_item_cos_data {
|
|
uint8_t data[0x408];
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_item_cos_data) == 0x408, "\"rob_chara_item_cos_data\" struct should have a size of 0x408");
|
|
|
|
struct struc_264 {
|
|
uint8_t data[0x1D8];
|
|
};
|
|
|
|
static_assert(sizeof(struc_264) == 0x1D8, "\"struc_264\" struct should have a size of 0x1D8");
|
|
|
|
struct RobSubAction {
|
|
uint8_t data[0xB0];
|
|
};
|
|
|
|
static_assert(sizeof(RobSubAction) == 0xB0, "\"RobSubAction\" struct should have a size of 0xB0");
|
|
|
|
struct struc_389 {
|
|
float_t frame;
|
|
float_t prev_frame;
|
|
float_t last_set_frame;
|
|
};
|
|
|
|
static_assert(sizeof(struc_389) == 0x0C, "\"struc_389\" struct should have a size of 0x0C");
|
|
|
|
struct struc_406 {
|
|
float_t frame;
|
|
float_t field_4;
|
|
float_t step;
|
|
};
|
|
|
|
static_assert(sizeof(struc_406) == 0x0C, "\"struc_406\" struct should have a size of 0x0C");
|
|
|
|
struct rob_chara_data_hand_adjust {
|
|
bool enable;
|
|
int16_t scale_select;
|
|
rob_chara_data_hand_adjust_type type;
|
|
float_t current_scale;
|
|
float_t scale;
|
|
float_t duration;
|
|
float_t current_time;
|
|
float_t rotation_blend;
|
|
float_t scale_blend;
|
|
bool enable_scale;
|
|
bool disable_x;
|
|
bool disable_y;
|
|
bool disable_z;
|
|
vec3 offset;
|
|
vec3 field_30;
|
|
float_t arm_length;
|
|
int32_t field_40;
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_data_hand_adjust) == 0x44, "\"rob_chara_data_hand_adjust\" struct should have a size of 0x44");
|
|
|
|
struct rob_chara_motion {
|
|
uint32_t motion_id;
|
|
uint32_t prev_motion_id;
|
|
struc_389 frame_data;
|
|
struc_406 step_data;
|
|
uint8_t data[0x1198];
|
|
rob_chara_data_hand_adjust hand_adjust[2];
|
|
rob_chara_data_hand_adjust hand_adjust_prev[2];
|
|
uint8_t data1[0x30];
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_motion) == 0x12F8, "\"rob_chara_motion\" struct should have a size of 0x12F8");
|
|
|
|
struct struc_526 {
|
|
int32_t field_0;
|
|
int32_t field_4;
|
|
};
|
|
|
|
struct struc_228 {
|
|
int32_t field_0;
|
|
int32_t field_4;
|
|
uint32_t field_8;
|
|
int32_t field_C;
|
|
};
|
|
|
|
struct struc_227 {
|
|
int32_t field_0;
|
|
float_t field_4;
|
|
float_t field_8;
|
|
};
|
|
|
|
struct struc_652 {
|
|
int32_t motion_id;
|
|
float_t frame_count;
|
|
float_t frame;
|
|
int16_t field_C;
|
|
struc_228 field_10;
|
|
struc_228 field_20;
|
|
struc_228 field_30;
|
|
struc_228 field_40;
|
|
int16_t field_50;
|
|
int16_t field_52;
|
|
int16_t field_54;
|
|
int32_t field_58;
|
|
int32_t field_5C;
|
|
int32_t field_60;
|
|
int32_t field_64;
|
|
int32_t field_68;
|
|
int32_t loop_count;
|
|
float_t loop_begin;
|
|
float_t loop_end;
|
|
float_t field_78;
|
|
float_t field_7C;
|
|
float_t field_80;
|
|
int8_t field_84;
|
|
int32_t field_88;
|
|
int32_t field_8C;
|
|
int32_t field_90;
|
|
int16_t field_94;
|
|
int16_t field_96;
|
|
int16_t field_98;
|
|
int32_t field_9C;
|
|
int16_t field_A0;
|
|
int32_t field_A4;
|
|
int64_t field_A8;
|
|
struc_227 field_B0[26];
|
|
int32_t field_1E8;
|
|
float_t field_1EC;
|
|
float_t field_1F0;
|
|
float_t field_1F4;
|
|
float_t field_1F8;
|
|
float_t field_1FC;
|
|
float_t field_200;
|
|
int32_t field_204;
|
|
int32_t field_208;
|
|
int32_t field_20C;
|
|
int64_t field_210;
|
|
float_t field_218;
|
|
float_t field_21C;
|
|
int16_t field_220;
|
|
prj::list<void*> field_228;
|
|
int16_t field_238;
|
|
float_t field_23C;
|
|
int32_t field_240;
|
|
int16_t field_244;
|
|
const void* field_248;
|
|
int64_t field_250;
|
|
float_t field_258;
|
|
int32_t field_25C;
|
|
struc_526 field_260;
|
|
struc_526 field_268;
|
|
int32_t field_270;
|
|
int16_t field_274;
|
|
int16_t field_276;
|
|
int32_t field_278;
|
|
int32_t field_27C;
|
|
int32_t field_280;
|
|
int16_t field_284;
|
|
int64_t field_288;
|
|
int32_t field_290;
|
|
int32_t field_294;
|
|
int32_t field_298;
|
|
float_t field_29C;
|
|
int8_t field_2A0;
|
|
float_t field_2A4;
|
|
float_t field_2A8;
|
|
float_t field_2AC;
|
|
int64_t field_2B0;
|
|
int16_t field_2B8;
|
|
int32_t field_2BC;
|
|
float_t field_2C0;
|
|
float_t field_2C4;
|
|
int32_t field_2C8;
|
|
int32_t field_2CC;
|
|
int64_t field_2D0;
|
|
int64_t field_2D8;
|
|
int64_t field_2E0;
|
|
int16_t field_2E8;
|
|
int32_t field_2EC;
|
|
int32_t field_2F0;
|
|
struc_526 field_2F4;
|
|
int32_t field_2FC;
|
|
int8_t field_300;
|
|
int32_t field_304;
|
|
int32_t field_308;
|
|
float_t field_30C;
|
|
int32_t field_310;
|
|
int16_t field_314;
|
|
vec3 field_318;
|
|
float_t field_324;
|
|
float_t field_328;
|
|
int32_t iterations;
|
|
};
|
|
|
|
struct struc_377 {
|
|
void* current; // mothead_data
|
|
void* data; // mothead_data
|
|
};
|
|
|
|
struct struc_226 {
|
|
int8_t field_0[27];
|
|
};
|
|
|
|
struct struc_225 {
|
|
float_t field_0[27];
|
|
};
|
|
|
|
struct struc_224 {
|
|
int32_t field_0[27];
|
|
};
|
|
|
|
struct struc_306 {
|
|
int16_t field_0;
|
|
float_t frame;
|
|
float_t field_8;
|
|
int16_t field_C;
|
|
int16_t field_E;
|
|
vec3 field_10;
|
|
vec3 field_1C;
|
|
vec3 field_28;
|
|
int32_t field_34;
|
|
int32_t field_38;
|
|
int32_t field_3C;
|
|
int32_t field_40;
|
|
int32_t field_44;
|
|
int32_t field_48;
|
|
};
|
|
|
|
struct struc_651 {
|
|
struc_377 field_0;
|
|
int32_t field_10;
|
|
int32_t field_14;
|
|
int32_t field_18;
|
|
float_t field_1C;
|
|
vec3 field_20;
|
|
struc_226 field_2C[3];
|
|
struc_225 field_80[3];
|
|
struc_224 field_1C4[3];
|
|
int64_t field_308;
|
|
float_t field_310;
|
|
float_t field_314;
|
|
int8_t field_318;
|
|
int32_t field_31C;
|
|
float_t field_320;
|
|
float_t field_324;
|
|
float_t field_328;
|
|
float_t field_32C;
|
|
float_t field_330;
|
|
float_t field_334;
|
|
int8_t field_338;
|
|
struc_306 field_33C[4];
|
|
};
|
|
|
|
struct struc_223 {
|
|
struc_652 field_0;
|
|
struc_651 field_330;
|
|
int64_t* field_7A0;
|
|
int32_t motion_set_id;
|
|
};
|
|
|
|
static_assert(sizeof(struc_223) == 0x7B0, "\"struc_223\" struct should have a size of 0x7B0");
|
|
|
|
struct rob_chara_data_miku_rot {
|
|
uint8_t data[0xAC];
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_data_miku_rot) == 0xAC, "\"rob_chara_data_miku_rot\" struct should have a size of 0xAC");
|
|
|
|
struct rob_chara_adjust_data {
|
|
float_t scale;
|
|
bool height_adjust;
|
|
float_t pos_adjust_y;
|
|
vec3 pos_adjust;
|
|
vec3 offset;
|
|
bool offset_x;
|
|
bool offset_y;
|
|
bool offset_z;
|
|
bool get_global_trans;
|
|
vec3 trans;
|
|
mat4 mat;
|
|
float_t left_hand_scale;
|
|
float_t right_hand_scale;
|
|
float_t left_hand_scale_default;
|
|
float_t right_hand_scale_default;
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_adjust_data) == 0x84, "\"rob_chara_adjust_data\" struct should have a size of 0x84");
|
|
|
|
struct struc_209 {
|
|
uint8_t data[0x1F28];
|
|
};
|
|
|
|
static_assert(sizeof(struc_209) == 0x1F28, "\"struc_209\" struct should have a size of 0x1F28");
|
|
|
|
struct rob_chara_data {
|
|
uint8_t field_0;
|
|
uint8_t field_1;
|
|
uint8_t field_2;
|
|
uint8_t field_3;
|
|
int32_t field_4;
|
|
struc_264 field_8;
|
|
RobSubAction rob_sub_action;
|
|
rob_chara_motion motion;
|
|
struc_223 field_1588;
|
|
rob_chara_data_miku_rot miku_rot;
|
|
rob_chara_adjust_data adjust_data;
|
|
struc_209 field_1E68;
|
|
float_t field_3D90;
|
|
int32_t field_3D94;
|
|
int16_t field_3D98;
|
|
int16_t field_3D9A;
|
|
int32_t field_3D9C;
|
|
int32_t field_3DA0;
|
|
int8_t field_3DA4;
|
|
int64_t field_3DA8;
|
|
int64_t field_3DB0;
|
|
int32_t field_3DB8;
|
|
int32_t field_3DBC;
|
|
int32_t field_3DC0;
|
|
int32_t field_3DC4;
|
|
int32_t field_3DC8;
|
|
int32_t field_3DCC;
|
|
int32_t field_3DD0;
|
|
float_t field_3DD4;
|
|
int32_t field_3DD8;
|
|
float_t field_3DDC;
|
|
int8_t field_3DE0;
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_data) == 0x3DE8, "\"rob_chara_data\" struct should have a size of 0x3DE8");
|
|
|
|
struct rob_chara_pv_data {
|
|
uint8_t data[0xC4];
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara_pv_data) == 0xC4, "\"rob_chara_pv_data\" struct should have a size of 0xC4");
|
|
|
|
struct rob_touch {
|
|
uint8_t data[0x28];
|
|
};
|
|
|
|
static_assert(sizeof(rob_touch) == 0x28, "\"rob_touch\" struct should have a size of 0x28");
|
|
|
|
struct rob_chara {
|
|
int8_t chara_id;
|
|
int8_t field_1;
|
|
int8_t field_2;
|
|
int8_t field_3;
|
|
int32_t type;
|
|
int16_t field_8;
|
|
int16_t field_A;
|
|
bool field_C;
|
|
bool field_D;
|
|
chara_index chara_index;
|
|
int32_t cos_id;
|
|
int32_t field_18;
|
|
float_t frame_speed;
|
|
void* field_20;
|
|
struct rob_chara_bone_data* bone_data;
|
|
rob_chara_item_equip* item_equip;
|
|
rob_chara_item_cos_data item_cos_data;
|
|
rob_chara_data data;
|
|
rob_chara_data data_prev;
|
|
struct chara_init_data* chara_init_data;
|
|
struct rob_detail* rob_detail;
|
|
rob_chara_pv_data pv_data;
|
|
int32_t field_80E4;
|
|
rob_touch rob_touch;
|
|
};
|
|
|
|
static_assert(sizeof(rob_chara) == 0x8110, "\"rob_chara\" struct should have a size of 0x8110");
|
|
|
|
struct rob_chara_item_adjust_x {
|
|
mat4 mat;
|
|
vec3 trans;
|
|
float_t scale;
|
|
|
|
rob_chara_item_adjust_x();
|
|
|
|
void reset();
|
|
};
|
|
|
|
struct rob_chara_arm_adjust_x {
|
|
float_t next_value;
|
|
float_t prev_value;
|
|
int32_t start_frame;
|
|
float_t duration;
|
|
float_t scale;
|
|
|
|
rob_chara_arm_adjust_x();
|
|
|
|
void reset();
|
|
};
|
|
|
|
const mat4* (FASTCALL* rob_chara_bone_data_get_mats_mat)(size_t rob_bone_data, size_t index)
|
|
= (const mat4 * (FASTCALL*)(size_t rob_bone_data, size_t index))0x0000000140419520;
|
|
const char* (FASTCALL* chara_index_get_auth_3d_name)(chara_index chara_index)
|
|
= (const char* (FASTCALL*)(chara_index chara_index))0x0000000140508100;
|
|
void(FASTCALL* sub_1405163C0)(size_t rob_chr, int32_t index, mat4* mat)
|
|
= (void(FASTCALL*)(size_t rob_chr, int32_t index, mat4 * mat))0x00000001405163C0;
|
|
float_t(FASTCALL* rob_chara_get_max_face_depth)(size_t rob_chr)
|
|
= (float_t(FASTCALL*)(size_t rob_chr))0x0000000140516510;
|
|
const mat4* (FASTCALL* rob_chara_get_bone_data_mat)(size_t rob_chr, mot_bone_index index)
|
|
= (const mat4 * (FASTCALL*)(size_t rob_chr, mot_bone_index index))0x0000000140516730;
|
|
const mat4* (FASTCALL* sub_140516740)(size_t rob_chr)
|
|
= (const mat4 * (FASTCALL*)(size_t rob_chr))0x0000000140516740;
|
|
bool(FASTCALL* rob_chara_array_check_visibility)(size_t rob_chr_smth, int32_t chara_id)
|
|
= (bool(FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x0000000140531F50;
|
|
size_t(FASTCALL* get_rob_chara_smth)() = (size_t(FASTCALL*)())0x00000001405320E0;
|
|
size_t(FASTCALL* rob_chara_array_get)(size_t rob_chr_smth, int32_t chara_id)
|
|
= (size_t(FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x0000000140532030;
|
|
size_t(FASTCALL* rob_chara_array_get_bone_data)(size_t rob_chr_smth, int32_t chara_id)
|
|
= (size_t(FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x00000001405320F0;
|
|
bool (FASTCALL* rob_chara_pv_data_array_check_chara_id)(size_t rob_chr_smth, int32_t chara_id)
|
|
= (bool (FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x00000001405327B0;
|
|
|
|
static rob_chara_age_age* rob_chara_age_age_array = (rob_chara_age_age*)0x00000001411E83C0;
|
|
|
|
static bool& chara_reflect = *(bool*)0x00000001411ADAFC;
|
|
static bool& chara_refract = *(bool*)0x00000001411ADAFD;
|
|
|
|
const mat4* rob_chara_item_equip_mat = 0;
|
|
|
|
rob_chara_item_adjust_x rob_chara_item_adjust_x_array[ROB_CHARA_COUNT];
|
|
rob_chara_arm_adjust_x rob_chara_arm_adjust_x_array[ROB_CHARA_COUNT];
|
|
|
|
static void rob_chara_age_age_array_disp(int32_t chara_id, bool reflect, bool chara_color);
|
|
|
|
const mat4* rob_chara_get_adjust_data_mat(size_t rob_chr) {
|
|
return &((rob_chara*)rob_chr)->data.adjust_data.mat;
|
|
}
|
|
|
|
const mat4* rob_chara_get_item_adjust_data_mat(size_t rob_chr) {
|
|
int32_t chara_id = ((rob_chara*)rob_chr)->chara_id;
|
|
return &rob_chara_item_adjust_x_array[chara_id].mat;
|
|
}
|
|
|
|
HOOK(void, FASTCALL, sub_1405044B0, 0x00000001405044B0, rob_chara* rob_chr) {
|
|
rob_chara_item_adjust_x& item_adjust = rob_chara_item_adjust_x_array[rob_chr->chara_id];
|
|
rob_chara_arm_adjust_x& arm_adjust = rob_chara_arm_adjust_x_array[rob_chr->chara_id];
|
|
if (arm_adjust.duration > 0) {
|
|
float_t blend = 1.0f;
|
|
if (fabsf(arm_adjust.duration) > 0.000001f)
|
|
blend = (rob_chr->data.motion.frame_data.frame
|
|
- (float_t)arm_adjust.start_frame) / arm_adjust.duration;
|
|
|
|
blend = clamp_def(blend, 0.0f, 1.0f);
|
|
if (fabsf(blend - 1.0f) <= 0.000001f)
|
|
arm_adjust.duration = -1.0f;
|
|
arm_adjust.scale = lerp_def(arm_adjust.prev_value, arm_adjust.next_value, blend);
|
|
|
|
static float_t(FASTCALL * chara_size_table_get_value)(uint32_t id)
|
|
= (float_t(FASTCALL*)(uint32_t id))0x00000001405103C0;
|
|
|
|
float_t default_scale = chara_size_table_get_value(1);
|
|
item_adjust.scale = default_scale + (rob_chr->data.adjust_data.scale
|
|
- default_scale) * arm_adjust.scale;
|
|
}
|
|
|
|
originalsub_1405044B0(rob_chr);
|
|
}
|
|
|
|
static void rob_chara_data_adjuct_set_trans(rob_chara_adjust_data* rob_chr_adj,
|
|
rob_chara_item_adjust_x* rob_chr_itm_adj_x, vec3& trans, bool pos_adjust, vec3* global_trans) {
|
|
float_t scale = rob_chr_adj->scale;
|
|
float_t item_scale = rob_chr_itm_adj_x->scale;
|
|
vec3 _offset = rob_chr_adj->offset;
|
|
if (global_trans)
|
|
_offset.y += global_trans->y;
|
|
|
|
vec3 _trans = trans;
|
|
vec3 _item_trans = trans;
|
|
if (rob_chr_adj->height_adjust) {
|
|
_trans.y += rob_chr_adj->pos_adjust_y;
|
|
_item_trans.y += rob_chr_adj->pos_adjust_y;
|
|
}
|
|
else {
|
|
vec3 temp = (_trans - _offset) * scale + _offset;
|
|
vec3 arm_temp = (_item_trans - _offset) * item_scale + _offset;
|
|
|
|
if (!rob_chr_adj->offset_x) {
|
|
_trans.x = temp.x;
|
|
_item_trans.x = arm_temp.x;
|
|
}
|
|
|
|
if (!rob_chr_adj->offset_y) {
|
|
_trans.y = temp.y;
|
|
_item_trans.y = arm_temp.y;
|
|
}
|
|
|
|
if (!rob_chr_adj->offset_z) {
|
|
_trans.z = temp.z;
|
|
_item_trans.z = arm_temp.z;
|
|
}
|
|
}
|
|
|
|
if (pos_adjust) {
|
|
_trans = rob_chr_adj->pos_adjust + _trans;
|
|
_item_trans = rob_chr_adj->pos_adjust + _item_trans;
|
|
}
|
|
|
|
rob_chr_adj->trans = _trans - trans * scale;
|
|
rob_chr_itm_adj_x->trans = _item_trans - trans * item_scale;
|
|
}
|
|
|
|
HOOK(void, FASTCALL, rob_chara_set_data_adjust_mat, 0x00000001405050D0,
|
|
rob_chara* rob_chr, rob_chara_adjust_data* rob_chr_adj, bool pos_adjust) {
|
|
mat4 mat = *rob_chara_bone_data_get_mats_mat((size_t)rob_chr->bone_data, ROB_BONE_N_HARA_CP);
|
|
|
|
vec3 trans;
|
|
mat4_transpose(&mat, &mat);
|
|
mat4_get_translation(&mat, &trans);
|
|
|
|
rob_chara_item_adjust_x* item_adjust = &rob_chara_item_adjust_x_array[rob_chr->chara_id];
|
|
|
|
vec3* global_trans = 0;
|
|
if (rob_chr_adj->get_global_trans) {
|
|
static vec3* (FASTCALL * rob_chara_bone_data_get_global_trans)(size_t rob_bone_data)
|
|
= (vec3 * (FASTCALL*)(size_t rob_bone_data))0x0000000140419360;
|
|
|
|
global_trans = rob_chara_bone_data_get_global_trans((size_t)rob_chr->bone_data);
|
|
}
|
|
rob_chara_data_adjuct_set_trans(rob_chr_adj, item_adjust, trans, pos_adjust, global_trans);
|
|
|
|
float_t scale = rob_chr_adj->scale;
|
|
mat4_scale(scale, scale, scale, &rob_chr_adj->mat);
|
|
mat4_set_translation(&rob_chr_adj->mat, &rob_chr_adj->trans);
|
|
mat4_transpose(&rob_chr_adj->mat, &rob_chr_adj->mat);
|
|
|
|
float_t item_scale = item_adjust->scale;
|
|
mat4_scale(item_scale, item_scale, item_scale, &item_adjust->mat);
|
|
mat4_set_translation(&item_adjust->mat, &item_adjust->trans);
|
|
mat4_transpose(&item_adjust->mat, &item_adjust->mat);
|
|
}
|
|
|
|
HOOK(void, FASTCALL, rob_chara_reset_data, 0x0000000140507210, rob_chara* rob_chr, rob_chara_pv_data* pv_data) {
|
|
rob_chara_item_adjust_x& item_adjust = rob_chara_item_adjust_x_array[rob_chr->chara_id];
|
|
rob_chara_arm_adjust_x& arm_adjust = rob_chara_arm_adjust_x_array[rob_chr->chara_id];
|
|
|
|
item_adjust.reset();
|
|
arm_adjust.reset();
|
|
originalrob_chara_reset_data(rob_chr, pv_data);
|
|
item_adjust.scale = rob_chr->data.adjust_data.scale;
|
|
}
|
|
|
|
static void sub_140512C20(rob_chara_item_equip* rob_itm_equip) {
|
|
if (rob_itm_equip->field_D0.is_null() || rob_itm_equip->field_D4 == -1)
|
|
return;
|
|
|
|
mat4 mat = mat4_identity;
|
|
const char* name;
|
|
if (rob_itm_equip->field_DC == 1) {
|
|
name = "kl_te_r_wj";
|
|
mat4_translate(0.0f, 0.0f, 0.082f, &mat);
|
|
mat4_mul_rotate_zyx(&mat, (float_t)(-90.9 * DEG_TO_RAD), 0.0f, (float_t)(-179.5 * DEG_TO_RAD), &mat);
|
|
}
|
|
if (rob_itm_equip->field_DC == 2) {
|
|
name = "kl_te_l_wj";
|
|
mat4_translate(0.0f, 0.0015f, -0.0812f, &mat);
|
|
mat4_mul_rotate_zyx(&mat, (float_t)(-34.5 * DEG_TO_RAD), 0.0f, (float_t)(-179.5 * DEG_TO_RAD), &mat);
|
|
}
|
|
else
|
|
name = "j_1_hyoutan_000wj";
|
|
|
|
bone_node* node = rob_itm_equip->item_equip_object[rob_itm_equip->field_D4].get_bone_node(name);
|
|
if (!node || !node->mat)
|
|
return;
|
|
|
|
mat4_transpose(&mat, &mat);
|
|
mat4_mul(&mat, node->mat, &mat);
|
|
int32_t tex_pat_count = (int32_t)rob_itm_equip->texture_pattern.size();
|
|
if (tex_pat_count)
|
|
disp_manager->set_texture_pattern(tex_pat_count, rob_itm_equip->texture_pattern.data());
|
|
disp_manager->entry_obj_by_object_info(&mat, rob_itm_equip->field_D0);
|
|
if (tex_pat_count)
|
|
disp_manager->set_texture_pattern();
|
|
}
|
|
|
|
static float_t sub_140512F60(rob_chara_item_equip* rob_itm_equip) {
|
|
mat4* mats = rob_itm_equip->matrices;
|
|
float_t y = 1.0f;
|
|
y = min_def(y, mats[ 0].row1.w);
|
|
y = min_def(y, mats[175].row1.w);
|
|
y = min_def(y, mats[181].row1.w);
|
|
y = min_def(y, mats[105].row1.w);
|
|
y = min_def(y, mats[140].row1.w);
|
|
return y;
|
|
}
|
|
|
|
HOOK(void, FASTCALL, rob_chara_item_equip_disp, 0x0000000140512950,
|
|
rob_chara_item_equip* rob_item_equip, int32_t chara_id) {
|
|
|
|
mdl::ObjFlags flags = (mdl::ObjFlags)0;
|
|
if (chara_reflect)
|
|
enum_or(flags, mdl::OBJ_CHARA_REFLECT);
|
|
if (chara_refract)
|
|
enum_or(flags, mdl::OBJ_REFRACT);
|
|
|
|
mdl::DispManager& disp_manager = *::disp_manager;
|
|
if (rob_item_equip->shadow_type != -1) {
|
|
if (rob_item_equip->field_A0 & 0x04) {
|
|
vec3 pos = rob_item_equip->position;
|
|
pos.y -= 0.2f;
|
|
shadow_ptr_get()->field_1D0[rob_item_equip->shadow_type].push_back(pos);
|
|
|
|
float_t v9;
|
|
if (sub_140512F60(rob_item_equip) <= -0.2f)
|
|
v9 = -0.5f;
|
|
else
|
|
v9 = 0.05f;
|
|
shadow_ptr_get()->field_1C0[rob_item_equip->shadow_type] = v9;
|
|
disp_manager.set_shadow_type(rob_item_equip->shadow_type);
|
|
enum_or(flags, mdl::OBJ_SHADOW);
|
|
}
|
|
|
|
if (rob_item_equip->field_A0 & 0x01)
|
|
enum_or(flags, mdl::OBJ_4);
|
|
}
|
|
disp_manager.set_obj_flags(flags);
|
|
disp_manager.set_chara_color(rob_item_equip->chara_color);
|
|
|
|
vec4 temp_texture_color_coeff;
|
|
disp_manager.get_texture_color_coeff(temp_texture_color_coeff);
|
|
|
|
disp_manager.set_texture_color_coefficients(rob_item_equip->texture_color_coefficients);
|
|
disp_manager.set_wet_param(rob_item_equip->wet);
|
|
render_manager->field_31C |= rob_item_equip->npr_flag;
|
|
sub_140512C20(rob_item_equip);
|
|
rob_chara_age_age_array_disp(chara_id, chara_reflect, rob_item_equip->chara_color);
|
|
|
|
if (rob_item_equip->item_equip_range)
|
|
for (int32_t i = rob_item_equip->first_item_equip_object; i < rob_item_equip->max_item_equip_object; i++)
|
|
rob_item_equip->item_equip_object[i].disp(&rob_item_equip->mat);
|
|
else {
|
|
for (int32_t i = ITEM_ATAMA; i < ITEM_MAX; i++) {
|
|
mdl::ObjFlags chara_flags = (mdl::ObjFlags)0;
|
|
if (!rob_item_equip->field_18[i]) {
|
|
if (chara_reflect)
|
|
enum_or(chara_flags, mdl::OBJ_CHARA_REFLECT);
|
|
if (chara_refract)
|
|
enum_or(chara_flags, mdl::OBJ_REFRACT);
|
|
}
|
|
|
|
mdl::ObjFlags flags = (mdl::ObjFlags)(mdl::OBJ_4 | mdl::OBJ_SHADOW);
|
|
if (i == ITEM_HARA)
|
|
flags = (mdl::ObjFlags)0;
|
|
|
|
if (!(rob_item_equip->field_A0 & 0x04))
|
|
enum_and(flags, ~mdl::OBJ_SHADOW);
|
|
|
|
disp_manager.set_obj_flags((mdl::ObjFlags)(chara_flags | flags | mdl::OBJ_SSS));
|
|
rob_item_equip->item_equip_object[i].disp(&rob_item_equip->mat);
|
|
}
|
|
}
|
|
disp_manager.set_texture_color_coefficients(temp_texture_color_coeff);
|
|
disp_manager.set_wet_param();
|
|
disp_manager.set_chara_color();
|
|
disp_manager.set_obj_flags();
|
|
disp_manager.set_shadow_type();
|
|
}
|
|
|
|
HOOK(void, FASTCALL, rob_chara_set_chara_size, 0x0000000140516810, rob_chara* rob_chr, float_t value) {
|
|
originalrob_chara_set_chara_size(rob_chr, value);
|
|
rob_chara_item_adjust_x& item_adjust = rob_chara_item_adjust_x_array[rob_chr->chara_id];
|
|
item_adjust.scale = value;
|
|
}
|
|
|
|
HOOK(void, FASTCALL, sub_1405335C0, 0x0000001405335C0, struc_223* a1) {
|
|
originalsub_1405335C0(a1);
|
|
int32_t chara_id = ((rob_chara*)((size_t)a1 - 0x19C8))->chara_id;
|
|
rob_chara_arm_adjust_x_array[chara_id].reset();
|
|
}
|
|
|
|
HOOK(void, FASTCALL, mothead_func_32, 0x0000000140533C00, struct mothead_func_data* func_data,
|
|
void* data, const struct mothead_data* mhd_data, int64_t frame) {
|
|
float_t v8 = (float_t)((int16_t*)data)[0];
|
|
int32_t v5 = ((int32_t*)data)[1];
|
|
float_t v9 = ((float_t*)data)[2];
|
|
int32_t v10 = ((int32_t*)data)[3];
|
|
|
|
if (v8 != (int16_t)0xFA0C || v10 != 0xD62721C5) { // X
|
|
originalmothead_func_32(func_data, data, mhd_data, frame);
|
|
return;
|
|
}
|
|
|
|
size_t rob_chr_data = *(size_t*)((size_t)func_data + 0x08);
|
|
rob_chara* rob_chr = ((rob_chara*)((size_t)rob_chr_data - 0x440));
|
|
|
|
float_t value = v9;
|
|
float_t duration = (float_t)v5;
|
|
rob_chara_arm_adjust_x& arm_adjust = rob_chara_arm_adjust_x_array[rob_chr->chara_id];
|
|
arm_adjust.next_value = value;
|
|
arm_adjust.prev_value = arm_adjust.scale;
|
|
arm_adjust.start_frame = (int32_t)frame;
|
|
arm_adjust.duration = max_def(duration, 0.0f);
|
|
return;
|
|
}
|
|
|
|
HOOK(bool, FASTCALL, sub_14053ACA0, 0x000000014053ACA0, rob_chara* rob_chr, int32_t hand) {
|
|
if (hand >= 2 || !rob_chr->data.motion.hand_adjust[hand].enable)
|
|
return false;
|
|
|
|
rob_chara_item_adjust_x& item_adjust = rob_chara_item_adjust_x_array[rob_chr->chara_id];
|
|
rob_chara_item_adjust_x item_adjust_temp = item_adjust;
|
|
float_t chara_scale = rob_chr->data.adjust_data.scale;
|
|
float_t adjust_scale = rob_chr->data.motion.hand_adjust[hand].current_scale;
|
|
item_adjust.scale = adjust_scale / chara_scale;
|
|
originalsub_14053ACA0(rob_chr, hand);
|
|
item_adjust = item_adjust_temp;
|
|
return true;
|
|
}
|
|
|
|
HOOK(void, FASTCALL, rob_chara_set_hand_adjust, 0x000000014053C070, rob_chara* rob_chr,
|
|
rob_chara_data_hand_adjust* adjust, rob_chara_data_hand_adjust* prev_adjust) {
|
|
if (!adjust->enable)
|
|
return;
|
|
|
|
static float_t(FASTCALL * chara_size_table_get_value)(uint32_t id)
|
|
= (float_t(FASTCALL*)(uint32_t id))0x00000001405103C0;
|
|
static float_t(FASTCALL * rob_chara_array_get_data_adjust_scale)(size_t rob_chr_smth, int32_t chara_id)
|
|
= (float_t(FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x0000000140531F90;
|
|
|
|
float_t chara_scale = rob_chr->data.adjust_data.scale;
|
|
float_t opposite_chara_scale = rob_chara_array_get_data_adjust_scale(get_rob_chara_smth(), rob_chr->chara_id ? 0 : 1);
|
|
bool chara_opposite_chara_same = fabsf(chara_scale - opposite_chara_scale) <= 0.000001f;
|
|
|
|
switch (adjust->type) {
|
|
case ROB_CHARA_DATA_HAND_ADJUST_NORMAL:
|
|
adjust->scale = chara_size_table_get_value(1);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_SHORT:
|
|
adjust->scale = chara_size_table_get_value(2);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_TALL:
|
|
adjust->scale = chara_size_table_get_value(0);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_MIN:
|
|
adjust->scale = min_def(opposite_chara_scale, chara_scale);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_MAX:
|
|
adjust->scale = max_def(opposite_chara_scale, chara_scale);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_OPPOSITE_CHARA:
|
|
adjust->scale = opposite_chara_scale;
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_1P:
|
|
adjust->scale = rob_chara_array_get_data_adjust_scale(get_rob_chara_smth(), 0);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_2P:
|
|
adjust->scale = rob_chara_array_get_data_adjust_scale(get_rob_chara_smth(), 1);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_3P:
|
|
adjust->scale = rob_chara_array_get_data_adjust_scale(get_rob_chara_smth(), 2);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_4P:
|
|
adjust->scale = rob_chara_array_get_data_adjust_scale(get_rob_chara_smth(), 3);
|
|
break;
|
|
case ROB_CHARA_DATA_HAND_ADJUST_ITEM: // X
|
|
adjust->scale = rob_chara_item_adjust_x_array[rob_chr->chara_id].scale;
|
|
break;
|
|
}
|
|
|
|
if (adjust->scale_select == 1 && adjust->enable_scale && chara_opposite_chara_same) {
|
|
adjust->scale_select = 0;
|
|
adjust->rotation_blend = prev_adjust->rotation_blend;
|
|
adjust->disable_x = prev_adjust->disable_x;
|
|
adjust->disable_y = prev_adjust->disable_y;
|
|
adjust->disable_z = prev_adjust->disable_z;
|
|
adjust->scale_blend = 1.0f;
|
|
}
|
|
|
|
float_t prev_scale;
|
|
if (prev_adjust->enable || prev_adjust->scale_select == 1)
|
|
prev_scale = prev_adjust->current_scale;
|
|
else
|
|
prev_scale = chara_scale;
|
|
|
|
float_t scale;
|
|
if (adjust->scale_select == 1)
|
|
scale = adjust->scale;
|
|
else
|
|
scale = chara_scale;
|
|
|
|
if (fabsf(prev_scale - scale * adjust->scale_blend) <= 0.000001f || adjust->duration <= adjust->current_time
|
|
|| fabsf(adjust->duration - adjust->current_time) <= 0.000001f) {
|
|
adjust->current_scale = lerp_def(prev_scale, scale, adjust->scale_blend);
|
|
if (fabsf(adjust->current_scale - chara_scale) <= 0.000001f
|
|
&& adjust->type != ROB_CHARA_DATA_HAND_ADJUST_ITEM) {
|
|
adjust->current_scale = chara_scale;
|
|
adjust->enable = false;
|
|
}
|
|
}
|
|
else {
|
|
float_t t = (adjust->current_time + 1.0f) / (adjust->duration + 1.0f);
|
|
adjust->current_scale = lerp_def(prev_scale, scale, t * adjust->scale_blend);
|
|
adjust->current_time += rob_chr->data.motion.step_data.frame;
|
|
}
|
|
}
|
|
|
|
void rob_patch() {
|
|
INSTALL_HOOK(rob_chara_set_data_adjust_mat);
|
|
INSTALL_HOOK(rob_chara_reset_data);
|
|
INSTALL_HOOK(sub_1405044B0);
|
|
INSTALL_HOOK(rob_chara_item_equip_disp);
|
|
INSTALL_HOOK(rob_chara_set_chara_size);
|
|
INSTALL_HOOK(sub_1405335C0);
|
|
INSTALL_HOOK(mothead_func_32);
|
|
INSTALL_HOOK(sub_14053ACA0);
|
|
INSTALL_HOOK(rob_chara_set_hand_adjust);
|
|
}
|
|
|
|
void rob_chara_age_age_object::disp(size_t chara_index,
|
|
bool npr, bool reflect, const vec3& a5, bool chara_color) {
|
|
int32_t disp_count = this->disp_count;
|
|
if (!objset_info || !disp_count)
|
|
return;
|
|
|
|
disp_count = min_def(disp_count, 10);
|
|
|
|
std::pair<float_t, int32_t> v44[10];
|
|
for (int32_t i = 0; i < disp_count; i++) {
|
|
v44[i].first = vec3::dot(trans[i], a5);
|
|
v44[i].second = i;
|
|
}
|
|
|
|
if (disp_count >= 2)
|
|
std::sort(v44, v44 + disp_count,
|
|
[](const std::pair<float_t, int32_t>& a, const std::pair<float_t, int32_t>& b) {
|
|
return a.first < b.first;
|
|
});
|
|
|
|
obj_vert_buf.cycle_index();
|
|
|
|
GLArrayBuffer buffer = obj_vert_buf.get_buffer();
|
|
size_t vtx_data = (size_t)buffer.MapMemory();
|
|
if (!vtx_data)
|
|
return;
|
|
|
|
size_t vertex_array_size = this->vertex_array_size;
|
|
for (int32_t i = 0; i < disp_count; i++)
|
|
memmove((void*)(vtx_data + vertex_array_size * i),
|
|
(void*)((size_t)vertex_data + vertex_array_size * v44[i].second), vertex_array_size);
|
|
|
|
buffer.UnmapMemory();
|
|
|
|
mesh.num_vertex = disp_count * num_vertex;
|
|
sub_mesh.num_index = disp_count * num_index;
|
|
sub_mesh.material_index = npr ? 1 : 0;
|
|
|
|
mdl::ObjFlags flags = (mdl::ObjFlags)(mdl::OBJ_SSS | mdl::OBJ_4 | mdl::OBJ_SHADOW);
|
|
if (reflect)
|
|
enum_or(flags, mdl::OBJ_CHARA_REFLECT);
|
|
disp_manager->set_obj_flags(flags);
|
|
disp_manager->set_chara_color(chara_color);
|
|
disp_manager->set_shadow_type(chara_index ? SHADOW_STAGE : SHADOW_CHARA);
|
|
|
|
static prj::vector<GLuint>* (FASTCALL * rob_chara_age_age_object__get_obj_set_texture)(rob_chara_age_age_object * rob_age_age_obj)
|
|
= (prj::vector<GLuint>*(FASTCALL*)(rob_chara_age_age_object * rob_age_age_obj))0x000000014045A8E0;
|
|
disp_manager->entry_obj_by_obj(&mat4_identity, &obj,
|
|
rob_chara_age_age_object__get_obj_set_texture(this),
|
|
&obj_vert_buf, &obj_index_buf, 0, 1.0f);
|
|
}
|
|
|
|
void rob_chara_age_age::disp(size_t chara_id,
|
|
bool npr, bool reflect, const vec3& a5, bool chara_color) {
|
|
if (alpha >= 0.1f && this->visible)
|
|
object.disp(chara_id, npr || this->npr, reflect, a5, chara_color);
|
|
}
|
|
|
|
void rob_chara_item_equip_object::disp(const mat4* mat) {
|
|
if (obj_info.is_null())
|
|
return;
|
|
|
|
mdl::ObjFlags flags = disp_manager->get_obj_flags();
|
|
mdl::ObjFlags chara_flags = flags;
|
|
if (fabsf(alpha - 1.0f) > 0.000001f)
|
|
enum_or(chara_flags, obj_flags);
|
|
else
|
|
enum_and(chara_flags, ~(mdl::OBJ_ALPHA_ORDER_3 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_1));
|
|
disp_manager->set_obj_flags(chara_flags);
|
|
if (can_disp) {
|
|
disp_manager->entry_obj_by_object_info_object_skin(obj_info,
|
|
&texture_pattern, &texture_data, alpha, mats, ex_data_bone_mats.data(), 0, mat);
|
|
|
|
rob_chara_item_equip_mat = mat;
|
|
|
|
for (ExNodeBlock*& i : node_blocks)
|
|
i->__vftable->Disp(i);
|
|
}
|
|
disp_manager->set_obj_flags(flags);
|
|
}
|
|
|
|
int32_t rob_chara_item_equip_object::get_bone_index(const char* name) {
|
|
int32_t(FASTCALL * sub_1401F13B0)(int32_t a1, const char* a2)
|
|
= (int32_t(FASTCALL*)(int32_t a1, const char* a2))0x00000001401F13B0;
|
|
|
|
int32_t bone_index = sub_1401F13B0(0, name);
|
|
if (bone_index == -1)
|
|
for (auto& i : ex_bones)
|
|
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) {
|
|
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 0;
|
|
}
|
|
|
|
bone_node* rob_chara_item_equip_object::get_bone_node(const char* name) {
|
|
return get_bone_node(get_bone_index(name));
|
|
}
|
|
|
|
rob_chara_item_adjust_x::rob_chara_item_adjust_x() : scale() {
|
|
reset();
|
|
}
|
|
|
|
void rob_chara_item_adjust_x::reset() {
|
|
mat4_translate(&trans, &mat);
|
|
mat4_transpose(&mat, &mat);
|
|
scale = 1.0f;
|
|
}
|
|
|
|
rob_chara_arm_adjust_x::rob_chara_arm_adjust_x() : next_value(),
|
|
prev_value(), start_frame(), duration(), scale() {
|
|
reset();
|
|
}
|
|
|
|
void rob_chara_arm_adjust_x::reset() {
|
|
next_value = 0.0f;
|
|
prev_value = 0.0f;
|
|
start_frame = -1;
|
|
duration = -1.0f;
|
|
scale = 1.0f;
|
|
}
|
|
|
|
static void rob_chara_age_age_disp(rob_chara_age_age* arr,
|
|
int32_t chara_id, bool reflect, bool chara_color) {
|
|
bool npr = !!render_manager->npr_param;
|
|
mat4& view = camera_data->view;
|
|
vec3 v11 = *(vec3*)&view.row2;
|
|
arr[chara_id * 3 + 0].disp(chara_id, npr, reflect, v11, chara_color);
|
|
arr[chara_id * 3 + 1].disp(chara_id, npr, reflect, v11, chara_color);
|
|
arr[chara_id * 3 + 2].disp(chara_id, npr, reflect, v11, chara_color);
|
|
}
|
|
|
|
static void rob_chara_age_age_array_disp(int32_t chara_id, bool reflect, bool chara_color) {
|
|
mdl::ObjFlags obj_flags = disp_manager->get_obj_flags();
|
|
rob_chara_age_age_disp(rob_chara_age_age_array, chara_id, reflect, chara_color);
|
|
disp_manager->set_obj_flags(obj_flags);
|
|
}
|