/* by korenkonder GitHub/GitLab: korenkonder */ #include "auth_3d.hpp" #include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/io/json.hpp" #include "../KKdLib/io/path.hpp" #include "../KKdLib/prj/algorithm.hpp" #include "../KKdLib/hash.hpp" #include "../KKdLib/interpolation.hpp" #include "../KKdLib/msgpack.hpp" #include "../KKdLib/sort.hpp" #include "../KKdLib/str_utils.hpp" #include "rob/rob.hpp" #include "app_system_detail.hpp" #include "clear_color.hpp" #include "data.hpp" #include "effect.hpp" #include "object.hpp" #include "pv_db.hpp" #include "task.hpp" #include "sound.hpp" #include "sprite.hpp" #include "stage.hpp" namespace auth_3d_detail { class TaskAuth3d : public app::Task { public: TaskAuth3d(); virtual ~TaskAuth3d() override; virtual bool init() override; virtual bool ctrl() override; virtual void disp() override; }; class FrameRateTimeStop : public FrameRateControl { public: FrameRateTimeStop(); virtual ~FrameRateTimeStop() override; virtual float_t get_delta_frame() override; }; } typedef a3da_ambient auth_3d_ambient_file; typedef a3da_camera_auxiliary auth_3d_camera_auxiliary_file; typedef a3da_camera_root auth_3d_camera_root_file; typedef a3da_camera_root_view_point auth_3d_camera_root_view_point_file; typedef a3da_chara auth_3d_chara_file; typedef a3da_curve auth_3d_curve_file; typedef a3da_dof auth_3d_dof_file; typedef a3da_event auth_3d_event_file; typedef a3da_fog auth_3d_fog_file; typedef a3da_key auth_3d_key_file; typedef a3da_light auth_3d_light_file; typedef a3da_m_object_hrc auth_3d_m_object_hrc_file; typedef a3da_object_instance auth_3d_object_instance_file; typedef a3da_material_list auth_3d_material_list_file; typedef a3da_model_transform auth_3d_model_transform_file; typedef a3da_object auth_3d_object_file; typedef a3da_object_hrc auth_3d_object_hrc_file; typedef a3da_object_node auth_3d_object_node_file; typedef a3da_object_texture_pattern auth_3d_object_texture_pattern_file; typedef a3da_object_texture_transform auth_3d_object_texture_transform_file; typedef a3da_play_control auth_3d_play_control_file; typedef a3da_point auth_3d_point_file; typedef a3da_post_process auth_3d_post_process_file; typedef a3da_rgba auth_3d_rgba_file; typedef a3da_vec3 auth_3d_vec3_file; static void a3da_msgpack_read(const char* path, const char* file, a3da* auth_file); static bool auth_3d_key_detect_fast_change(auth_3d_key* data, float_t frame, float_t threshold); static kft3* auth_3d_key_find_keyframe(auth_3d_key* data, float_t frame); static float_t auth_3d_key_interpolate_inner(auth_3d_key* data, float_t frame); static float_t auth_3d_interpolate_value(auth_3d_key_type type, float_t frame, kft3* curr_key, kft3* next_key); static void auth_3d_key_load(auth_3d* auth, auth_3d_key* k, auth_3d_key_file* kf); static void auth_3d_key_store(auth_3d* auth, auth_3d_key* k, auth_3d_key_file* kf); static void auth_3d_rgba_load(auth_3d* auth, auth_3d_rgba* rgba, auth_3d_rgba_file* rgbaf); static void auth_3d_rgba_store(auth_3d* auth, auth_3d_rgba* rgba, auth_3d_rgba_file* rgbaf); static void auth_3d_vec3_load(auth_3d* auth, auth_3d_vec3* vec, auth_3d_vec3_file* vecf); static void auth_3d_vec3_store(auth_3d* auth, auth_3d_vec3* vec, auth_3d_vec3_file* vecf); static void auth_3d_model_transform_load(auth_3d* auth, auth_3d_model_transform* mt, auth_3d_model_transform_file* mtf); static void auth_3d_model_transform_store(auth_3d* auth, auth_3d_model_transform* mt, auth_3d_model_transform_file* mtf); static int32_t auth_3d_get_auth_3d_object_index_by_object_info(auth_3d* auth, object_info obj_info, int32_t object_instance); static int32_t auth_3d_get_auth_3d_object_index_by_hash(auth_3d* auth, uint32_t object_hash, int32_t object_instance); static const mat4* auth_3d_get_auth_3d_object_mat(auth_3d* auth, size_t index); static const mat4* auth_3d_get_auth_3d_object_hrc_bone_mats(auth_3d* auth, size_t index); static int32_t auth_3d_get_auth_3d_object_hrc_index_by_object_info(auth_3d* auth, object_info obj_info, int32_t object_instance = -1); static int32_t auth_3d_get_auth_3d_object_hrc_index_by_hash(auth_3d* auth, uint32_t object_hash, int32_t object_instance = -1); static void auth_3d_read_file(auth_3d* auth, auth_3d_database* auth_3d_db); static void auth_3d_read_file_modern(auth_3d* auth); static void auth_3d_set_material_list(auth_3d* auth, render_context* rctx); static void auth_3d_ambient_load(auth_3d* auth, auth_3d_ambient* a, auth_3d_ambient_file* af); static void auth_3d_ambient_set(auth_3d_ambient* a, render_context* rctx); static void auth_3d_ambient_store(auth_3d* auth, auth_3d_ambient* a, auth_3d_ambient_file* af); static void auth_3d_camera_auxiliary_load(auth_3d* auth, auth_3d_camera_auxiliary_file* caf); static void auth_3d_camera_auxiliary_restore_prev_value(auth_3d_camera_auxiliary* ca, render_context* rctx); static void auth_3d_camera_auxiliary_set(auth_3d_camera_auxiliary* ca, render_context* rctx); static void auth_3d_camera_auxiliary_store(auth_3d* auth, auth_3d_camera_auxiliary_file* caf); static float_t auth_3d_camera_root_calc_frame(auth_3d_camera_root* cr, float_t frame, render_context* rctx); static void auth_3d_camera_root_load(auth_3d* auth, auth_3d_camera_root* cr, auth_3d_camera_root_file* crf); static void auth_3d_camera_root_store(auth_3d* auth, auth_3d_camera_root* cr, auth_3d_camera_root_file* crf); static void auth_3d_camera_root_view_point_load(auth_3d* auth, auth_3d_camera_root_view_point* crvp, auth_3d_camera_root_view_point_file* crvpf); static void auth_3d_camera_root_view_point_store(auth_3d* auth, auth_3d_camera_root_view_point* crvp, auth_3d_camera_root_view_point_file* crvpf); static void auth_3d_chara_disp(auth_3d_chara* c, auth_3d* auth, render_context* rctx); static void auth_3d_chara_load(auth_3d* auth, auth_3d_chara* c, auth_3d_chara_file* cf); static void auth_3d_chara_store(auth_3d* auth, auth_3d_chara* c, auth_3d_chara_file* cf); static void auth_3d_curve_load(auth_3d* auth, auth_3d_curve* c, auth_3d_curve_file* cf); static void auth_3d_curve_store(auth_3d* auth, auth_3d_curve* c, auth_3d_curve_file* cf); static void auth_3d_dof_load(auth_3d* auth, auth_3d_dof* d, auth_3d_dof_file* df); static void auth_3d_dof_restore_prev_value(auth_3d_dof* d, render_context* rctx); static void auth_3d_dof_set(auth_3d_dof* d, render_context* rctx); static void auth_3d_dof_store(auth_3d* auth, auth_3d_dof* d, auth_3d_dof_file* df); static auth_3d_detail::Event* auth_3d_event_load(auth_3d* auth, auth_3d_event_file* ef); static void auth_3d_event_store(auth_3d* auth, auth_3d_detail::Event* e, auth_3d_event_file* ef); static const char* auth_3d_event_type_string(auth_3d_detail::Event::Type type); static void auth_3d_fog_load(auth_3d* auth, auth_3d_fog* f, auth_3d_fog_file* ff); static void auth_3d_fog_restore_prev_value(auth_3d_fog* f, render_context* rctx); static void auth_3d_fog_set(auth_3d_fog* f, render_context* rctx); static void auth_3d_fog_store(auth_3d* auth, auth_3d_fog* f, auth_3d_fog_file* ff); static void auth_3d_light_load(auth_3d* auth, auth_3d_light* l, auth_3d_light_file* lf); static void auth_3d_light_restore_prev_value(auth_3d_light* l, render_context* rctx); static void auth_3d_light_set(auth_3d_light* l, render_context* rctx); static void auth_3d_light_store(auth_3d* auth, auth_3d_light* l, auth_3d_light_file* lf); static void auth_3d_m_object_hrc_disp(auth_3d_m_object_hrc* moh, auth_3d* auth, render_context* rctx); static void auth_3d_m_object_hrc_get_mat(auth_3d_m_object_hrc* moh, mat4* mat); static void auth_3d_m_object_hrc_load(auth_3d* auth, auth_3d_m_object_hrc* moh, auth_3d_m_object_hrc_file* mohf, object_database* obj_db); static void auth_3d_m_object_hrc_nodes_mat_mult(auth_3d_m_object_hrc* moh); static void auth_3d_m_object_hrc_store(auth_3d* auth, auth_3d_m_object_hrc* moh, auth_3d_m_object_hrc_file* mohf); static void auth_3d_material_list_load(auth_3d* auth, auth_3d_material_list* ml, auth_3d_material_list_file* mlf); static void auth_3d_material_list_store(auth_3d* auth, auth_3d_material_list* ml, auth_3d_material_list_file* mlf); static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context* rctx); static void auth_3d_object_load(auth_3d* auth, auth_3d_object* o, auth_3d_object_file* of, object_database* obj_db, texture_database* tex_db); static void auth_3d_object_store(auth_3d* auth, auth_3d_object* o, auth_3d_object_file* of); static void auth_3d_object_curve_load(auth_3d* auth, auth_3d_object_curve* oc, std::string& name, float_t frame_offset); static void auth_3d_object_curve_store(auth_3d* auth, auth_3d_object_curve* oc, std::string& name, float_t& frame_offset); static void auth_3d_object_hrc_disp(auth_3d_object_hrc* oh, auth_3d* auth, render_context* rctx); static void auth_3d_object_hrc_load(auth_3d* auth, auth_3d_object_hrc* oh, auth_3d_object_hrc_file* ohf, object_database* obj_db); static void auth_3d_object_hrc_store(auth_3d* auth, auth_3d_object_hrc* oh, auth_3d_object_hrc_file* ohf); static bool auth_3d_object_hrc_replace_chara(auth_3d_object_hrc* oh, chara_index src_chara, chara_index dst_chara, object_database* obj_db); static void auth_3d_object_hrc_nodes_mat_mult(auth_3d_object_hrc* oh, const mat4* mat); static void auth_3d_object_instance_load(auth_3d* auth, auth_3d_object_instance* oi, auth_3d_object_instance_file* oif, auth_3d_m_object_hrc* moh, object_database* obj_db); static void auth_3d_object_instance_store(auth_3d* auth, auth_3d_object_instance* oi, auth_3d_object_instance_file* oif, auth_3d_m_object_hrc* moh); static void auth_3d_object_model_transform_load(auth_3d* auth, auth_3d_object_model_transform* omt, auth_3d_model_transform_file* mtf); static void auth_3d_object_model_transform_store(auth_3d* auth, auth_3d_object_model_transform* omt, auth_3d_model_transform_file* mtf); static void auth_3d_object_node_load(auth_3d* auth, auth_3d_object_node* on, auth_3d_object_node_file* onf); static void auth_3d_object_node_store(auth_3d* auth, auth_3d_object_node* on, auth_3d_object_node_file* onf); static void auth_3d_object_texture_pattern_load(auth_3d* auth, auth_3d_object_texture_pattern* otp, auth_3d_object_texture_pattern_file* otpf, texture_database* tex_db); static void auth_3d_object_texture_pattern_store(auth_3d* auth, auth_3d_object_texture_pattern* otp, auth_3d_object_texture_pattern_file* otpf); static void auth_3d_object_texture_transform_load(auth_3d* auth, auth_3d_object_texture_transform* ott, auth_3d_object_texture_transform_file* ottf, texture_database* tex_db); static void auth_3d_object_texture_transform_store(auth_3d* auth, auth_3d_object_texture_transform* ott, auth_3d_object_texture_transform_file* ottf); static void auth_3d_play_control_load(auth_3d* auth, auth_3d_play_control_file* pcf); static void auth_3d_play_control_store(auth_3d* auth, auth_3d_play_control_file* pcf); static void auth_3d_point_disp(auth_3d_point* p, auth_3d* auth, render_context* rctx); static void auth_3d_point_load(auth_3d* auth, auth_3d_point* p, auth_3d_point_file* pf); static void auth_3d_point_store(auth_3d* auth, auth_3d_point* p, auth_3d_point_file* pf); static void auth_3d_post_process_load(auth_3d* auth, auth_3d_post_process* pp, auth_3d_post_process_file* ppf); static void auth_3d_post_process_restore_prev_value(auth_3d_post_process* pp, render_context* rctx); static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* rctx); static void auth_3d_post_process_store(auth_3d* auth, auth_3d_post_process* pp, auth_3d_post_process_file* ppf); static bool auth_3d_data_struct_init(auth_3d_data_struct* auth_3d_data, render_context* rctx); static bool auth_3d_data_struct_check_category_loaded( auth_3d_data_struct* auth_3d_data, const char* category_name); static bool auth_3d_data_struct_check_category_loaded( auth_3d_data_struct* auth_3d_data, uint32_t category_hash); static bool auth_3d_data_struct_ctrl(auth_3d_data_struct* auth_3d_data, render_context* rctx); static void auth_3d_data_struct_disp(auth_3d_data_struct* auth_3d_data, render_context* rctx); static auth_3d_farc* auth_3d_data_struct_get_farc( auth_3d_data_struct* auth_3d_data, const char* category_name); static void auth_3d_data_struct_load_category(auth_3d_data_struct* auth_3d_data, const char* category_name, const char* mdata_dir); static void auth_3d_data_struct_load_category(auth_3d_data_struct* auth_3d_data, void* data, const char* category_name, uint32_t category_hash); static void auth_3d_data_struct_unload_category(auth_3d_data_struct* auth_3d_data, const char* category_name); static void auth_3d_data_struct_unload_category( auth_3d_data_struct* auth_3d_data, uint32_t category_hash); static void auth_3d_farc_load(auth_3d_farc* a3da_farc, const char* mdata_dir); static void auth_3d_farc_load_modern(auth_3d_farc* a3da_farc, void* data); static void auth_3d_farc_read_file(auth_3d_farc* a3da_farc, const char* mdata_dir); static void auth_3d_farc_read_file_modern(auth_3d_farc* a3da_farc, void* data); static bool auth_3d_farc_read_func(auth_3d_farc* a3da_farc, const void* data, size_t size); static void auth_3d_farc_reset(auth_3d_farc* a3da_farc); static void auth_3d_farc_unload(auth_3d_farc* a3da_farc); static void auth_3d_uid_file_load(auth_3d_uid_file* uid_file); static void auth_3d_uid_file_modern_load(auth_3d_uid_file_modern* uid_file); static void auth_3d_uid_file_load_file(auth_3d_uid_file* uid_file, auth_3d_database* auth_3d_db); static void auth_3d_uid_file_modern_load_file(auth_3d_uid_file_modern* uid_file); static void auth_3d_uid_file_unload(auth_3d_uid_file* uid_file); static void auth_3d_uid_file_modern_unload(auth_3d_uid_file_modern* uid_file); static void auth_3d_uid_file_unload_file(auth_3d_uid_file* uid_file); static void auth_3d_uid_file_modern_unload_file(auth_3d_uid_file_modern* uid_file); static size_t auth_3d_time_event_radix_index_func_frame(auth_3d_time_event* data, size_t index); auth_3d_data_struct* auth_3d_data; auth_3d_detail::TaskAuth3d* task_auth_3d; static int16_t auth_3d_load_counter; static auth_3d_detail::FrameRateTimeStop frame_rate_time_stop; extern render_context* rctx_ptr; auth_3d::auth_3d() : uid(), id(), mat(), enable(), camera_root_update(), visible(), repeat(), ended(), left_right_reverse(), once(), alpha(), chara_id(), chara_item(), shadow(), pos(), frame_rate(), frame(), req_frame(), max_frame(), frame_changed(), frame_offset(), last_frame(), paused(), event_time_next() { hash = hash_murmurhash_empty; src_chara = CHARA_MAX; dst_chara = CHARA_MAX; reset(); } auth_3d::~auth_3d() { reset(); } void auth_3d::ctrl(render_context* rctx) { if (state == 1) if (hash == hash_murmurhash_empty) { data_struct* aft_data = &data_list[DATA_AFT]; auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; object_database* aft_obj_db = &aft_data->data_ft.obj_db; texture_database* aft_tex_db = &aft_data->data_ft.tex_db; auth_3d_database_uid* db_uid = &aft_auth_3d_db->uid[uid]; if (db_uid->enabled) { auth_3d_uid_file* uid_file = &auth_3d_data->uid_files[uid]; if (uid_file->uid == uid && uid_file->state == 1 && uid_file->farc->state == 2) { state = 2; farc_file* ff = uid_file->farc->farc->read_file(uid_file->file_name.c_str()); if (ff) { a3da a; a.read(ff->data, ff->size); load(&a, aft_obj_db, aft_tex_db); frame = 0.0f; } } } } else { auto elem = auth_3d_data->uid_files_modern.find(hash); if (elem == auth_3d_data->uid_files_modern.end()) return; auth_3d_uid_file_modern* uid_file = &elem->second; if (uid_file->hash == hash && uid_file->state == 1 && uid_file->farc->state == 2) { state = 2; farc_file* ff = uid_file->farc->farc->read_file(uid_file->hash); if (ff) { a3da a; a.read(ff->data, ff->size); a3da_msgpack_read("patch\\AFT\\auth_3d", a._file_name.c_str(), &a); const char* l_str = ff->name.c_str(); const char* t = strrchr(l_str, '.'); size_t l_len = ff->name.size(); if (t) l_len = t - l_str; uid_file->name.assign(ff->name.c_str(), l_len); uid_file->file_name.assign(ff->name); file_name.assign(ff->name); load(&a, uid_file->obj_db, uid_file->tex_db); hash = uid_file->hash; frame = 0.0f; } } } if (state != 2 || !enable) return; int32_t event_flags = 0; bool set = false; while (true) { if (frame_changed) { frame_changed = false; if (req_frame < frame) { event_time_next = event_time.data(); event_flags |= 0x02; } else event_flags |= 0x04; frame = req_frame; ended = false; if (max_frame >= 0.0f && frame >= max_frame) max_frame = -1.0f; } else if (!paused) { event_flags |= 0x01; frame += frame_rate->get_delta_frame(); if (max_frame >= 0.0f && frame > max_frame) frame = max_frame; } float_t frame = this->frame; for (auth_3d_point& i : point) i.interpolate(frame); for (auth_3d_curve& i : curve) i.interpolate(frame); for (auth_3d_chara& i : chara) i.interpolate(frame); for (auth_3d_material_list& i : material_list) i.interpolate(frame); for (auth_3d_object& i : object) i.interpolate(frame); for (auth_3d_object*& i : object_list) i->list_ctrl(&mat); for (auth_3d_object_hrc& i : object_hrc) i.interpolate(frame); for (auth_3d_object_hrc*& i : object_hrc_list) i->list_ctrl(&mat); for (auth_3d_m_object_hrc& i : m_object_hrc) i.interpolate(frame); for (auth_3d_m_object_hrc*& i : m_object_hrc_list) i->list_ctrl(&mat); for (auth_3d_ambient& i : ambient) { i.interpolate(frame); auth_3d_ambient_set(&i, rctx); } for (auth_3d_light& i : light) { i.interpolate(frame); auth_3d_light_set(&i, rctx); } for (auth_3d_fog& i : fog) { i.interpolate(frame); auth_3d_fog_set(&i, rctx); } post_process.interpolate(frame); auth_3d_post_process_set(&post_process, rctx); auth_3d_time_event* i_event = event_time_next; auth_3d_time_event* i_event_end = event_time.data() + event_time.size(); for (; i_event != i_event_end && frame >= i_event->frame; i_event++) { auth_3d_detail::Event* e = event[i_event->event_index]; if (!i_event->type) { printf_debug(" [%s]: [%s][%s]\n", auth_3d_event_type_string(e->type), e->ref.c_str(), e->param1.c_str()); e->Begin(this, event_flags, rctx); e->active = true; } else if (i_event->type) { printf_debug(" [%s]: [%s][%s]\n", auth_3d_event_type_string(e->type), e->ref.c_str(), e->param1.c_str()); if (e->active) { e->active = false; e->End(this, event_flags, rctx); } } } event_time_next = i_event; for (auth_3d_detail::Event*& i : event) if (i->active) i->Ctrl(this, event_flags, rctx); camera_auxiliary.interpolate(frame); auth_3d_camera_auxiliary_set(&camera_auxiliary, rctx); if (camera_root_update) for (auth_3d_camera_root& i : camera_root) { i.interpolate(auth_3d_camera_root_calc_frame(&i, frame, rctx)); cam_struct cam; cam.interest = i.interest_value; cam.view_point = i.view_point_value; cam.fov = i.fov_value; cam.roll = i.roll_value; if (left_right_reverse) { cam.interest.x = -cam.interest.x; cam.view_point.x = -cam.view_point.x; cam.roll = -cam.roll; } mat4_transform_point(&mat, &cam.interest, &cam.interest); mat4_transform_point(&mat, &cam.view_point, &cam.view_point); cam.set(rctx->camera); break; } dof.interpolate(frame); auth_3d_dof_set(&dof, rctx); if (set || !repeat || last_frame > frame) break; req_frame = frame - last_frame + frame_offset; frame_changed = true; set = true; } bool ended = play_control.size <= frame; if (ended && this->ended != ended) { paused = true; if (once) enable = false; } this->ended = ended; } void auth_3d::disp(render_context* rctx) { if (state != 2 || !enable) return; if (pos) spr::put_rgb_cross(mat); auth_3d_set_material_list(this, rctx); for (auth_3d_point& i : point) auth_3d_point_disp(&i, this, rctx); for (auth_3d_chara& i : chara) auth_3d_chara_disp(&i, this, rctx); for (auth_3d_object*& i : object_list) auth_3d_object_disp(i, this, rctx); for (auth_3d_object_hrc*& i : object_hrc_list) auth_3d_object_hrc_disp(i, this, rctx); for (auth_3d_m_object_hrc*& i : m_object_hrc_list) auth_3d_m_object_hrc_disp(i, this, rctx); for (auth_3d_detail::Event*& i : event) if (i->active) i->Disp(this, &mat, rctx); rctx->disp_manager->set_material_list(); } void auth_3d::load(a3da* auth_file, object_database* obj_db, texture_database* tex_db) { if (!auth_file) return; hash = hash_murmurhash_empty; auth_3d_play_control_load(this, &auth_file->play_control); frame_offset = 0.0f; max_frame = play_control.size; last_frame = play_control.size; this->obj_db = obj_db; this->tex_db = tex_db; auth_3d_camera_auxiliary_load(this, &auth_file->camera_auxiliary); auth_3d_dof_load(this, &dof, &auth_file->dof); auth_3d_post_process_load(this, &post_process, &auth_file->post_process); if (auth_file->ambient.size()) { size_t ambient_index = 0; ambient.resize(auth_file->ambient.size()); for (auth_3d_ambient_file& i : auth_file->ambient) auth_3d_ambient_load(this, &ambient[ambient_index++], &i); } if (auth_file->auth_2d.size()) { size_t auth_2d_index = 0; auth_2d.resize(auth_file->auth_2d.size()); for (std::string& i : auth_file->auth_2d) auth_2d[auth_2d_index++].assign(i); } if (auth_file->camera_root.size()) { size_t camera_root_index = 0; camera_root.resize(auth_file->camera_root.size()); for (auth_3d_camera_root_file& i : auth_file->camera_root) auth_3d_camera_root_load(this, &camera_root[camera_root_index++], &i); } if (auth_file->chara.size()) { size_t chara_index = 0; chara.resize(auth_file->chara.size()); for (auth_3d_chara_file& i : auth_file->chara) auth_3d_chara_load(this, &chara[chara_index++], &i); } if (auth_file->curve.size()) { size_t curve_index = 0; curve.resize(auth_file->curve.size()); for (auth_3d_curve_file& i : auth_file->curve) auth_3d_curve_load(this, &curve[curve_index++], &i); } if (auth_file->event.size()) { event.reserve(auth_file->event.size()); for (auth_3d_event_file& i : auth_file->event) { auth_3d_detail::Event* e = auth_3d_event_load(this, &i); if (e) event.push_back(e); } } if (auth_file->fog.size()) { size_t fog_index = 0; fog.resize(auth_file->fog.size()); for (auth_3d_fog_file& i : auth_file->fog) auth_3d_fog_load(this, &fog[fog_index++], &i); } if (auth_file->light.size()) { size_t light_index = 0; light.resize(auth_file->light.size()); for (auth_3d_light_file& i : auth_file->light) auth_3d_light_load(this, &light[light_index++], &i); } if (auth_file->m_object_hrc.size()) { size_t m_object_hrc_index = 0; m_object_hrc.resize(auth_file->m_object_hrc.size()); for (auth_3d_m_object_hrc_file& i : auth_file->m_object_hrc) auth_3d_m_object_hrc_load(this, &m_object_hrc[m_object_hrc_index++], &i, obj_db); } if (auth_file->material_list.size()) { size_t material_list_index = 0; material_list.resize(auth_file->material_list.size()); for (auth_3d_material_list_file& i : auth_file->material_list) auth_3d_material_list_load(this, &material_list[material_list_index++], &i); } if (auth_file->motion.size()) { size_t motion_index = 0; motion.resize(auth_file->motion.size()); for (std::string& i : auth_file->motion) motion[motion_index++].assign(i); } if (auth_file->object.size()) { size_t object_index = 0; object.resize(auth_file->object.size()); for (auth_3d_object_file& i : auth_file->object) auth_3d_object_load(this, &object[object_index++], &i, obj_db, tex_db); } if (auth_file->object_hrc.size()) { size_t object_hrc_index = 0; object_hrc.resize(auth_file->object_hrc.size()); for (auth_3d_object_hrc_file& i : auth_file->object_hrc) auth_3d_object_hrc_load(this, &object_hrc[object_hrc_index++], &i, obj_db); for (auth_3d_object_hrc& i : object_hrc) auth_3d_object_hrc_replace_chara(&i, (chara_index)src_chara, (chara_index)dst_chara, obj_db); } if (auth_file->point.size()) { size_t point_index = 0; point.resize(auth_file->point.size()); for (auth_3d_point_file& i : auth_file->point) auth_3d_point_load(this, &point[point_index++], &i); } if (auth_file->m_object_hrc_list.size()) { size_t m_object_hrc_list_index = 0; m_object_hrc_list.resize(auth_file->m_object_hrc_list.size()); for (std::string& i : auth_file->m_object_hrc_list) for (auth_3d_m_object_hrc& j : m_object_hrc) if (!i.compare(j.name)) { m_object_hrc_list[m_object_hrc_list_index++] = &j; break; } m_object_hrc_list.resize(m_object_hrc_list_index); } if (auth_file->object_list.size()) { size_t object_list_index = 0; object_list.resize(auth_file->object_list.size()); for (std::string& i : auth_file->object_list) for (auth_3d_object& j : object) if (!i.compare(j.name)) { object_list[object_list_index++] = &j; break; } object_list.resize(object_list_index); } if (auth_file->object_hrc_list.size()) { size_t object_hrc_list_index = 0; object_hrc_list.resize(auth_file->object_hrc_list.size()); for (std::string& i : auth_file->object_hrc_list) for (auth_3d_object_hrc& j : object_hrc) if (!i.compare(j.name)) { object_hrc_list[object_hrc_list_index++] = &j; break; } object_hrc_list.resize(object_hrc_list_index); } if (object.size()) { for (auth_3d_object& i : object) { if (!i.parent_name.size()) continue; if (i.parent_node.size()) for (auth_3d_object_hrc& j : object_hrc) { if (i.parent_name.compare(j.name)) continue; int32_t node_index = j.get_node_index(i.parent_node.c_str()); if (node_index > -1) { j.children_object_parent_node.push_back(node_index); j.children_object.push_back(&i); } break; } else for (auth_3d_object& j : object) { if (i.parent_name.compare(j.name)) continue; j.children_object.push_back(&i); break; } } } if (object_hrc.size()) { for (auth_3d_object_hrc& i : object_hrc) { if (!i.parent_name.size()) continue; if (i.parent_node.size()) for (auth_3d_object_hrc& j : object_hrc) { if (i.parent_name.compare(j.name)) continue; int32_t node_index = j.get_node_index(i.parent_node.c_str()); if (node_index > -1) { j.children_object_hrc_parent_node.push_back(node_index); j.children_object_hrc.push_back(&i); } break; } else for (auth_3d_object& j : object) { if (i.parent_name.compare(j.name)) continue; j.children_object_hrc.push_back(&i); break; } } } if (event.size()) { for (auth_3d_detail::Event*& i : event) if (i) i->Load(this); size_t event_index = 0; event_time.clear(); event_time.shrink_to_fit(); event_time.reserve(event.size() * 2); for (auth_3d_detail::Event*& i : event) { event_time.push_back({ i->begin, 0, event_index }); event_time.push_back({ i->end , 1, event_index }); event_index++; } radix_sort_custom(event_time.data(), event_time.size(), sizeof(auth_3d_time_event), sizeof(float_t), (radix_index_func)auth_3d_time_event_radix_index_func_frame); event_time_next = event_time.data(); } file_name.assign(auth_file->_file_name); } void auth_3d::load_from_farc(farc* f, const char* file, object_database* obj_db, texture_database* tex_db) { farc_file* ff = f->read_file(file); if (!ff) return; const char* l_str = ff->name.c_str(); const char* t = strrchr(l_str, '.'); size_t l_len = ff->name.size(); if (t) l_len = t - l_str; uint32_t h = hash_murmurhash(l_str, l_len); a3da a; a.read(ff->data, ff->size); load(&a, obj_db, tex_db); } void auth_3d::reset() { uid = -1; id = -1; mat = mat4_identity; enable = false; camera_root_update = true; visible = true; repeat = false; ended = false; left_right_reverse = false; once = false; mat = mat4_identity; alpha = 1.0f; obj_flags = mdl::OBJ_ALPHA_ORDER_1; chara_id = -1; chara_item = false; shadow = false; src_chara = CHARA_MAX; dst_chara = CHARA_MAX; pos = 0; frame_rate = get_sys_frame_rate(); frame = 0.0f; req_frame = 0.0f; max_frame = -1.0f; frame_changed = true; frame_offset = 0.0f; last_frame = 0.0f; paused = true; ambient.clear(); ambient.shrink_to_fit(); auth_2d.clear(); auth_2d.shrink_to_fit(); camera_auxiliary.reset(); camera_root.clear(); camera_root.shrink_to_fit(); chara.clear(); chara.shrink_to_fit(); curve.clear(); curve.shrink_to_fit(); dof.reset(); for (auth_3d_detail::Event*& i : event) if (i) { delete i; i = 0; } event.clear(); event.shrink_to_fit(); event_time.clear(); event_time.shrink_to_fit(); event_time_next = 0; fog.clear(); fog.shrink_to_fit(); light.clear(); light.shrink_to_fit(); m_object_hrc.clear(); m_object_hrc.shrink_to_fit(); m_object_hrc_list.clear(); m_object_hrc_list.shrink_to_fit(); material_list.clear(); material_list.shrink_to_fit(); motion.clear(); motion.shrink_to_fit(); object.clear(); object.shrink_to_fit(); object_hrc.clear(); object_hrc.shrink_to_fit(); object_hrc_list.clear(); object_hrc_list.shrink_to_fit(); object_list.clear(); object_list.shrink_to_fit(); play_control.reset(); point.clear(); point.shrink_to_fit(); post_process.reset(); hash = hash_murmurhash_empty; } void auth_3d::store(a3da* auth_file) { auth_3d_play_control_store(this, &auth_file->play_control); auth_3d_camera_auxiliary_store(this, &auth_file->camera_auxiliary); auth_3d_dof_store(this, &dof, &auth_file->dof); auth_3d_post_process_store(this, &post_process, &auth_file->post_process); if (ambient.size()) { size_t ambient_index = 0; auth_file->ambient.resize(auth_file->ambient.size()); for (auth_3d_ambient& i : ambient) auth_3d_ambient_store(this, &i, &auth_file->ambient[ambient_index++]); } if (auth_2d.size()) { size_t auth_2d_index = 0; auth_file->auth_2d.resize(auth_2d.size()); for (std::string& i : auth_2d) auth_file->auth_2d[auth_2d_index++].assign(i); } if (camera_root.size()) { size_t camera_root_index = 0; auth_file->camera_root.resize(camera_root.size()); for (auth_3d_camera_root& i : camera_root) auth_3d_camera_root_store(this, &i, &auth_file->camera_root[camera_root_index++]); } if (chara.size()) { size_t chara_index = 0; auth_file->chara.resize(chara.size()); for (auth_3d_chara& i : chara) auth_3d_chara_store(this, &i, &auth_file->chara[chara_index++]); } if (curve.size()) { size_t curve_index = 0; auth_file->curve.resize(curve.size()); for (auth_3d_curve& i : curve) auth_3d_curve_store(this, &i, &auth_file->curve[curve_index++]); } if (event.size()) { size_t event_index = 0; auth_file->event.resize(event.size()); for (auth_3d_detail::Event*& i : event) auth_3d_event_store(this, i, &auth_file->event[event_index]); } if (fog.size()) { size_t fog_index = 0; auth_file->fog.resize(fog.size()); for (auth_3d_fog& i : fog) auth_3d_fog_store(this, &i, &auth_file->fog[fog_index++]); } if (light.size()) { size_t light_index = 0; auth_file->light.resize(light.size()); for (auth_3d_light& i : light) auth_3d_light_store(this, &i, &auth_file->light[light_index++]); } if (m_object_hrc.size()) { size_t m_object_hrc_index = 0; auth_file->m_object_hrc.resize(m_object_hrc.size()); for (auth_3d_m_object_hrc& i : m_object_hrc) auth_3d_m_object_hrc_store(this, &i, &auth_file->m_object_hrc[m_object_hrc_index++]); } if (material_list.size()) { size_t material_list_index = 0; auth_file->material_list.resize(material_list.size()); for (auth_3d_material_list& i : material_list) auth_3d_material_list_store(this, &i, &auth_file->material_list[material_list_index++]); } if (motion.size()) { size_t motion_index = 0; auth_file->motion.resize(motion.size()); for (std::string& i : motion) auth_file->motion[motion_index++].assign(i); } if (object.size()) { size_t object_index = 0; auth_file->object.resize(object.size()); for (auth_3d_object& i : object) auth_3d_object_store(this, &i, &auth_file->object[object_index++]); } if (object_hrc.size()) { size_t object_hrc_index = 0; auth_file->object_hrc.resize(object_hrc.size()); for (auth_3d_object_hrc& i : object_hrc) auth_3d_object_hrc_store(this, &i, &auth_file->object_hrc[object_hrc_index++]); } if (point.size()) { size_t point_index = 0; auth_file->point.resize(point.size()); for (auth_3d_point& i : point) auth_3d_point_store(this, &i, &auth_file->point[point_index++]); } if (m_object_hrc_list.size()) { size_t m_object_hrc_list_index = 0; auth_file->m_object_hrc_list.resize(m_object_hrc_list.size()); for (auth_3d_m_object_hrc*& i : m_object_hrc_list) auth_file->m_object_hrc_list[m_object_hrc_list_index++].assign(i->name); } if (object_list.size()) { size_t object_list_index = 0; auth_file->object_list.resize(object_list.size()); for (auth_3d_object*& i : object_list) auth_file->object_list[object_list_index++].assign(i->name); } if (object_hrc_list.size()) { size_t object_hrc_list_index = 0; auth_file->object_hrc_list.resize(object_hrc_list.size()); for (auth_3d_object_hrc*& i : object_hrc_list) auth_file->object_hrc_list[object_hrc_list_index++].assign(i->name); } } void auth_3d::unload(render_context* rctx) { auth_3d_camera_auxiliary_restore_prev_value(&camera_auxiliary, rctx); for (auth_3d_light& i : light) auth_3d_light_restore_prev_value(&i, rctx); for (auth_3d_fog& i : fog) auth_3d_fog_restore_prev_value(&i, rctx); auth_3d_dof_restore_prev_value(&dof, rctx); auth_3d_post_process_restore_prev_value(&post_process, rctx); if (state) if (hash == hash_murmurhash_empty) { data_struct* aft_data = &data_list[DATA_AFT]; auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; if (aft_auth_3d_db->uid[uid].enabled) { auth_3d_uid_file* uid_file = &auth_3d_data->uid_files[uid]; if (uid_file->uid == uid) auth_3d_uid_file_unload(uid_file); } } else { auto elem = auth_3d_data->uid_files_modern.find(hash); if (elem == auth_3d_data->uid_files_modern.end()) return; auth_3d_uid_file_modern* uid_file = &elem->second; if (uid_file->hash == hash) auth_3d_uid_file_modern_unload(uid_file); } reset(); } namespace auth_3d_detail { Event::Event(a3da_event* e) { active = false; switch (e->type) { case A3DA_EVENT_MISC: default: type = Event::Type::MISC; case A3DA_EVENT_FILT: type = Event::Type::FILT; case A3DA_EVENT_FX: type = Event::Type::FX; case A3DA_EVENT_SND: type = Event::Type::SND; case A3DA_EVENT_MOT: type = Event::Type::MOT; case A3DA_EVENT_A2D: type = Event::Type::A2D; } name.assign(e->name); begin = e->begin; end = e->end; param1.assign(e->param1); ref.assign(e->ref); index = -1; } Event::~Event() { } void Event::Load(auth_3d* auth) { } void Event::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { } void Event::End(auth_3d* auth, int32_t flags, render_context* rctx) { } void Event::Ctrl(auth_3d* auth, int32_t flags, render_context* rctx) { } void Event::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { } EventA2d::EventA2d(a3da_event* e) : Event(e) { } EventA2d::~EventA2d() { } void EventA2d::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventA2d::End(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventA2d::Ctrl(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventA2d::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { } EventFX::EventFX(a3da_event* e) : Event(e) { } EventFX::~EventFX() { } void EventFX::Load(auth_3d* auth) { if (param1.compare("DOWN") && param1.compare("KABEHIT1") && param1.compare("PAPER1")) return; index = -1; for (auth_3d_point& i : auth->point) if (!i.name.compare(ref)) { index = &i - auth->point.data(); break; } } void EventFX::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { printf_debug(" [FX]: %s\n", param1.c_str()); } void EventFX::Ctrl(auth_3d* auth, int32_t flags, render_context* rctx) { if (index >= auth->point.size() || auth->frame < begin || auth->frame >= end || param1.compare("PAPER1")) return; auth_3d_point& point = auth->point[index]; vec3 pos = point.model_transform.translation_value; if (auth->left_right_reverse) pos.x = -pos.x; mat4_transform_point(&auth->mat, &pos, &pos); particle_event_data event; event.type = 1.0f; event.count = point.model_transform.scale_value.x * 100.0f; event.size = point.model_transform.scale_value.z; event.pos = pos; event.force = point.model_transform.scale_value.y; effect_manager_event(EFFECT_PARTICLE, 1, &event); } EventFXSmoothCut::EventFXSmoothCut(a3da_event* e) : Event(e), cam() { } EventFXSmoothCut::~EventFXSmoothCut() { } void EventFXSmoothCut::Load(auth_3d* auth) { if (!ref.compare("CAM")) { cam = true; return; } index = -1; for (auth_3d_point& i : auth->point) if (!i.name.compare(ref)) { index = &i - auth->point.data(); break; } } void EventFXSmoothCut::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { if (cam || !auth->chara.size() || index >= auth->chara.size()) return; int32_t chr_index = auth->chara[index].index; rob_chara* rob_chr = rob_chara_array_get(chr_index); if (rob_chr) rob_chr->field_C = true; } void EventFXSmoothCut::End(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventFXSmoothCut::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { } EventFilterFade::EventFilterFade(a3da_event* e) : Event(e) { type = Type::FADE_NONE; } EventFilterFade::~EventFilterFade() { } void EventFilterFade::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventFilterFade::End(auth_3d* auth, int32_t flags, render_context* rctx) { switch (type) { case EventFilterFade::Type::FADE_OUT: case EventFilterFade::Type::FADE_IN: break; default: return; } rctx->render.reset_scene_fade(0); } void EventFilterFade::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { switch (type) { case EventFilterFade::Type::FADE_OUT: case EventFilterFade::Type::FADE_IN: break; default: return; } float_t t = (auth->frame - begin) / (end - begin); vec4 value; *(vec3*)&value = color; if (type == EventFilterFade::Type::FADE_IN) value.w = t; else value.w = 1.0f - t; rctx->render.set_scene_fade(value, 0); } EventFilterTimeStop::EventFilterTimeStop(a3da_event* e) : Event(e) { } EventFilterTimeStop::~EventFilterTimeStop() { } void EventFilterTimeStop::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { for (auth_3d_chara& i : auth->chara) { rob_chara* rob_chr = rob_chara_array_get(i.index); if (rob_chr) rob_chr->item_equip->disable_update = true; } effect_manager_set_frame_rate_control(&frame_rate_time_stop); } void EventFilterTimeStop::End(auth_3d* auth, int32_t flags, render_context* rctx) { for (auth_3d_chara& i : auth->chara) { rob_chara* rob_chr = rob_chara_array_get(i.index); if (rob_chr) rob_chr->item_equip->disable_update = true; } effect_manager_set_frame_rate_control(get_sys_frame_rate()); } void EventFilterTimeStop::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { } EventMot::EventMot(a3da_event* e) : Event(e) { } EventMot::~EventMot() { } void EventMot::Load(auth_3d* auth) { index = -1; for (auth_3d_chara& i : auth->chara) if (!i.name.compare(ref)) { index = &i - auth->chara.data(); break; } } void EventMot::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventMot::End(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventMot::Ctrl(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventMot::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { } EventSnd::EventSnd(a3da_event* e) : Event(e) { field_190 = param1.find("zz", 0, 2) == 0; } EventSnd::~EventSnd() { } void EventSnd::Load(auth_3d* auth) { } static void sub_140532980(int32_t chara_id, const char* name) { } void EventSnd::Begin(auth_3d* auth, int32_t flags, render_context* rctx) { float_t frame = auth->frame; if (begin > frame || frame >= end || ((flags & 0x02) && fabsf(frame - begin) > 0.1f)) return; int32_t index = -1; if (auth->chara.size()) index = auth->chara.front().index; if (index >= 0 && index < ROB_CHARA_COUNT) sub_140532980(index, param1.c_str()); else if (sound_work_has_property(param1.c_str())) sound_work_play_se(1, param1.c_str(), 1.0f); } void EventSnd::End(auth_3d* auth, int32_t flags, render_context* rctx) { } void EventSnd::Disp(auth_3d* auth, const mat4* mat, render_context* rctx) { } } auth_3d_key::auth_3d_key() : type(), value(), max_frame(), ep_type_pre(), ep_type_post(), frame_delta(), value_delta(), length(), keys(), frame(), value_interp(), value_init() { reset(); } auth_3d_key::auth_3d_key(const auth_3d_key& k) : type(), value(), max_frame(), ep_type_pre(), ep_type_post(), frame_delta(), value_delta(), length(), keys(), frame(), value_interp(), value_init() { *this = k; } auth_3d_key::~auth_3d_key() { reset(); } float_t auth_3d_key::interpolate(float_t frame) { if (type == AUTH_3D_KEY_STATIC) return value; else if (type < AUTH_3D_KEY_STATIC || type > AUTH_3D_KEY_HOLD || !length) return 0.0f; kft3* first_key = &keys[0]; kft3* last_key = &keys[length - 1]; float_t first_frame = first_key->frame; float_t last_frame = last_key->frame; float_t offset = 0.0f; if (frame < first_frame) { float_t delta_frame = first_frame - frame; switch (ep_type_pre) { case A3DA_EP_NONE: default: this->frame = frame; value_interp = first_key->value; return value_interp; case A3DA_EP_LINEAR: this->frame = frame; value_interp = first_key->value + delta_frame * first_key->tangent1; return value_interp; case A3DA_EP_CYCLE: frame = last_frame - fmodf(delta_frame, frame_delta); break; case A3DA_EP_CYCLE_OFFSET: offset = (prj::truncf(delta_frame / frame_delta) + 1.0f) * value_delta; frame = last_frame - fmodf(delta_frame, frame_delta); break; } } else if (frame >= last_frame) { float_t delta_frame = frame - last_frame; switch (ep_type_post) { case A3DA_EP_NONE: default: this->frame = frame; value_interp = last_key->value; return value_interp; case A3DA_EP_LINEAR: this->frame = frame; value_interp = last_key->value - delta_frame * last_key->tangent2; return value_interp; case A3DA_EP_CYCLE: frame = first_frame + fmodf(delta_frame, frame_delta); break; case A3DA_EP_CYCLE_OFFSET: offset = (prj::truncf(delta_frame / frame_delta) + 1.0f) * value_delta; frame = first_frame + fmodf(delta_frame, frame_delta); break; } } this->frame = frame; value_interp = auth_3d_key_interpolate_inner(this, frame) + offset; return value_interp; } void auth_3d_key::reset() { type = AUTH_3D_KEY_NONE; value = 0.0f; max_frame = 0.0f; ep_type_pre = AUTH_3D_EP_NONE; ep_type_post = AUTH_3D_EP_NONE; frame_delta = 0.0f; value_delta = 0.0f; keys_vec.clear(); keys_vec.shrink_to_fit(); length = 0; keys = 0; frame = 0.0f; value_interp = 0.0f; value_init = 0.0f; } auth_3d_key& auth_3d_key::operator=(const auth_3d_key& k) { type = k.type; value = k.value; max_frame = k.max_frame; ep_type_pre = k.ep_type_pre; ep_type_post = k.ep_type_post; frame_delta = k.frame_delta; value_delta = k.value_delta; keys_vec.assign(k.keys_vec.begin(), k.keys_vec.end()); length = k.length; keys = keys_vec.data(); frame = k.frame; value_interp = k.value_interp; value_init = k.value_init; return *this; } auth_3d_rgba::auth_3d_rgba() : flags(), value() { reset(); } auth_3d_rgba::~auth_3d_rgba() { reset(); } void auth_3d_rgba::interpolate(float_t frame){ if (flags & AUTH_3D_RGBA_R) value.x = r.interpolate(frame); if (flags & AUTH_3D_RGBA_G) value.y = g.interpolate(frame); if (flags & AUTH_3D_RGBA_B) value.z = b.interpolate(frame); if (flags & AUTH_3D_RGBA_A) value.w = a.interpolate(frame); } void auth_3d_rgba::reset() { flags = (auth_3d_rgba_flags)0; r.reset(); g.reset(); b.reset(); a.reset(); value = 0.0f; } auth_3d_vec3::auth_3d_vec3() { reset(); } auth_3d_vec3::~auth_3d_vec3() { reset(); } vec3 auth_3d_vec3::interpolate(float_t frame) { vec3 value; value.x = x.interpolate(frame); value.y = y.interpolate(frame); value.z = z.interpolate(frame); return value; } void auth_3d_vec3::reset() { x.reset(); y.reset(); z.reset(); } auth_3d_model_transform::auth_3d_model_transform() : mat(), scale_value(), rotation_value(), translation_value(), visible() { reset(); } auth_3d_model_transform::~auth_3d_model_transform() { reset(); } void auth_3d_model_transform::interpolate(float_t frame) { scale_value = scale.interpolate(frame); rotation_value = rotation.interpolate(frame); translation_value = translation.interpolate(frame); visible = visibility.interpolate(frame) >= 0.999f; if (visible && (scale_value.x == 0.0f || scale_value.y == 0.0f || scale_value.z == 0.0f)) visible = false; } void auth_3d_model_transform::reset() { mat = mat4_identity; scale.reset(); rotation.reset(); translation.reset(); visibility.reset(); scale_value = 0.0f; rotation_value = 0.0f; translation_value = 0.0f; visible = false; } void auth_3d_model_transform::set_mat(const mat4* parent_mat) { mat4 mat; mat4_mul_translate(parent_mat, &translation_value, &mat); mat4_mul_rotate_zyx(&mat, &rotation_value, &mat); mat4_scale_rot(&mat, &scale_value, &this->mat); } auth_3d_ambient::auth_3d_ambient() : flags() { reset(); } auth_3d_ambient::~auth_3d_ambient() { reset(); } void auth_3d_ambient::interpolate(float_t frame) { if (flags & AUTH_3D_AMBIENT_LIGHT_DIFFUSE) light_diffuse.interpolate(frame); if (flags & AUTH_3D_AMBIENT_LIGHT_DIFFUSE) rim_light_diffuse.interpolate(frame); } void auth_3d_ambient::reset() { flags = (auth_3d_ambient_flags)0; light_diffuse.reset(); name.clear(); name.shrink_to_fit(); rim_light_diffuse.reset(); } auth_3d_camera_auxiliary::auth_3d_camera_auxiliary() : flags(), auto_exposure_value(), exposure_value(), exposure_rate_value(), gamma_value(), gamma_rate_value(), saturate_value() { reset(); } auth_3d_camera_auxiliary::~auth_3d_camera_auxiliary() { reset(); } void auth_3d_camera_auxiliary::interpolate(float_t frame) { if (flags & AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE) auto_exposure_value = auto_exposure.interpolate(frame); if (flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE) exposure_value = exposure.interpolate(frame); if (flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE_RATE) exposure_rate_value = exposure_rate.interpolate(frame); if (flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA) gamma_value = gamma.interpolate(frame); if (flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA_RATE) gamma_rate_value = gamma_rate.interpolate(frame); if (flags & AUTH_3D_CAMERA_AUXILIARY_SATURATE) saturate_value = saturate.interpolate(frame); } void auth_3d_camera_auxiliary::reset() { flags = (auth_3d_camera_auxiliary_flags)0; auto_exposure.reset(); exposure.reset(); exposure_rate.reset(); gamma.reset(); gamma_rate.reset(); saturate.reset(); auto_exposure_value = 1.0f; exposure_value = 2.0f; exposure_rate_value = 1.0f; gamma_value = 1.0f; gamma_rate_value = 1.0f; saturate_value = 1.0f; } auth_3d_camera_root::auth_3d_camera_root() : fov_value(), interest_value(), roll_value(), view_point_value() { reset(); } void auth_3d_camera_root::interpolate(float_t frame) { model_transform.interpolate(frame); model_transform.set_mat(&mat4_identity); mat4& cr_mat = model_transform.mat; vec3 _view_point = view_point.model_transform.translation.interpolate(frame); mat4_transform_point(&cr_mat, &_view_point, &view_point_value); vec3 _interest = interest.translation.interpolate(frame); mat4_transform_point(&cr_mat, &_interest, &interest_value); float_t fov; if (view_point.flags & AUTH_3D_CAMERA_ROOT_VIEW_POINT_FOV) { fov = view_point.fov.interpolate(frame); if (view_point.fov_is_horizontal) fov = atanf(tanf(fov * 0.5f) / view_point.aspect) * 2.0f; } else { float_t camera_aperture_h = view_point.camera_aperture_h; float_t focal_lenth = view_point.focal_length.interpolate(frame); fov = atanf((camera_aperture_h * 25.4f) * 0.5f / focal_lenth) * 2.0f; } fov_value = fov; if (view_point.flags & AUTH_3D_CAMERA_ROOT_VIEW_POINT_ROLL) roll_value = view_point.roll.interpolate(frame); } void auth_3d_camera_root::reset() { interest.reset(); model_transform.reset(); view_point.reset(); fov_value = 0.0f; interest_value = 0.0f; roll_value = 0.0f; view_point_value = 0.0f; } auth_3d_camera_root::~auth_3d_camera_root() { reset(); } auth_3d_camera_root_view_point::auth_3d_camera_root_view_point() : flags(), aspect(), camera_aperture_h(), camera_aperture_w(), fov_is_horizontal() { reset(); } auth_3d_camera_root_view_point::~auth_3d_camera_root_view_point() { reset(); } void auth_3d_camera_root_view_point::reset() { flags = (auth_3d_camera_root_view_point_flags)0; aspect = 0.0f; camera_aperture_h = 0.0f; camera_aperture_w = 0.0f; focal_length.reset(); fov.reset(); fov_is_horizontal = false; model_transform.reset(); roll.reset(); } auth_3d_chara::auth_3d_chara() : index() { reset(); } auth_3d_chara::~auth_3d_chara() { reset(); } void auth_3d_chara::interpolate(float_t frame) { model_transform.interpolate(frame); } void auth_3d_chara::reset() { model_transform.reset(); name.clear(); name.shrink_to_fit(); index = -1; } auth_3d_curve::auth_3d_curve() : value() { reset(); } auth_3d_curve::~auth_3d_curve() { reset(); } void auth_3d_curve::interpolate(float_t frame) { value = curve.interpolate(frame); } void auth_3d_curve::reset() { curve.reset(); name.clear(); name.shrink_to_fit(); value = 0.0f; } auth_3d_dof::auth_3d_dof() : has_dof() { reset(); } auth_3d_dof::~auth_3d_dof() { reset(); } void auth_3d_dof::interpolate(float_t frame) { if (!has_dof) return; model_transform.interpolate(frame); } void auth_3d_dof::reset() { has_dof = false; model_transform.reset(); } auth_3d_fog::auth_3d_fog() : flags(), flags_init(), id(), density_value(), end_value(), start_value(), density_init(), end_init(), start_init() { reset(); } auth_3d_fog::~auth_3d_fog() { reset(); } void auth_3d_fog::interpolate(float_t frame) { if (flags & AUTH_3D_FOG_DENSITY) density_value = density.interpolate(frame); if (flags & AUTH_3D_FOG_START) start_value = start.interpolate(frame); if (flags & AUTH_3D_FOG_END) end_value = end.interpolate(frame); if (flags & AUTH_3D_FOG_COLOR) color.interpolate(frame); } void auth_3d_fog::reset() { flags = (auth_3d_fog_flags)0; flags_init = (auth_3d_fog_flags)0; color.reset(); density.reset(); end.reset(); id = (fog_id)0; start.reset(); density_value = 0.0f; end_value = 0.0f; start_value = 0.0f; color_init = 0.0f; density_init = 0.0f; end_init = 0.0f; start_init = 0.0f; } auth_3d_light::auth_3d_light() : flags(), flags_init(), id(), cone_angle_value(), constant_value(), drop_off_value(), far_value(), intensity_value(), linear_value(), quadratic_value(), cone_angle_init(), constant_init(), drop_off_init(), far_init(), intensity_init(), linear_init(), quadratic_init(), tone_curve_init() { reset(); } auth_3d_light::~auth_3d_light() { reset(); } void auth_3d_light::interpolate(float_t frame) { if (flags & AUTH_3D_LIGHT_AMBIENT) ambient.interpolate(frame); if (flags & AUTH_3D_LIGHT_CONE_ANGLE) cone_angle_value = cone_angle.interpolate(frame); if (flags & AUTH_3D_LIGHT_CONSTANT) constant_value = constant.interpolate(frame); if (flags & AUTH_3D_LIGHT_DIFFUSE) diffuse.interpolate(frame); if (flags & AUTH_3D_LIGHT_DROP_OFF) drop_off_value = drop_off.interpolate(frame); if (flags & AUTH_3D_LIGHT_FAR) far_value = _far.interpolate(frame); if (flags & AUTH_3D_LIGHT_INTENSITY) intensity_value = intensity.interpolate(frame); if (flags & AUTH_3D_LIGHT_LINEAR) linear_value = linear.interpolate(frame); if (flags & AUTH_3D_LIGHT_POSITION) position.interpolate(frame); if (flags & AUTH_3D_LIGHT_QUADRATIC) quadratic_value = quadratic.interpolate(frame); if (flags & AUTH_3D_LIGHT_SPECULAR) specular.interpolate(frame); if (flags & AUTH_3D_LIGHT_SPOT_DIRECTION) spot_direction.interpolate(frame); if (flags & AUTH_3D_LIGHT_TONE_CURVE) tone_curve.interpolate(frame); } void auth_3d_light::reset() { flags = (auth_3d_light_flags)0; flags_init = (auth_3d_light_flags)0; ambient.reset(); cone_angle.reset(); constant.reset(); diffuse.reset(); drop_off.reset(); _far.reset(); id = (light_id)0; intensity.reset(); linear.reset(); position.reset(); quadratic.reset(); specular.reset(); spot_direction.reset(); tone_curve.reset(); type.clear(); type.shrink_to_fit(); cone_angle_value = 0.0f; constant_value = 0.0f; drop_off_value = 0.0f; far_value = 0.0f; intensity_value = 0.0f; linear_value = 0.0f; quadratic_value = 0.0f; ambient_init = 0.0f; cone_angle_init = 0.0f; constant_init = 0.0f; diffuse_init = 0.0f; drop_off_init = 0.0f; far_init = 0.0f; intensity_init = 0.0f; linear_init = 0.0f; quadratic_init = 0.0f; specular_init = 0.0f; tone_curve_init = {}; } auth_3d_m_object_hrc::auth_3d_m_object_hrc() { reset(); } auth_3d_m_object_hrc::~auth_3d_m_object_hrc() { reset(); } void auth_3d_m_object_hrc::interpolate(float_t frame) { model_transform.interpolate(frame); for (auth_3d_object_instance& i : instance) i.interpolate(frame); for (auth_3d_object_node& i : node) i.interpolate(frame); } void auth_3d_m_object_hrc::list_ctrl(const mat4* parent_mat) { //if (!model_transform.visible) // return; auth_3d_object_node* node = this->node.data(); auth_3d_m_object_hrc_nodes_mat_mult(this); this->model_transform.mat_mult(parent_mat); mat4& mat = this->model_transform.mat; for (auth_3d_object_instance& i : this->instance) { //if (!i.model_transform.visible) // continue; i.model_transform.mat_mult(&mat); int32_t* object_bone_indices = i.object_bone_indices.data(); size_t object_bone_indices_count = i.object_bone_indices.size(); mat4* mats = i.mats.data(); for (size_t j = 0; j < object_bone_indices_count; j++) mats[j] = node[object_bone_indices[j]].model_transform.mat; } } void auth_3d_m_object_hrc::reset() { for (auth_3d_object_instance& i : instance) i.reset(); instance.clear(); instance.shrink_to_fit(); model_transform.reset(); name.clear(); name.shrink_to_fit(); for (auth_3d_object_node& i : node) i.reset(); node.clear(); node.shrink_to_fit(); } auth_3d_material_list::auth_3d_material_list() : flags(), glow_intensity_value() { reset(); } auth_3d_material_list::~auth_3d_material_list() { reset(); } void auth_3d_material_list::interpolate(float_t frame) { if (flags & AUTH_3D_MATERIAL_LIST_BLEND_COLOR) blend_color.interpolate(frame); if (flags & AUTH_3D_MATERIAL_LIST_GLOW_INTENSITY) glow_intensity_value = glow_intensity.interpolate(frame); if (flags & AUTH_3D_MATERIAL_LIST_EMISSION) emission.interpolate(frame); } void auth_3d_material_list::reset() { flags = (auth_3d_material_list_flags)0; blend_color.reset(); glow_intensity.reset(); emission.reset(); name.clear(); name.shrink_to_fit(); glow_intensity_value = 0.0f; } auth_3d_object::auth_3d_object() : object_info(), object_hash(), reflect(), refract() { reset(); } auth_3d_object::~auth_3d_object() { reset(); } void auth_3d_object::interpolate(float_t frame) { model_transform.interpolate(frame); pattern.interpolate(frame); morph.interpolate(frame); for (auth_3d_object_texture_pattern& i : texture_pattern) i.interpolate(frame); for (auth_3d_object_texture_transform& i : texture_transform) i.interpolate(frame); } void auth_3d_object::list_ctrl(const mat4* parent_mat) { //if (!model_transform.visible) // return; model_transform.set_mat(parent_mat); mat4& mat = model_transform.mat; for (auth_3d_object*& i : children_object) i->list_ctrl(&mat); for (auth_3d_object_hrc*& i : children_object_hrc) i->list_ctrl(&mat); } void auth_3d_object::reset() { children_object.clear(); children_object.shrink_to_fit(); children_object_hrc.clear(); children_object_hrc.shrink_to_fit(); model_transform.reset(); morph.reset(); object_info = {}; object_hash = (uint32_t)-1; name.clear(); name.shrink_to_fit(); parent_name.clear(); parent_name.shrink_to_fit(); parent_node.clear(); parent_node.shrink_to_fit(); pattern.reset(); reflect = false; refract = false; for (auth_3d_object_texture_pattern& i : texture_pattern) i.reset(); texture_pattern.clear(); texture_pattern.shrink_to_fit(); for (auth_3d_object_texture_transform& i : texture_transform) i.reset(); texture_transform.clear(); texture_transform.shrink_to_fit(); uid_name.clear(); uid_name.shrink_to_fit(); } auth_3d_object_curve::auth_3d_object_curve() : curve(), frame_offset(), value() { reset(); } auth_3d_object_curve::~auth_3d_object_curve() { reset(); } void auth_3d_object_curve::interpolate(float_t frame) { auth_3d_curve* c = curve; if (!c) return; if (frame_offset != 0.0f) { frame += frame_offset; if (frame >= c->curve.max_frame) frame -= c->curve.max_frame; } value = c->curve.interpolate(frame); } void auth_3d_object_curve::reset() { curve = 0; name.clear(); name.shrink_to_fit(); frame_offset = 0.0f; value = 0.0f; } auth_3d_object_hrc::auth_3d_object_hrc() : object_info(), object_hash(), reflect(), refract(), shadow() { reset(); } auth_3d_object_hrc::~auth_3d_object_hrc() { reset(); } int32_t auth_3d_object_hrc::get_node_index(const char* node) { for (auth_3d_object_node& i : this->node) if (!i.name.compare(node)) return (int32_t)(&i - this->node.data()); return -1; } void auth_3d_object_hrc::interpolate(float_t frame) { for (auth_3d_object_node& i : node) i.interpolate(frame); } void auth_3d_object_hrc::list_ctrl(const mat4* mat) { //if (node.size() < 1 || !node.front().model_transform.visible) // return; auth_3d_object_hrc_nodes_mat_mult(this, mat); auth_3d_object_node* node = this->node.data(); int32_t* children_object_parent_node = this->children_object_parent_node.data(); auth_3d_object** children_object = this->children_object.data(); size_t children_object_count = this->children_object.size(); for (size_t i = 0; i < children_object_count; i++) children_object[i]->list_ctrl( &node[children_object_parent_node[i]].model_transform.mat); int32_t* children_object_hrc_parent_node = this->children_object_hrc_parent_node.data(); auth_3d_object_hrc** children_object_hrc = this->children_object_hrc.data(); size_t children_object_hrc_count = this->children_object_hrc.size(); for (size_t i = 0; i < children_object_hrc_count; i++) children_object_hrc[i]->list_ctrl( &node[children_object_hrc_parent_node[i]].model_transform.mat); } void auth_3d_object_hrc::reset() { children_object.clear(); children_object.shrink_to_fit(); children_object_hrc.clear(); children_object_hrc.shrink_to_fit(); children_object_parent_node.clear(); children_object_parent_node .shrink_to_fit(); children_object_hrc_parent_node.clear(); children_object_hrc_parent_node.shrink_to_fit(); mats.clear(); mats.shrink_to_fit(); name.clear(); name.shrink_to_fit(); for (auth_3d_object_node& i : node) i.reset(); node.clear(); node.shrink_to_fit(); object_info = {}; object_hash = (uint32_t)-1; parent_name.clear(); parent_name.shrink_to_fit(); parent_node.clear(); parent_node.shrink_to_fit(); reflect = false; refract = false; shadow = false; uid_name.clear(); uid_name.shrink_to_fit(); } auth_3d_object_instance::auth_3d_object_instance() : object_info(), object_hash(), shadow() { reset(); } auth_3d_object_instance::~auth_3d_object_instance() { reset(); } void auth_3d_object_instance::interpolate(float_t frame) { model_transform.interpolate(frame); } void auth_3d_object_instance::reset() { mats.clear(); mats.shrink_to_fit(); model_transform.reset(); name.clear(); name.shrink_to_fit(); object_bone_indices.clear(); object_bone_indices.shrink_to_fit(); object_info = {}; object_hash = (uint32_t)-1; shadow = false; uid_name.clear(); uid_name.shrink_to_fit(); } auth_3d_object_model_transform::auth_3d_object_model_transform() : mat(), mat_inner(), mat_rot(), translation_value(), rotation_value(), scale_value(), visible(), frame(), has_rotation(), has_translation(), has_scale(), has_visibility() { reset(); } auth_3d_object_model_transform::~auth_3d_object_model_transform() { reset(); } void auth_3d_object_model_transform::interpolate(float_t frame) { if (frame != this->frame || has_rotation) { translation_value = translation.interpolate(frame); rotation_value = rotation.interpolate(frame); if (has_scale) scale_value = scale.interpolate(frame); if (has_visibility) visible = visibility.interpolate(frame) >= 0.999f; mat4_rotate_zyx(&rotation_value, &mat_rot); this->frame = frame; has_rotation = false; has_translation = false; } if (has_translation && !has_rotation) return; mat4 mat; mat4_translate(&translation_value, &mat); mat4_mul(&mat_rot, &mat, &mat); if (has_scale) mat4_scale_rot(&mat, &scale_value, &mat); mat_inner = mat; has_translation = true; } void auth_3d_object_model_transform::mat_mult(const mat4* mat) { mat4_mul(&this->mat_inner, mat, &this->mat); } void auth_3d_object_model_transform::reset() { mat = mat4_identity; mat_inner = mat4_identity; mat_rot = mat4_identity; translation.reset(); rotation.reset(); scale.reset(); visibility.reset(); translation_value = 0.0f; rotation_value = 0.0f; scale_value = 1.0f; visible = true; frame = -1.0f; has_rotation = false; has_translation = false; has_scale = false; has_visibility = false; } auth_3d_object_node::auth_3d_object_node() : flags(), bone_id(), joint_orient(), joint_orient_mat(), mat(), parent() { reset(); } auth_3d_object_node::~auth_3d_object_node() { reset(); } void auth_3d_object_node::interpolate(float_t frame) { model_transform.interpolate(frame); } void auth_3d_object_node::reset() { flags = (auth_3d_object_node_flags)0; bone_id = -1; joint_orient = 0.0f; joint_orient_mat = mat4_identity; mat = 0; model_transform.reset(); name.clear(); name.shrink_to_fit(); parent = -1; } auth_3d_object_texture_pattern::auth_3d_object_texture_pattern() : texture_id() { reset(); } auth_3d_object_texture_pattern::~auth_3d_object_texture_pattern() { reset(); } void auth_3d_object_texture_pattern::interpolate(float_t frame) { pattern.interpolate(frame); } void auth_3d_object_texture_pattern::reset() { name.clear(); name.shrink_to_fit(); pattern.reset(); texture_id = -1; } auth_3d_object_texture_transform::auth_3d_object_texture_transform() : flags(), mat(), texture_id() { reset(); } auth_3d_object_texture_transform::~auth_3d_object_texture_transform() { reset(); } void auth_3d_object_texture_transform::interpolate(float_t frame) { int32_t flags = this->flags; vec3 scale = 1.0f; vec3 repeat = 1.0f; vec3 rotate = 0.0f; vec3 translate_frame = 0.0f; if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_COVERAGE_U && this->coverage_u.max_frame > 0.0f) { float_t coverage_u = this->coverage_u.interpolate(frame); if (fabsf(coverage_u) > 0.000001f) scale.x = 1.0f / coverage_u; } if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_COVERAGE_V && this->coverage_v.max_frame > 0.0f) { float_t coverage_v = this->coverage_v.interpolate(frame); if (fabsf(coverage_v) > 0.000001f) scale.y = 1.0f / coverage_v; } if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_REPEAT_U && this->repeat_u.max_frame > 0.0f) { float_t value = this->repeat_u.interpolate(frame); if (fabsf(value) > 0.000001f) repeat.x = value; } if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_REPEAT_V && this->repeat_v.max_frame > 0.0f) { float_t value = this->repeat_v.interpolate(frame); if (fabsf(value) > 0.000001f) repeat.y = value; } if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_ROTATE_FRAME) rotate.z = this->rotate_frame.interpolate(frame); if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_ROTATE) rotate.z += this->rotate.interpolate(frame); float_t translate_frame_u; if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_U) translate_frame_u = -this->translate_frame_u.interpolate(frame); else translate_frame_u = 0.0f; float_t offset_u; if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_OFFSET_U) offset_u = this->offset_u.interpolate(frame); else offset_u = 0.0f; translate_frame.x = (translate_frame_u + offset_u) * repeat.x; float_t translate_frame_v; if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_V) translate_frame_v = -this->translate_frame_v.interpolate(frame); else translate_frame_v = 0.0f; float_t offset_v; if (flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_OFFSET_V) offset_v = this->offset_v.interpolate(frame); else offset_v = 0.0f; translate_frame.y = (translate_frame_v + offset_v) * repeat.y; mat4 mat; mat4_translate(&translate_frame, &mat); mat4_scale_rot(&mat, &scale, &mat); mat4_mul_translate(&mat, 1.0f, 1.0f, 0.0f, &mat); mat4_scale_rot(&mat, &repeat, &mat); mat4_mul_translate(&mat, -1.0f, -1.0f, 0.0f, &mat); mat4_mul_translate(&mat, 0.5f, 0.5f, 0.0f, &mat); mat4_mul_rotate_z(&mat, rotate.z, &mat); mat4_mul_translate(&mat, -0.5f, -0.5f, 0.0f, &mat); this->mat = mat; } void auth_3d_object_texture_transform::reset() { flags = (auth_3d_object_texture_transform_flags)0; coverage_u.reset(); coverage_v.reset(); mat = mat4_identity; name.clear(); name.shrink_to_fit(); offset_u.reset(); offset_v.reset(); repeat_u.reset(); repeat_v.reset(); rotate.reset(); rotate_frame.reset(); texture_id = -1; translate_frame_u.reset(); translate_frame_v.reset(); } auth_3d_play_control::auth_3d_play_control() : flags(), begin(), div(), fps(), offset(), size() { reset(); } auth_3d_play_control::~auth_3d_play_control() { reset(); } void auth_3d_play_control::reset() { flags = (auth_3d_play_control_flags)0; begin = 0.0f; div = 0; fps = 0.0f; offset = 0.0f; size = 0.0f; } auth_3d_point::auth_3d_point() { reset(); } auth_3d_point::~auth_3d_point() { reset(); } void auth_3d_point::interpolate(float_t frame) { model_transform.interpolate(frame); } void auth_3d_point::reset() { model_transform.reset(); name.clear(); name.shrink_to_fit(); } auth_3d_post_process::auth_3d_post_process() : flags(), flags_init() { reset(); } auth_3d_post_process::~auth_3d_post_process() { reset(); } void auth_3d_post_process::interpolate(float_t frame) { if (flags & AUTH_3D_POST_PROCESS_INTENSITY) intensity.interpolate(frame); if (flags & AUTH_3D_POST_PROCESS_LENS_FLARE) lens_value.x = lens_flare.interpolate(frame); if (flags & AUTH_3D_POST_PROCESS_LENS_SHAFT) lens_value.y = lens_shaft.interpolate(frame); if (flags & AUTH_3D_POST_PROCESS_LENS_GHOST) lens_value.z = lens_ghost.interpolate(frame); if (flags & AUTH_3D_POST_PROCESS_RADIUS) radius.interpolate(frame); if (flags & AUTH_3D_POST_PROCESS_SCENE_FADE) scene_fade.interpolate(frame); } void auth_3d_post_process::reset() { flags = (auth_3d_post_process_flags)0; flags_init = (auth_3d_post_process_flags)0; intensity.reset(); lens_flare.reset(); lens_ghost.reset(); lens_shaft.reset(); radius.reset(); scene_fade.reset(); lens_value = 1.0f; intensity_init = 0.0f; lens_init = 1.0f; radius_init = 0.0f; scene_fade_init = 0.0f; } auth_3d_farc::auth_3d_farc() : load_count(), name(), state(), farc(), data(), size() { } auth_3d_farc::~auth_3d_farc() { delete farc; } auth_3d_uid_file::auth_3d_uid_file() : load_count(), uid(), state(), name(), farc() { } auth_3d_uid_file::~auth_3d_uid_file() { } auth_3d_uid_file_modern::auth_3d_uid_file_modern() : load_count(), state(), name(), farc(),data(), obj_db(), tex_db() { hash = hash_murmurhash_empty; } auth_3d_uid_file_modern::~auth_3d_uid_file_modern() { } auth_3d_id::auth_3d_id(uint32_t hash, void* data, object_database* obj_db, texture_database* tex_db) { id = -1; int32_t index = 0; while (auth_3d_data->data[index].uid != -1 || auth_3d_data->data[index].hash != hash_murmurhash_empty && auth_3d_data->data[index].hash != -1) if (++index >= AUTH_3D_DATA_COUNT) return; auto elem = auth_3d_data->uid_files_modern.find(hash); if (elem == auth_3d_data->uid_files_modern.end()) elem = auth_3d_data->uid_files_modern.insert({ hash, {} }).first; auth_3d_uid_file_modern* uid_file = &elem->second; uid_file->load_count = 0; uid_file->hash = hash; uid_file->file_name.clear(); uid_file->file_name.shrink_to_fit(); uid_file->state = 0; uid_file->name.clear(); uid_file->name.shrink_to_fit(); uid_file->farc = 0; uid_file->data = data; uid_file->obj_db = obj_db; uid_file->tex_db = tex_db; auth_3d_data->data[index].reset(); if (++auth_3d_load_counter < 0) auth_3d_load_counter = 1; int32_t id = ((auth_3d_load_counter & 0x7FFF) << 16) | index & 0x7FFF; auth_3d_data->data[index].hash = hash; auth_3d_data->data[index].id = id; auth_3d_data->loaded_ids.push_back(id); this->id = id; } auth_3d_id::auth_3d_id(int32_t uid, auth_3d_database* auth_3d_db) { id = -1; if (uid >= auth_3d_db->uid.size() || !auth_3d_db->uid[uid].enabled) return; int32_t index = 0; while (auth_3d_data->data[index].uid != -1 || auth_3d_data->data[index].hash != hash_murmurhash_empty && auth_3d_data->data[index].hash != -1) if (++index >= AUTH_3D_DATA_COUNT) return; auth_3d_data->data[index].reset(); if (++auth_3d_load_counter < 0) auth_3d_load_counter = 1; int32_t id = ((auth_3d_load_counter & 0x7FFF) << 16) | index & 0x7FFF; auth_3d_data->data[index].uid = uid; auth_3d_data->data[index].id = id; auth_3d_data->loaded_ids.push_back(id); this->id = id; } bool auth_3d_id::check_not_empty() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->id != -1; } return false; } bool auth_3d_id::check_loading() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->state == 1; } return false; } bool auth_3d_id::check_loaded() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->state == 2; } return true; } auth_3d* auth_3d_id::get_auth_3d() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth; } return 0; } int32_t auth_3d_id::get_chara_id() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->chara_id; } return -1; } const mat4* auth_3d_id::get_auth_3d_object_mat(size_t index, bool hrc) { if (id < 0 || (id & 0x7FFF) >= AUTH_3D_DATA_COUNT) return 0; auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id != id || !auth->enable) return 0; if (hrc) return auth_3d_get_auth_3d_object_hrc_bone_mats(auth, index); return auth_3d_get_auth_3d_object_mat(auth, index); } bool auth_3d_id::get_enable() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->enable; } return false; } bool auth_3d_id::get_ended() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->ended; } return true; } float_t auth_3d_id::get_frame() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->frame; } return 0.0f; } float_t auth_3d_id::get_frame_offset() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->frame_offset; } return 0.0f; } float_t auth_3d_id::get_last_frame() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->last_frame; } return 0.0f; } bool auth_3d_id::get_left_right_reverse() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->left_right_reverse; } return false; } float_t auth_3d_id::get_play_control_begin() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->play_control.begin; } return 0.0f; } float_t auth_3d_id::get_play_control_size() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->play_control.size; } return 0.0f; } bool auth_3d_id::get_paused() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->paused; } return false; } bool auth_3d_id::get_repeat() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->repeat; } return false; } int32_t auth_3d_id::get_uid() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) return auth->uid; } return -1; } void auth_3d_id::read_file(auth_3d_database* auth_3d_db) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth && auth->id == id) auth_3d_read_file(auth, auth_3d_db); } } void auth_3d_id::read_file_modern() { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth && auth->id == id) auth_3d_read_file_modern(auth); } } void auth_3d_id::set_alpha_obj_flags(float_t alpha, mdl::ObjFlags obj_flags) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) { auth->alpha = alpha; auth->obj_flags = obj_flags; } } } void auth_3d_id::set_camera_root_update(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->camera_root_update = value; } } void auth_3d_id::set_chara_id(int32_t value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->chara_id = value; } } void auth_3d_id::set_chara_item(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->chara_item = value; } } void auth_3d_id::set_enable(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->enable = value; } } void auth_3d_id::set_frame_rate(FrameRateControl* value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) if (value) auth->frame_rate = value; else auth->frame_rate = get_sys_frame_rate(); } } void auth_3d_id::set_last_frame(float_t value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->last_frame = value; } } void auth_3d_id::set_left_right_reverse(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->left_right_reverse = value; } } void auth_3d_id::set_mat(const mat4& value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->mat = value; } } void auth_3d_id::set_max_frame(float_t value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->max_frame = value; } } void auth_3d_id::set_paused(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->paused = value; } } void auth_3d_id::set_pos(int32_t value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->pos = value; } } void auth_3d_id::set_repeat(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->repeat = value; } } void auth_3d_id::set_req_frame(float_t value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) { auth->req_frame = value; auth->frame_changed = true; } } } void auth_3d_id::set_shadow(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->shadow = value; } } void auth_3d_id::set_src_dst_chara(int32_t src_chara, int32_t dst_chara) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) { auth->src_chara = src_chara; auth->dst_chara = dst_chara; } } } void auth_3d_id::set_visibility(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (auth->id == id) auth->visible = value; } } void auth_3d_id::unload(render_context* rctx) { if (id < 0 || (id & 0x7FFF) >= AUTH_3D_DATA_COUNT) return; auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; if (!auth || auth->id != id) return; for (auto i = auth_3d_data->loaded_ids.begin(); i != auth_3d_data->loaded_ids.end();) { if (*i != id) { i++; continue; } i = auth_3d_data->loaded_ids.erase(i); auth->unload(rctx); break; } } auth_3d_data_struct::auth_3d_data_struct() { } auth_3d_data_struct::~auth_3d_data_struct() { } void auth_3d_data_init() { if (!auth_3d_data) auth_3d_data = new auth_3d_data_struct; } bool auth_3d_data_check_category_loaded(const char* category_name) { return auth_3d_data_struct_check_category_loaded(auth_3d_data, category_name); } bool auth_3d_data_check_category_loaded(uint32_t category_hash) { return auth_3d_data_struct_check_category_loaded(auth_3d_data, category_hash); } auth_3d* auth_3d_data_get_auth_3d(uint32_t hash) { for (int32_t& i : auth_3d_data->loaded_ids) { if (i < 0 || (i & 0x7FFF) >= AUTH_3D_DATA_COUNT) continue; auth_3d* auth = &auth_3d_data->data[i & 0x7FFF]; if (auth->hash == hash) return auth; } return 0; } auth_3d* auth_3d_data_get_auth_3d(int32_t uid) { for (int32_t& i : auth_3d_data->loaded_ids) { if (i < 0 || (i & 0x7FFF) >= AUTH_3D_DATA_COUNT) continue; auth_3d* auth = &auth_3d_data->data[i & 0x7FFF]; if (auth->uid == uid) return auth; } return 0; } int32_t auth_3d_data_get_auth_3d_id(const char* object_name) { for (int32_t& i : auth_3d_data->loaded_ids) { if (i < 0 || (i & 0x7FFF) >= AUTH_3D_DATA_COUNT) continue; auth_3d* auth = &auth_3d_data->data[i & 0x7FFF]; if (auth->id != i || !auth->enable) continue; for (auth_3d_object_hrc& j : auth->object_hrc) if (!j.name.compare(object_name)) return i; for (auth_3d_object& j : auth->object) if (!j.name.compare(object_name)) return i; } return -1; } int32_t auth_3d_data_get_auth_3d_id(object_info obj_info, int32_t* object_index, bool* hrc, int32_t object_instance) { for (int32_t& i : auth_3d_data->loaded_ids) { if (i < 0 || (i & 0x7FFF) >= AUTH_3D_DATA_COUNT) continue; auth_3d* auth = &auth_3d_data->data[i & 0x7FFF]; if (auth->id != i || !auth->enable) continue; int32_t obj_hrc_index = auth_3d_get_auth_3d_object_hrc_index_by_object_info( auth, obj_info, object_instance); if (obj_hrc_index >= 0) { if (object_index) *object_index = obj_hrc_index; if (hrc) *hrc = true; return i; } int32_t obj_index = auth_3d_get_auth_3d_object_index_by_object_info( auth, obj_info, object_instance); if (obj_index >= 0) { if (object_index) *object_index = obj_index; if (hrc) *hrc = false; return i; } } return -1; } int32_t auth_3d_data_get_auth_3d_id(uint32_t file_name_hash, uint32_t object_hash, int32_t* object_index, bool* hrc, int32_t object_instance) { for (int32_t& i : auth_3d_data->loaded_ids) { if (i < 0 || (i & 0x7FFF) >= AUTH_3D_DATA_COUNT) continue; auth_3d* auth = &auth_3d_data->data[i & 0x7FFF]; if (auth->id != i || !auth->enable) continue; bool ret = false; if (file_name_hash != hash_murmurhash_empty) { if (auth->hash != file_name_hash) continue; ret = true; } int32_t obj_index = auth_3d_get_auth_3d_object_index_by_hash( auth, object_hash, object_instance); if (obj_index >= 0) { if (object_index) *object_index = obj_index; if (hrc) *hrc = false; return i; } int32_t obj_hrc_index = auth_3d_get_auth_3d_object_hrc_index_by_hash( auth, object_hash, object_instance); if (obj_hrc_index >= 0) { if (object_index) *object_index = obj_hrc_index; if (hrc) *hrc = true; return i; } if (ret) return -1; } return -1; } void auth_3d_data_get_obj_sets_from_category(std::string& name, std::vector& obj_sets, auth_3d_database* auth_3d_db, object_database* obj_db) { obj_sets.clear(); std::vector uid; auth_3d_db->get_category_uids(name.c_str(), uid); for (int32_t& i : uid) { const char* uid_name = auth_3d_data_get_uid_name(i, auth_3d_db); if (!uid_name) continue; const char* s = strchr(uid_name, '_'); if (!s) break; uint32_t obj_set = obj_db->get_object_set_id(std::string(uid_name, s - uid_name).c_str()); if (obj_set != -1) obj_sets.push_back(obj_set); break; } if (!name.find("ITMPV")) { int32_t pv_id = atoi(name.substr(5, 3).c_str()); const pv_db_pv_difficulty* diff = task_pv_db_get_pv_difficulty(pv_id, PV_DIFFICULTY_HARD, 0); if (diff) for (const pv_db_pv_item& i : diff->pv_item) { if (i.index <= 0) continue; object_info info = obj_db->get_object_info(i.name.c_str()); if (info.not_null()) obj_sets.push_back(info.set_id); } } if (!name.find("EFFCHRPV")) { uint32_t obj_set = obj_db->get_object_set_id(name.c_str()); if (obj_set != -1) obj_sets.push_back(obj_set); } prj::sort_unique(obj_sets); std::string stgpv; size_t stgpv_offset = name.find("STGPV"); if (stgpv_offset != -1) stgpv = name.substr(stgpv_offset, 8); size_t stgd2pv_offset = name.find("STGD2PV"); if (stgd2pv_offset != -1) stgpv = name.substr(stgd2pv_offset, 10); if (stgpv.size()) { uint32_t obj_set = obj_db->get_object_set_id(stgpv.c_str()); if (obj_set != -1) obj_sets.push_back(obj_set); } stgpv.append("HRC"); uint32_t obj_set = obj_db->get_object_set_id(stgpv.c_str()); if (obj_set != -1) obj_sets.push_back(obj_set); } const char* auth_3d_data_get_uid_name(int32_t uid, auth_3d_database* auth_3d_db) { if (uid < 0 || uid > auth_3d_db->uid.size()) return 0; auth_3d_database_uid* db_uid = &auth_3d_db->uid[uid]; if (db_uid->enabled) return db_uid->name.c_str(); return 0; } void auth_3d_data_load_auth_3d_db(auth_3d_database* auth_3d_db) { auth_3d_data->farcs.clear(); auth_3d_data->farcs.resize(auth_3d_db->category.size()); size_t cat_index = 0; for (auth_3d_farc& i : auth_3d_data->farcs) i.name.assign(auth_3d_db->category[cat_index++].name); auth_3d_data->uid_files.clear(); auth_3d_data->uid_files.resize(auth_3d_db->uid.size()); size_t uid_index = 0; for (auth_3d_uid_file& i : auth_3d_data->uid_files) i.uid = (int32_t)(uid_index++); } void auth_3d_data_load_category(const char* category_name, const char* mdata_dir) { auth_3d_data_struct_load_category(auth_3d_data, category_name, mdata_dir); } void auth_3d_data_load_category(void* data, const char* category_name, uint32_t category_hash) { auth_3d_data_struct_load_category(auth_3d_data, data, category_name, category_hash); } void auth_3d_data_unload_category(const char* category_name) { auth_3d_data_struct_unload_category(auth_3d_data, category_name); } void auth_3d_data_unload_category(uint32_t category_hash) { auth_3d_data_struct_unload_category(auth_3d_data, category_hash); } void auth_3d_data_free() { if (auth_3d_data) { delete auth_3d_data; auth_3d_data = 0; } } void task_auth_3d_init() { if (!task_auth_3d) task_auth_3d = new auth_3d_detail::TaskAuth3d; } bool task_auth_3d_add_task() { return app::TaskWork::add_task(task_auth_3d, "AUTH_3D"); } bool task_auth_3d_check_task_ready() { return app::TaskWork::check_task_ready(task_auth_3d); } bool task_auth_3d_del_task() { return task_auth_3d->del(); } void task_auth_3d_free() { if (task_auth_3d) { delete task_auth_3d; task_auth_3d = 0; } } namespace auth_3d_detail { TaskAuth3d::TaskAuth3d() { } TaskAuth3d:: ~TaskAuth3d() { } bool TaskAuth3d::init() { return auth_3d_data_struct_init(auth_3d_data, rctx_ptr); } bool TaskAuth3d::ctrl() { return auth_3d_data_struct_ctrl(auth_3d_data, rctx_ptr); } void TaskAuth3d::disp() { auth_3d_data_struct_disp(auth_3d_data, rctx_ptr); } FrameRateTimeStop::FrameRateTimeStop() { } FrameRateTimeStop::~FrameRateTimeStop() { } float_t FrameRateTimeStop::get_delta_frame() { return 0.0f; } } static bool a3da_msgpack_read_key(a3da_key& key, msgpack* msg) { if (msg->read_bool("remove")) { key = {}; return false; } if (msg->read_bool("ignore_tangents") && key.keys.size()) { float_t ep_pre_val = key.keys.front().tangent1; float_t ep_post_val = key.keys.back().tangent2; for (kft3& i : key.keys) { i.tangent1 = 0.0f; i.tangent2 = 0.0f; } if (key.ep_type_pre == A3DA_EP_LINEAR) key.keys.front().tangent1 = ep_pre_val; if (key.ep_type_post == A3DA_EP_LINEAR) key.keys.back().tangent2 = ep_post_val; } msgpack* max_frame = msg->read("max_frame"); if (max_frame) key.max_frame = max_frame->read_float_t(); msgpack* change_type = msg->read("change_type"); if (change_type) { a3da_key_type type = (a3da_key_type)change_type->read_int32_t(); switch (type) { case A3DA_KEY_NONE: key.keys.clear(); key.type = A3DA_KEY_NONE; key.value = 0.0f; return true; case A3DA_KEY_STATIC: key.keys.clear(); key.type = A3DA_KEY_STATIC; key.value = msg->read_float_t("value"); return true; case A3DA_KEY_LINEAR: case A3DA_KEY_HERMITE: case A3DA_KEY_HOLD: switch (key.type) { case A3DA_KEY_LINEAR: case A3DA_KEY_HERMITE: case A3DA_KEY_HOLD: key.type = type; break; } break; } } msgpack* replace_keys = msg->read_array("replace_keys"); if (replace_keys) { key.keys.clear(); msgpack_array* ptr = replace_keys->data.arr; for (msgpack& i : *ptr) { msgpack& _key = i; msgpack* data = _key.read_array(); if (!data) continue; msgpack_array* ptr = data->data.arr; kft3 k = {}; switch (ptr->size()) { case 1: k.frame = (*ptr)[0].read_float_t(); break; case 2: k.frame = (*ptr)[0].read_float_t(); k.value = (*ptr)[1].read_float_t(); break; case 3: { k.frame = (*ptr)[0].read_float_t(); k.value = (*ptr)[1].read_float_t(); float_t tangent = (*ptr)[2].read_float_t(); k.tangent1 = tangent; k.tangent2 = tangent; } break; case 4: k.frame = (*ptr)[0].read_float_t(); k.value = (*ptr)[1].read_float_t(); k.tangent1 = (*ptr)[2].read_float_t(); k.tangent2 = (*ptr)[3].read_float_t(); break; } key.keys.push_back(k); } } return true; } static bool a3da_msgpack_read_vec3(a3da_vec3& vec, msgpack* msg) { if (msg->read_bool("remove")) { vec = {}; return false; } msgpack* x = msg->read_map("x"); if (x && !a3da_msgpack_read_key(vec.x, x)) vec.x = {}; msgpack* y = msg->read_map("y"); if (y && !a3da_msgpack_read_key(vec.y, y)) vec.y = {}; msgpack* z = msg->read_map("z"); if (z && !a3da_msgpack_read_key(vec.z, z)) vec.z = {}; return true; } static bool a3da_msgpack_read_rgba(a3da_rgba& rgba, msgpack* msg) { if (msg->read_bool("remove")) { rgba = {}; return false; } msgpack* rgb = msg->read_map("rgb"); if (rgb) { a3da_key rgb_key = rgba.r; if (a3da_msgpack_read_key(rgb_key, rgb)) { rgba.r = rgb_key; rgba.g = rgb_key; rgba.b = rgb_key; enum_or(rgba.flags, A3DA_RGBA_R | A3DA_RGBA_G | A3DA_RGBA_B); } else { rgba.r = {}; rgba.g = {}; rgba.b = {}; enum_and(rgba.flags, ~(A3DA_RGBA_R | A3DA_RGBA_G | A3DA_RGBA_B)); } } msgpack* r = msg->read_map("r"); if (r) { enum_or(rgba.flags, A3DA_RGBA_R); if (!a3da_msgpack_read_key(rgba.r, r)) { rgba.r = {}; enum_and(rgba.flags, ~A3DA_RGBA_R); } } msgpack* g = msg->read_map("g"); if (g) { enum_or(rgba.flags, A3DA_RGBA_G); if (!a3da_msgpack_read_key(rgba.g, g)) { rgba.g = {}; enum_and(rgba.flags, ~A3DA_RGBA_G); } } msgpack* b = msg->read_map("b"); if (b) { enum_or(rgba.flags, A3DA_RGBA_B); if (!a3da_msgpack_read_key(rgba.b, b)) { rgba.b = {}; enum_and(rgba.flags, ~A3DA_RGBA_B); } } msgpack* a = msg->read_map("a"); if (a) { enum_or(rgba.flags, A3DA_RGBA_A); if (!a3da_msgpack_read_key(rgba.a, a)) { rgba.a = {}; enum_and(rgba.flags, ~A3DA_RGBA_A); } } return true; } static bool a3da_msgpack_read_model_transform(a3da_model_transform& mt, msgpack* msg) { if (msg->read_bool("remove")) { mt = {}; mt.scale.x.type = A3DA_KEY_STATIC; mt.scale.x.value = 1.0f; mt.scale.y.type = A3DA_KEY_STATIC; mt.scale.y.value = 1.0f; mt.scale.z.type = A3DA_KEY_STATIC; mt.scale.z.value = 1.0f; mt.visibility.type = A3DA_KEY_STATIC; mt.visibility.value = 1.0f; return false; } msgpack* trans = msg->read_map("trans"); if (trans && !a3da_msgpack_read_vec3(mt.translation, trans)) mt.translation = {}; msgpack* rot = msg->read_map("rot"); if (rot && !a3da_msgpack_read_vec3(mt.rotation, rot)) mt.rotation = {}; msgpack* scale = msg->read_map("scale"); if (scale && !a3da_msgpack_read_vec3(mt.scale, scale)) { mt.scale = {}; mt.scale.x.type = A3DA_KEY_STATIC; mt.scale.x.value = 1.0f; mt.scale.y.type = A3DA_KEY_STATIC; mt.scale.y.value = 1.0f; mt.scale.z.type = A3DA_KEY_STATIC; mt.scale.z.value = 1.0f; } msgpack* visibility = msg->read_map("visibility"); if (visibility && !a3da_msgpack_read_key(mt.visibility, visibility)) { mt.visibility = {}; mt.visibility.type = A3DA_KEY_STATIC; mt.visibility.value = 1.0f; } return true; } static void a3da_msgpack_read(const char* path, const char* file, a3da* auth_file) { if (!path_check_directory_exists(path)) return; char file_buf[0x80]; for (const char* i = file; *i && *i != '.'; i++) { char c = *i; file_buf[i - file] = c; file_buf[i - file + 1] = 0; } char buf[0x200]; sprintf_s(buf, sizeof(buf), "%s\\%s.json", path, file_buf); if (!path_check_file_exists(buf)) return; msgpack msg; file_stream s; s.open(buf, "rb"); io_json_read(s, &msg); s.close(); if (msg.type != MSGPACK_MAP) return; msgpack* curves = msg.read_array("curve"); if (curves) { msgpack_array* ptr = curves->data.arr; for (msgpack& i : *ptr) { msgpack& curve = i; std::string name = curve.read_string("name"); uint32_t name_hash = hash_string_murmurhash(name); for (a3da_curve& j : auth_file->curve) { if (name_hash != hash_string_murmurhash(j.name)) continue; msgpack* cv = curve.read_map("cv"); if (cv) a3da_msgpack_read_key(j.curve, cv); break; } } } msgpack* m_objhrcs = msg.read_array("m_objhrc"); if (m_objhrcs) { msgpack_array* ptr = m_objhrcs->data.arr; for (msgpack& i : *ptr) { msgpack& m_objhrc = i; std::string name = m_objhrc.read_string("name"); uint32_t name_hash = hash_string_murmurhash(name); for (a3da_m_object_hrc& j : auth_file->m_object_hrc) { if (name_hash != hash_string_murmurhash(j.name)) continue; msgpack* instances = m_objhrc.read_array("instance"); if (instances) { msgpack_array* ptr = instances->data.arr; for (msgpack& k : *ptr) { msgpack& instance = k; int32_t index = instance.read_int32_t("index"); if (index < j.instance.size()) j.instance[index].shadow = instance.read_bool("shadow"); } } break; } } } msgpack* material_lists = msg.read_array("material_list"); if (material_lists) { msgpack_array* ptr = material_lists->data.arr; for (msgpack& i : *ptr) { msgpack& material_list = i; std::string name = material_list.read_string("name"); uint32_t name_hash = hash_string_murmurhash(name); auto j_begin = auth_file->material_list.begin(); auto j_end = auth_file->material_list.end(); for (auto j = j_begin; j != j_end; j++) { if (name_hash != hash_string_murmurhash(j->name)) continue; bool remove = material_list.read_bool("remove"); if (remove) { auth_file->material_list.erase(j); break; } msgpack* new_name = material_list.read("new_name"); if (new_name) j->name.assign(new_name->read_string()); msgpack* blend_color = material_list.read_map("blend_color"); if (blend_color) { enum_or(j->flags, A3DA_MATERIAL_LIST_BLEND_COLOR); if (!a3da_msgpack_read_rgba(j->blend_color, blend_color)) enum_and(j->flags, ~A3DA_MATERIAL_LIST_BLEND_COLOR); } msgpack* emission = material_list.read_map("emission"); if (emission) { enum_or(j->flags, A3DA_MATERIAL_LIST_EMISSION); if (!a3da_msgpack_read_rgba(j->emission, emission)) enum_and(j->flags, ~A3DA_MATERIAL_LIST_EMISSION); } if (!j->flags) auth_file->material_list.erase(j); break; } } } std::vector remove_parent_name; std::vector remove_parent_node; msgpack* objhrcs = msg.read_array("objhrc"); if (objhrcs) { msgpack_array* ptr = objhrcs->data.arr; for (msgpack& i : *ptr) { msgpack& objhrc = i; std::string name = objhrc.read_string("name"); uint32_t name_hash = hash_string_murmurhash(name); auto j_begin = auth_file->object_hrc.begin(); auto j_end = auth_file->object_hrc.end(); for (auto j = j_begin; j != j_end; j++) { if (name_hash != hash_string_murmurhash(j->name)) continue; bool remove = objhrc.read_bool("remove"); if (remove) { auto k_begin = auth_file->object_list.begin(); auto k_end = auth_file->object_list.end(); for (auto k = k_begin; k != k_end; k++) if (name_hash == hash_string_murmurhash(*k)) { auth_file->object_list.erase(k); break; } remove_parent_name.push_back(j->name); for (a3da_object_node& k : j->node) remove_parent_node.push_back(k.name); auth_file->object_hrc.erase(j); break; } j->shadow = objhrc.read_bool("shadow"); break; } } } msgpack* objects = msg.read_array("object"); if (objects) { msgpack_array* ptr = objects->data.arr; for (msgpack& i : *ptr) { msgpack& object = i; std::string name = object.read_string("name"); uint32_t name_hash = hash_string_murmurhash(name); auto j_begin = auth_file->object.begin(); auto j_end = auth_file->object.end(); for (auto j = j_begin; j != j_end; j++) { if (name_hash != hash_string_murmurhash(j->name)) continue; bool remove = object.read_bool("remove"); if (remove) { auto k_begin = auth_file->object_hrc_list.begin(); auto k_end = auth_file->object_hrc_list.end(); for (auto k = k_begin; k != k_end; k++) if (name_hash == hash_string_murmurhash(*k)) { auth_file->object_hrc_list.erase(k); break; } remove_parent_name.push_back(j->name); auth_file->object.erase(j); break; } bool remove_morph = object.read_bool("remove_morph"); if (remove_morph) { j->morph.assign(""); j->morph_offset = 0.0f; } a3da_msgpack_read_model_transform(j->model_transform, &object); break; } } } msgpack* play_control = msg.read_map("play_control"); if (play_control) { msgpack* begin = play_control->read("begin"); if (begin) auth_file->play_control.begin = begin->read_float_t(); msgpack* fps = play_control->read("fps"); if (fps) auth_file->play_control.begin = fps->read_float_t(); msgpack* size = play_control->read("size"); if (size) auth_file->play_control.size = size->read_float_t(); } while (remove_parent_name.size() || remove_parent_node.size()) { size_t remove_parent_name_size = remove_parent_name.size(); for (size_t i = remove_parent_name_size, i1 = 0; i; i--, i1++) { uint32_t remove_parent_name_hash = hash_string_murmurhash(remove_parent_name[i1]); auto j_begin = auth_file->object.begin(); auto j_end = auth_file->object.end(); for (auto j = j_begin; j != j_end; j++) if (remove_parent_name_hash == hash_string_murmurhash(j->parent_name)) { remove_parent_name.push_back(j->name); auth_file->object.erase(j); break; } auto k_begin = auth_file->object_hrc.begin(); auto k_end = auth_file->object_hrc.end(); for (auto k = k_begin; k != k_end; k++) if (remove_parent_name_hash == hash_string_murmurhash(k->parent_name)) { remove_parent_name.push_back(k->name); for (a3da_object_node& l : k->node) remove_parent_node.push_back(l.name); auth_file->object_hrc.erase(k); break; } } remove_parent_name.erase(remove_parent_name.begin(), remove_parent_name.begin() + remove_parent_name_size); size_t remove_parent_node_size = remove_parent_node.size(); for (size_t i = remove_parent_node_size, i1 = 0; i; i--, i1++) { uint32_t remove_parent_node_hash = hash_string_murmurhash(remove_parent_node[i1]); auto j_begin = auth_file->object.begin(); auto j_end = auth_file->object.end(); for (auto j = j_begin; j != j_end; j++) if (remove_parent_node_hash == hash_string_murmurhash(j->parent_node)) { remove_parent_node.push_back(j->name); auth_file->object.erase(j); break; } auto k_begin = auth_file->object_hrc.begin(); auto k_end = auth_file->object_hrc.end(); for (auto k = k_begin; k != k_end; k++) if (remove_parent_node_hash == hash_string_murmurhash(k->parent_node)) { remove_parent_node.push_back(k->name); for (a3da_object_node& l : k->node) remove_parent_node.push_back(l.name); auth_file->object_hrc.erase(k); break; } } remove_parent_node.erase(remove_parent_node.begin(), remove_parent_node.begin() + remove_parent_node_size); }; } static bool auth_3d_key_detect_fast_change(auth_3d_key* data, float_t frame, float_t threshold) { if (data->type < AUTH_3D_KEY_LINEAR || data->type > AUTH_3D_KEY_HOLD) return false; frame = clamp_def(frame, 0.0f, data->max_frame); size_t length = data->length; if (!length) return false; kft3* keys = data->keys; kft3* key = auth_3d_key_find_keyframe(data, frame); if (key == keys || key == &keys[1] || key == &keys[length]) return false; kft3* next_key = &key[1]; if (next_key == &keys[length]) return false; kft3* prev_key = &key[-1]; float_t v18 = key->frame - prev_key->frame; if (v18 >= 2.0f || v18 <= 0.0f) return 0; if (fabsf(key->value - prev_key->value) <= threshold) return 0; kft3* v21 = &prev_key[-1]; if (prev_key->frame <= v21->frame) { while (v21 != keys) { if (prev_key->frame > v21->frame) break; v21++; } if (v21 == keys) return 0; } float_t v23 = key->value - (prev_key->value / v18); float_t v25; float_t v30; if (data->type != AUTH_3D_KEY_HERMITE) { v25 = (prev_key->value - v21->value) / (prev_key->frame - v21->frame); v30 = (next_key->value - key->value) / (next_key->frame - key->frame); } else { if (prev_key->frame - v21->frame >= 2.0f) { float_t v26; if (v21->frame < prev_key->frame) v26 = interpolate_chs_value(key->value, next_key->value, key->tangent2, next_key->tangent1, prev_key->frame, v21->frame, prev_key->frame - 1.0f); else v26 = v21->value; v25 = prev_key->value - v26; } else v25 = (prev_key->value - v21->value) / (prev_key->frame - v21->frame); if (next_key->frame - key->frame >= 2.0f) { float_t v29; if (key->frame < next_key->frame) v29 = interpolate_chs_value(key->value, next_key->value, key->tangent2, next_key->tangent1, key->frame, next_key->frame, 1.0f); else v29 = key->value; v30 = v29 - key->value; } else v30 = (next_key->value - key->value) / (next_key->frame - key->frame); } float_t v32 = fabsf(v25); float_t v33 = v25 * v23; float_t v34 = v30 * v23; float_t v35 = fabsf(v23); float_t v36 = fabsf(v30); return (v33 <= 0.0f || (v32 < v35 && v32 <= threshold)) && (v34 <= 0.0f || (v36 < v35 && v36 <= threshold)); } static float_t auth_3d_interpolate_value(auth_3d_key_type type, float_t frame, kft3* curr_key, kft3* next_key) { switch (type) { case AUTH_3D_KEY_LINEAR: if (curr_key->frame < next_key->frame) return interpolate_linear_value(curr_key->value, next_key->value, curr_key->frame, next_key->frame, frame); else return curr_key->value; case AUTH_3D_KEY_HERMITE: if (curr_key->frame < next_key->frame) return interpolate_chs_value(curr_key->value, next_key->value, curr_key->tangent2, next_key->tangent1, curr_key->frame, next_key->frame, frame); else return curr_key->value; case AUTH_3D_KEY_HOLD: if (frame >= next_key->frame) return next_key->value; else return curr_key->value; default: return 0.0f; } } static kft3* auth_3d_key_find_keyframe(auth_3d_key* data, float_t frame) { kft3* key = data->keys; size_t length = data->length; size_t temp; while (length > 0) if (key[temp = length / 2].frame > frame) length = temp; else { key += temp + 1; length -= temp + 1; } return key; } static float_t auth_3d_key_interpolate_inner(auth_3d_key* data, float_t frame) { kft3* first_key = data->keys; kft3* key = auth_3d_key_find_keyframe(data, frame); if (key == first_key) return first_key->value; else if (key == &first_key[data->length]) return key[-1].value; else return auth_3d_interpolate_value(data->type, frame, key - 1, key); } static void auth_3d_key_load(auth_3d* auth, auth_3d_key* k, auth_3d_key_file* kf) { k->max_frame = auth->max_frame; k->frame_delta = k->max_frame; k->value_delta = 0.0f; switch (kf->type) { case A3DA_KEY_NONE: k->type = AUTH_3D_KEY_NONE; k->value = 0.0f; return; case A3DA_KEY_STATIC: k->type = kf->value != 0.0f ? AUTH_3D_KEY_STATIC : AUTH_3D_KEY_NONE; k->value = kf->value; return; case A3DA_KEY_LINEAR: k->type = AUTH_3D_KEY_LINEAR; break; case A3DA_KEY_HERMITE: default: k->type = AUTH_3D_KEY_HERMITE; break; case A3DA_KEY_HOLD: k->type = AUTH_3D_KEY_HOLD; break; } size_t length = kf->keys.size(); if (length > 1) { k->keys_vec.assign(kf->keys.begin(), kf->keys.end()); k->length = length; k->keys = k->keys_vec.data(); kft3* first_key = &k->keys[0]; kft3* last_key = &k->keys[length - 1]; if (first_key->frame < last_key->frame && last_key->frame > 0.0f && k->max_frame > first_key->frame) { k->ep_type_pre = (auth_3d_ep_type)kf->ep_type_pre; k->ep_type_post = (auth_3d_ep_type)kf->ep_type_post; k->frame_delta = last_key->frame - first_key->frame; k->value_delta = last_key->value - first_key->value; } } else if (length == 1) { float_t value = kf->keys.front().value; k->type = value != 0.0f ? AUTH_3D_KEY_STATIC : AUTH_3D_KEY_NONE; k->value = value; } else { k->type = AUTH_3D_KEY_NONE; k->value = 0.0f; } } static void auth_3d_key_store(auth_3d* auth, auth_3d_key* k, auth_3d_key_file* kf) { kf->max_frame = auth->max_frame; switch (k->type) { case AUTH_3D_KEY_NONE : kf->type = A3DA_KEY_NONE; kf->value = 0.0f; return; case AUTH_3D_KEY_STATIC : kf->type = k->value != 0.0f ? A3DA_KEY_STATIC : A3DA_KEY_NONE; kf->value = k->value; return; case AUTH_3D_KEY_LINEAR : kf->type = A3DA_KEY_LINEAR; break; case AUTH_3D_KEY_HERMITE: default: kf->type = A3DA_KEY_HERMITE; break; case AUTH_3D_KEY_HOLD : kf->type = A3DA_KEY_HOLD; break; } size_t length = k->keys_vec.size(); if (length > 1) { kf->keys.assign(k->keys_vec.begin(), k->keys_vec.end()); kft3* first_key = &k->keys[0]; kft3* last_key = &k->keys[length - 1]; if (first_key->frame < last_key->frame && last_key->frame > 0.0f && k->max_frame > first_key->frame) { kf->ep_type_pre = (a3da_ep_type)k->ep_type_pre; kf->ep_type_post = (a3da_ep_type)k->ep_type_post; } } else if (length == 1) { float_t value = k->keys_vec.front().value; kf->type = value != 0.0f ? A3DA_KEY_STATIC : A3DA_KEY_NONE; kf->value = value; } else { kf->type = A3DA_KEY_NONE; kf->value = 0.0f; } } static void auth_3d_rgba_load(auth_3d* auth, auth_3d_rgba* rgba, auth_3d_rgba_file* rgbaf) { if (rgbaf->flags & A3DA_RGBA_R) { auth_3d_key_load(auth, &rgba->r, &rgbaf->r); enum_or(rgba->flags, AUTH_3D_RGBA_R); } if (rgbaf->flags & A3DA_RGBA_G) { auth_3d_key_load(auth, &rgba->g, &rgbaf->g); enum_or(rgba->flags, AUTH_3D_RGBA_G); } if (rgbaf->flags & A3DA_RGBA_B) { auth_3d_key_load(auth, &rgba->b, &rgbaf->b); enum_or(rgba->flags, AUTH_3D_RGBA_B); } if (rgbaf->flags & A3DA_RGBA_A) { auth_3d_key_load(auth, &rgba->a, &rgbaf->a); enum_or(rgba->flags, AUTH_3D_RGBA_A); } } static void auth_3d_rgba_store(auth_3d* auth, auth_3d_rgba* rgba, auth_3d_rgba_file* rgbaf) { if (rgba->flags & AUTH_3D_RGBA_R) { auth_3d_key_store(auth, &rgba->r, &rgbaf->r); enum_or(rgbaf->flags, A3DA_RGBA_R); } if (rgba->flags & AUTH_3D_RGBA_G) { auth_3d_key_store(auth, &rgba->g, &rgbaf->g); enum_or(rgbaf->flags, A3DA_RGBA_G); } if (rgba->flags & AUTH_3D_RGBA_B) { auth_3d_key_store(auth, &rgba->b, &rgbaf->b); enum_or(rgbaf->flags, A3DA_RGBA_B); } if (rgba->flags & AUTH_3D_RGBA_A) { auth_3d_key_store(auth, &rgba->a, &rgbaf->a); enum_or(rgbaf->flags, A3DA_RGBA_A); } } static void auth_3d_vec3_load(auth_3d* auth, auth_3d_vec3* vec, auth_3d_vec3_file* vecf) { auth_3d_key_load(auth, &vec->x, &vecf->x); auth_3d_key_load(auth, &vec->y, &vecf->y); auth_3d_key_load(auth, &vec->z, &vecf->z); } static void auth_3d_vec3_store(auth_3d* auth, auth_3d_vec3* vec, auth_3d_vec3_file* vecf) { auth_3d_key_store(auth, &vec->x, &vecf->x); auth_3d_key_store(auth, &vec->y, &vecf->y); auth_3d_key_store(auth, &vec->z, &vecf->z); } static void auth_3d_model_transform_load(auth_3d* auth, auth_3d_model_transform* mt, auth_3d_model_transform_file* mtf) { auth_3d_vec3_load(auth, &mt->rotation, &mtf->rotation); auth_3d_vec3_load(auth, &mt->scale, &mtf->scale); auth_3d_vec3_load(auth, &mt->translation, &mtf->translation); auth_3d_key_load(auth, &mt->visibility, &mtf->visibility); } static void auth_3d_model_transform_store(auth_3d* auth, auth_3d_model_transform* mt, auth_3d_model_transform_file* mtf) { auth_3d_vec3_store(auth, &mt->rotation, &mtf->rotation); auth_3d_vec3_store(auth, &mt->scale, &mtf->scale); auth_3d_vec3_store(auth, &mt->translation, &mtf->translation); auth_3d_key_store(auth, &mt->visibility, &mtf->visibility); } static int32_t auth_3d_get_auth_3d_object_index_by_object_info(auth_3d* auth, object_info obj_info, int32_t object_instance) { int32_t obj_instance = 0; for (auth_3d_object& i : auth->object) if (obj_info == i.object_info) { if (obj_instance == object_instance) return (int32_t)(&i - auth->object.data()); obj_instance++; } return -1; } static int32_t auth_3d_get_auth_3d_object_index_by_hash(auth_3d* auth, uint32_t object_hash, int32_t object_instance) { int32_t obj_instance = 0; for (auth_3d_object& i : auth->object) if (object_hash == i.object_hash) { if (obj_instance == object_instance) return (int32_t)(&i - auth->object.data()); obj_instance++; } return -1; } static const mat4* auth_3d_get_auth_3d_object_mat(auth_3d* auth, size_t index) { if (index >= auth->object.size()) return 0; return &auth->object[index].model_transform.mat; } static const mat4* auth_3d_get_auth_3d_object_hrc_bone_mats(auth_3d* auth, size_t index) { if (index >= auth->object_hrc.size() || auth->object_hrc[index].mats.size() < 1) return 0; return auth->object_hrc[index].mats.data(); } static int32_t auth_3d_get_auth_3d_object_hrc_index_by_object_info(auth_3d* auth, object_info obj_info, int32_t object_instance) { if (object_instance < 0) { for (auth_3d_object_hrc& i : auth->object_hrc) if (obj_info == i.object_info) return (int32_t)(&i - auth->object_hrc.data()); } else { int32_t obj_instance = 0; for (auth_3d_object_hrc& i : auth->object_hrc) if (obj_info == i.object_info) { if (obj_instance == object_instance) return (int32_t)(&i - auth->object_hrc.data()); obj_instance++; } } return -1; } static int32_t auth_3d_get_auth_3d_object_hrc_index_by_hash(auth_3d* auth, uint32_t object_hash, int32_t instance) { if (instance < 0) { for (auth_3d_object_hrc& i : auth->object_hrc) if (object_hash == i.object_hash) return (int32_t)(&i - auth->object_hrc.data()); } else { int32_t obj_instance = 0; for (auth_3d_object_hrc& i : auth->object_hrc) if (object_hash == i.object_hash) { if (obj_instance == instance) return (int32_t)(&i - auth->object_hrc.data()); obj_instance++; } } return -1; } static void auth_3d_read_file(auth_3d* auth, auth_3d_database* auth_3d_db) { if (auth->uid >= auth_3d_db->uid.size()) return; auth_3d_database_uid* db_uid = &auth_3d_db->uid[auth->uid]; if (db_uid->enabled) { auth_3d_uid_file* uid_file = &auth_3d_data->uid_files[auth->uid]; if (uid_file->uid == auth->uid) { auth_3d_uid_file_load_file(uid_file, auth_3d_db); auth->state = 1; } } } static void auth_3d_read_file_modern(auth_3d* auth) { auto elem = auth_3d_data->uid_files_modern.find(auth->hash); if (elem == auth_3d_data->uid_files_modern.end()) return; auth_3d_uid_file_modern* uid_file = &elem->second; if (uid_file->hash == auth->hash) { auth_3d_uid_file_modern_load_file(uid_file); auth->state = 1; } } static void auth_3d_set_material_list(auth_3d* auth, render_context* rctx) { mdl::DispManager& disp_manager = *rctx->disp_manager; int32_t mat_list_count = 0; material_list_struct mat_list[MATERIAL_LIST_COUNT]; for (auth_3d_material_list& i : auth->material_list) { if (!i.blend_color.flags && !i.emission.flags) continue; if (i.blend_color.flags) { vec4& blend_color = mat_list[mat_list_count].blend_color; vec4u8& has_blend_color = mat_list[mat_list_count].has_blend_color; blend_color = i.blend_color.value; has_blend_color.x = !!(i.blend_color.flags & AUTH_3D_RGBA_R); has_blend_color.y = !!(i.blend_color.flags & AUTH_3D_RGBA_B); has_blend_color.z = !!(i.blend_color.flags & AUTH_3D_RGBA_G); has_blend_color.w = !!(i.blend_color.flags & AUTH_3D_RGBA_A); } else { mat_list[mat_list_count].blend_color = {}; mat_list[mat_list_count].has_blend_color = {}; } if (i.emission.flags) { vec4& emission = mat_list[mat_list_count].emission; vec4u8& has_emission = mat_list[mat_list_count].has_emission; emission = i.emission.value; has_emission.x = !!(i.emission.flags & AUTH_3D_RGBA_R); has_emission.y = !!(i.emission.flags & AUTH_3D_RGBA_B); has_emission.z = !!(i.emission.flags & AUTH_3D_RGBA_G); has_emission.w = !!(i.emission.flags & AUTH_3D_RGBA_A); } else { mat_list[mat_list_count].emission = {}; mat_list[mat_list_count].has_emission = {}; } mat_list[mat_list_count].hash = i.hash; mat_list_count++; } disp_manager.set_material_list(mat_list_count, mat_list); } static void auth_3d_ambient_load(auth_3d* auth, auth_3d_ambient* a, auth_3d_ambient_file* af) { if (af->flags & A3DA_AMBIENT_LIGHT_DIFFUSE) { auth_3d_rgba_load(auth, &a->light_diffuse, &af->light_diffuse); enum_or(a->flags, AUTH_3D_AMBIENT_LIGHT_DIFFUSE); } a->name.assign(af->name); if (af->flags & A3DA_AMBIENT_LIGHT_DIFFUSE) { auth_3d_rgba_load(auth, &a->rim_light_diffuse, &af->rim_light_diffuse); enum_or(a->flags, AUTH_3D_AMBIENT_LIGHT_DIFFUSE); } } static void auth_3d_ambient_set(auth_3d_ambient* a, render_context* rctx) { } static void auth_3d_ambient_store(auth_3d* auth, auth_3d_ambient* a, auth_3d_ambient_file* af) { if (a->flags & AUTH_3D_AMBIENT_LIGHT_DIFFUSE) { auth_3d_rgba_store(auth, &a->light_diffuse, &af->light_diffuse); enum_or(af->flags, A3DA_AMBIENT_LIGHT_DIFFUSE); } af->name.assign(a->name); if (a->flags & AUTH_3D_AMBIENT_LIGHT_DIFFUSE) { auth_3d_rgba_store(auth, &a->rim_light_diffuse, &af->rim_light_diffuse); enum_or(af->flags, A3DA_AMBIENT_LIGHT_DIFFUSE); } } static void auth_3d_camera_auxiliary_load(auth_3d* auth, auth_3d_camera_auxiliary_file* caf) { auth_3d_camera_auxiliary* ca = &auth->camera_auxiliary; if (caf->flags & A3DA_CAMERA_AUXILIARY_AUTO_EXPOSURE) { auth_3d_key_load(auth, &ca->auto_exposure, &caf->auto_exposure); enum_or(ca->flags, AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE); } if (caf->flags & A3DA_CAMERA_AUXILIARY_EXPOSURE) { auth_3d_key_load(auth, &ca->exposure, &caf->exposure); enum_or(ca->flags, AUTH_3D_CAMERA_AUXILIARY_EXPOSURE); } if (caf->flags & A3DA_CAMERA_AUXILIARY_EXPOSURE_RATE) { auth_3d_key_load(auth, &ca->exposure_rate, &caf->exposure_rate); enum_or(ca->flags, AUTH_3D_CAMERA_AUXILIARY_EXPOSURE_RATE); } if (caf->flags & A3DA_CAMERA_AUXILIARY_GAMMA) { auth_3d_key_load(auth, &ca->gamma, &caf->gamma); enum_or(ca->flags, AUTH_3D_CAMERA_AUXILIARY_GAMMA); } if (caf->flags & A3DA_CAMERA_AUXILIARY_GAMMA_RATE) { auth_3d_key_load(auth, &ca->gamma_rate, &caf->gamma_rate); enum_or(ca->flags, AUTH_3D_CAMERA_AUXILIARY_GAMMA_RATE); } if (caf->flags & A3DA_CAMERA_AUXILIARY_SATURATE) { auth_3d_key_load(auth, &ca->saturate, &caf->saturate); enum_or(ca->flags, AUTH_3D_CAMERA_AUXILIARY_SATURATE); } } static void auth_3d_camera_auxiliary_restore_prev_value(auth_3d_camera_auxiliary* ca, render_context* rctx) { if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE) rctx->render.set_auto_exposure(true); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE) rctx->render.set_exposure(2.0); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA) rctx->render.set_gamma(1.0); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA_RATE) rctx->render.set_gamma_rate(1.0); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_SATURATE) rctx->render.set_saturate_coeff(1.0, 0, false); } static void auth_3d_camera_auxiliary_set(auth_3d_camera_auxiliary* ca, render_context* rctx) { if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE) rctx->render.set_auto_exposure(ca->auto_exposure_value > 0.0f); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE) rctx->render.set_exposure(ca->exposure_value); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA) rctx->render.set_gamma(ca->gamma_value); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA_RATE) rctx->render.set_gamma_rate(ca->gamma_rate_value); if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_SATURATE) rctx->render.set_saturate_coeff(ca->saturate_value, 0, false); } static void auth_3d_camera_auxiliary_store(auth_3d* auth, auth_3d_camera_auxiliary_file* caf) { auth_3d_camera_auxiliary* ca = &auth->camera_auxiliary; if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE) { auth_3d_key_store(auth, &ca->auto_exposure, &caf->auto_exposure); enum_or(caf->flags, A3DA_CAMERA_AUXILIARY_AUTO_EXPOSURE); } if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE) { auth_3d_key_store(auth, &ca->exposure, &caf->exposure); enum_or(caf->flags, A3DA_CAMERA_AUXILIARY_EXPOSURE); } if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_EXPOSURE_RATE) { auth_3d_key_store(auth, &ca->exposure_rate, &caf->exposure_rate); enum_or(caf->flags, A3DA_CAMERA_AUXILIARY_EXPOSURE_RATE); } if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA) { auth_3d_key_store(auth, &ca->gamma, &caf->gamma); enum_or(caf->flags, A3DA_CAMERA_AUXILIARY_GAMMA); } if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_GAMMA_RATE) { auth_3d_key_store(auth, &ca->gamma_rate, &caf->gamma_rate); enum_or(caf->flags, A3DA_CAMERA_AUXILIARY_GAMMA_RATE); } if (ca->flags & AUTH_3D_CAMERA_AUXILIARY_SATURATE) { auth_3d_key_store(auth, &ca->saturate, &caf->saturate); enum_or(caf->flags, A3DA_CAMERA_AUXILIARY_SATURATE); } } static float_t auth_3d_camera_root_calc_frame(auth_3d_camera_root* cr, float_t frame, render_context* rctx) { if (auth_3d_key_detect_fast_change(&cr->view_point.model_transform.translation.x, frame, 0.3f) || auth_3d_key_detect_fast_change(&cr->view_point.model_transform.translation.y, frame, 0.3f) || auth_3d_key_detect_fast_change(&cr->view_point.model_transform.translation.z, frame, 0.3f) || auth_3d_key_detect_fast_change(&cr->interest.translation.x, frame, 0.3f) || auth_3d_key_detect_fast_change(&cr->interest.translation.y, frame, 0.3f) || auth_3d_key_detect_fast_change(&cr->interest.translation.z, frame, 0.3f)) { frame = prj::floorf(frame); rctx->camera->set_fast_change(true); } else { float_t frame_prev = frame - get_delta_frame(); if (frame_prev > 0.0f && (int32_t)frame - (int32_t)frame_prev == 2) { frame_prev = prj::ceilf(frame_prev); if (auth_3d_key_detect_fast_change(&cr->view_point.model_transform.translation.x, frame_prev, 0.3f) || auth_3d_key_detect_fast_change(&cr->view_point.model_transform.translation.y, frame_prev, 0.3f) || auth_3d_key_detect_fast_change(&cr->view_point.model_transform.translation.z, frame_prev, 0.3f) || auth_3d_key_detect_fast_change(&cr->interest.translation.x, frame_prev, 0.3f) || auth_3d_key_detect_fast_change(&cr->interest.translation.y, frame_prev, 0.3f) || auth_3d_key_detect_fast_change(&cr->interest.translation.z, frame_prev, 0.3f)) rctx->camera->set_fast_change_hist0(true); } } return frame; } static void auth_3d_camera_root_load(auth_3d* auth, auth_3d_camera_root* cr, auth_3d_camera_root_file* crf) { auth_3d_model_transform_load(auth, &cr->interest, &crf->interest); auth_3d_model_transform_load(auth, &cr->model_transform, &crf->model_transform); auth_3d_camera_root_view_point_load(auth, &cr->view_point, &crf->view_point); } static void auth_3d_camera_root_store(auth_3d* auth, auth_3d_camera_root* cr, auth_3d_camera_root_file* crf) { auth_3d_model_transform_store(auth, &cr->interest, &crf->interest); auth_3d_model_transform_store(auth, &cr->model_transform, &crf->model_transform); auth_3d_camera_root_view_point_store(auth, &cr->view_point, &crf->view_point); } static void auth_3d_camera_root_view_point_load(auth_3d* auth, auth_3d_camera_root_view_point* crvp, auth_3d_camera_root_view_point_file* crvpf) { crvp->aspect = crvpf->aspect; if (crvpf->flags & A3DA_CAMERA_ROOT_VIEW_POINT_FOV) { auth_3d_key_load(auth, &crvp->fov, &crvpf->fov); crvp->fov_is_horizontal = crvpf->fov_is_horizontal; enum_or(crvp->flags, AUTH_3D_CAMERA_ROOT_VIEW_POINT_FOV); } else { crvp->camera_aperture_h = crvpf->camera_aperture_h; crvp->camera_aperture_w = crvpf->camera_aperture_w; auth_3d_key_load(auth, &crvp->focal_length, &crvpf->focal_length); } auth_3d_model_transform_load(auth, &crvp->model_transform, &crvpf->model_transform); if (crvpf->flags & A3DA_CAMERA_ROOT_VIEW_POINT_ROLL) { auth_3d_key_load(auth, &crvp->roll, &crvpf->roll); enum_or(crvp->flags, AUTH_3D_CAMERA_ROOT_VIEW_POINT_ROLL); } } static void auth_3d_camera_root_view_point_store(auth_3d* auth, auth_3d_camera_root_view_point* crvp, auth_3d_camera_root_view_point_file* crvpf) { } static void auth_3d_chara_disp(auth_3d_chara* c, auth_3d* auth, render_context* rctx) { if (c->index <= ROB_CHARA_COUNT) rob_chara_array_set_visibility(c->index, c->model_transform.visible); if (auth->pos) { c->model_transform.set_mat(&auth->mat); spr::put_rgb_cross(c->model_transform.mat); } } static void auth_3d_chara_load(auth_3d* auth, auth_3d_chara* c, auth_3d_chara_file* cf) { auth_3d_model_transform_load(auth, &c->model_transform, &cf->model_transform); c->name.assign(cf->name); } static void auth_3d_chara_store(auth_3d* auth, auth_3d_chara* c, auth_3d_chara_file* cf) { auth_3d_model_transform_store(auth, &c->model_transform, &cf->model_transform); cf->name.assign(c->name); } static void auth_3d_curve_load(auth_3d* auth, auth_3d_curve* c, auth_3d_curve_file* cf) { auth_3d_key_load(auth, &c->curve, &cf->curve); c->name.assign(cf->name); } static void auth_3d_curve_store(auth_3d* auth, auth_3d_curve* c, auth_3d_curve_file* cf) { auth_3d_key_store(auth, &c->curve, &cf->curve); cf->name.assign(c->name); } static void auth_3d_dof_load(auth_3d* auth, auth_3d_dof* d, auth_3d_dof_file* df) { if (df->has_dof) { auth_3d_model_transform_load(auth, &d->model_transform, &df->model_transform); d->has_dof = true; } } static void auth_3d_dof_restore_prev_value(auth_3d_dof* d, render_context* rctx) { if (!d->has_dof) return; rctx->render.set_dof_enable(false); } static void auth_3d_dof_set(auth_3d_dof* d, render_context* rctx) { if (!d->has_dof) return; vec3 view_point; rctx->camera->get_view_point(view_point); float_t focus = vec3::distance(d->model_transform.translation_value, view_point); rctx->render.set_dof_enable(fabsf(d->model_transform.translation_value.x) > 0.000001f); rctx->render.set_dof_data(focus, d->model_transform.scale_value.x, d->model_transform.rotation_value.x, d->model_transform.rotation_value.y); } static void auth_3d_dof_store(auth_3d* auth, auth_3d_dof* d, auth_3d_dof_file* df) { if (d->has_dof) { auth_3d_model_transform_store(auth, &d->model_transform, &df->model_transform); df->has_dof = true; } } static auth_3d_detail::Event* auth_3d_event_load(auth_3d* auth, auth_3d_event_file* ef) { auth_3d_detail::Event* e = 0; switch (ef->type) { case A3DA_EVENT_MISC: default: e = new auth_3d_detail::Event(ef); break; case A3DA_EVENT_FILT: { if (!ef->param1.compare("WHITEIN") || !ef->param1.compare("WHITEOUT") || !ef->param1.compare("FADEIN") || !ef->param1.compare("FADEOUT")) e = new auth_3d_detail::EventFilterFade(ef); else if (!ef->param1.compare("TIMESTOP")) e = new auth_3d_detail::EventFilterTimeStop(ef); else e = new auth_3d_detail::Event(ef); break; } case A3DA_EVENT_FX: if (!ef->param1.compare("SMOOTH")) e = new auth_3d_detail::EventFXSmoothCut(ef); else e = new auth_3d_detail::EventFX(ef); break; case A3DA_EVENT_SND: e = new auth_3d_detail::EventSnd(ef); break; case A3DA_EVENT_MOT: e = new auth_3d_detail::EventMot(ef); break; case A3DA_EVENT_A2D: e = new auth_3d_detail::EventA2d(ef); break; } return e; } static void auth_3d_event_store(auth_3d* auth, auth_3d_detail::Event* e, auth_3d_event_file* ef) { } static const char* auth_3d_event_type_string(auth_3d_detail::Event::Type type) { switch (type) { case auth_3d_detail::Event::Type::MISC: return "MISC"; case auth_3d_detail::Event::Type::FILT: return "FLT"; case auth_3d_detail::Event::Type::FX: return "FX"; case auth_3d_detail::Event::Type::SND: return "SND"; case auth_3d_detail::Event::Type::MOT: return "MOT"; case auth_3d_detail::Event::Type::A2D: return "A2D"; default: return "(unknown)"; } } static void auth_3d_fog_load(auth_3d* auth, auth_3d_fog* f, auth_3d_fog_file* ff) { if (ff->flags & A3DA_FOG_COLOR) { auth_3d_rgba_load(auth, &f->color, &ff->color); enum_or(f->flags, AUTH_3D_FOG_COLOR); } if (ff->flags & A3DA_FOG_DENSITY) { auth_3d_key_load(auth, &f->density, &ff->density); enum_or(f->flags, AUTH_3D_FOG_DENSITY); } if (ff->flags & A3DA_FOG_END) { auth_3d_key_load(auth, &f->end, &ff->end); enum_or(f->flags, AUTH_3D_FOG_END); } f->id = ff->id; if (ff->flags & A3DA_FOG_START) { auth_3d_key_load(auth, &f->start, &ff->start); enum_or(f->flags, AUTH_3D_FOG_START); } } static void auth_3d_fog_restore_prev_value(auth_3d_fog* f, render_context* rctx) { fog_id id = f->id; if (id < FOG_DEPTH || id > FOG_BUMP) return; fog* data = &rctx->fog[id]; if (f->flags_init & AUTH_3D_FOG_COLOR) data->set_color(f->color_init); if (f->flags_init & AUTH_3D_FOG_DENSITY) data->set_density(f->density_value); if (f->flags_init & AUTH_3D_FOG_END) data->set_end(f->end_value); if (f->flags_init & AUTH_3D_FOG_START) data->set_start(f->start_value); } static void auth_3d_fog_set(auth_3d_fog* f, render_context* rctx) { fog_id id = f->id; if (id < FOG_DEPTH || id > FOG_BUMP) return; fog* data = &rctx->fog[id]; if (f->flags & AUTH_3D_FOG_COLOR) { if (!(f->flags_init & AUTH_3D_FOG_COLOR)) { vec4 color_init; data->get_color(color_init); f->color_init = color_init; enum_or(f->flags_init, AUTH_3D_FOG_COLOR); } data->set_color(f->color.value); } if (f->flags & AUTH_3D_FOG_DENSITY) { if (!(f->flags_init & AUTH_3D_FOG_DENSITY)) { f->density_init = data->get_density(); enum_or(f->flags_init, AUTH_3D_FOG_DENSITY); } data->set_density(f->density_value); } if (f->flags & AUTH_3D_FOG_END) { if (!(f->flags_init & AUTH_3D_FOG_END)) { f->end_init = data->get_end(); enum_or(f->flags_init, AUTH_3D_FOG_END); } data->set_end(f->end_value); } if (f->flags & AUTH_3D_FOG_START) { if (!(f->flags_init & AUTH_3D_FOG_START)) { f->start_init = data->get_start(); enum_or(f->flags_init, AUTH_3D_FOG_START); } data->set_start(f->start_value); } } static void auth_3d_fog_store(auth_3d* auth, auth_3d_fog* f, auth_3d_fog_file* ff) { if (f->flags & AUTH_3D_FOG_COLOR) { auth_3d_rgba_store(auth, &f->color, &ff->color); enum_or(ff->flags, A3DA_FOG_COLOR); } if (f->flags & AUTH_3D_FOG_DENSITY) { auth_3d_key_store(auth, &f->density, &ff->density); enum_or(ff->flags, A3DA_FOG_DENSITY); } if (f->flags & AUTH_3D_FOG_END) { auth_3d_key_store(auth, &f->end, &ff->end); enum_or(ff->flags, A3DA_FOG_END); } ff->id = f->id; if (f->flags & AUTH_3D_FOG_START) { auth_3d_key_store(auth, &f->start, &ff->start); enum_or(ff->flags, A3DA_FOG_START); } } static void auth_3d_light_load(auth_3d* auth, auth_3d_light* l, auth_3d_light_file* lf) { if (lf->flags & A3DA_LIGHT_AMBIENT) { auth_3d_rgba_load(auth, &l->ambient, &lf->ambient); enum_or(l->flags, AUTH_3D_LIGHT_AMBIENT); } if (lf->flags & A3DA_LIGHT_CONE_ANGLE) { auth_3d_key_load(auth, &l->cone_angle, &lf->cone_angle); enum_or(l->flags, AUTH_3D_LIGHT_CONE_ANGLE); } if (lf->flags & A3DA_LIGHT_CONSTANT) { auth_3d_key_load(auth, &l->constant, &lf->constant); enum_or(l->flags, AUTH_3D_LIGHT_CONSTANT); } if (lf->flags & A3DA_LIGHT_DIFFUSE) { auth_3d_rgba_load(auth, &l->diffuse, &lf->diffuse); enum_or(l->flags, AUTH_3D_LIGHT_DIFFUSE); } if (lf->flags & A3DA_LIGHT_DROP_OFF) { auth_3d_key_load(auth, &l->drop_off, &lf->drop_off); enum_or(l->flags, AUTH_3D_LIGHT_DROP_OFF); } if (lf->flags & A3DA_LIGHT_FAR) { auth_3d_key_load(auth, &l->_far, &lf->_far); enum_or(l->flags, AUTH_3D_LIGHT_FAR); } l->id = lf->id; if (lf->flags & A3DA_LIGHT_INTENSITY) { auth_3d_key_load(auth, &l->intensity, &lf->intensity); enum_or(l->flags, AUTH_3D_LIGHT_INTENSITY); } if (lf->flags & A3DA_LIGHT_LINEAR) { auth_3d_key_load(auth, &l->linear, &lf->linear); enum_or(l->flags, AUTH_3D_LIGHT_LINEAR); } if (lf->flags & A3DA_LIGHT_POSITION) { auth_3d_model_transform_load(auth, &l->position, &lf->position); enum_or(l->flags, AUTH_3D_LIGHT_POSITION); } if (lf->flags & A3DA_LIGHT_QUADRATIC) { auth_3d_key_load(auth, &l->quadratic, &lf->quadratic); enum_or(l->flags, AUTH_3D_LIGHT_QUADRATIC); } if (lf->flags & A3DA_LIGHT_SPECULAR) { auth_3d_rgba_load(auth, &l->specular, &lf->specular); enum_or(l->flags, AUTH_3D_LIGHT_SPECULAR); } if (lf->flags & A3DA_LIGHT_SPOT_DIRECTION) { auth_3d_model_transform_load(auth, &l->spot_direction, &lf->spot_direction); enum_or(l->flags, AUTH_3D_LIGHT_SPOT_DIRECTION); } if (lf->flags & A3DA_LIGHT_TONE_CURVE) { auth_3d_rgba_load(auth, &l->tone_curve, &lf->tone_curve); enum_or(l->flags, AUTH_3D_LIGHT_TONE_CURVE); } l->type.assign(lf->type); } static void auth_3d_light_restore_prev_value(auth_3d_light* l, render_context* rctx) { light_set* set = &rctx->light_set[LIGHT_SET_MAIN]; light_id id = l->id; if (id < LIGHT_CHARA || id > LIGHT_PROJECTION) return; light_data* data = &set->lights[id]; if (l->flags_init & AUTH_3D_LIGHT_AMBIENT) data->set_ambient(l->ambient_init); if (l->flags_init & AUTH_3D_LIGHT_DIFFUSE) data->set_diffuse(l->diffuse_init); if (l->flags_init & AUTH_3D_LIGHT_SPECULAR) data->set_specular(l->specular_init); if (l->flags_init & AUTH_3D_LIGHT_TONE_CURVE) data->set_tone_curve(l->tone_curve_init); } static void auth_3d_light_set(auth_3d_light* l, render_context* rctx) { light_set* set = &rctx->light_set[LIGHT_SET_MAIN]; light_id id = l->id; if (id < LIGHT_CHARA || id > LIGHT_PROJECTION) return; light_data* data = &set->lights[id]; if (l->flags & AUTH_3D_LIGHT_AMBIENT) { if (!(l->flags_init & AUTH_3D_LIGHT_AMBIENT)) { vec4 ambient_init; data->get_ambient(ambient_init); l->ambient_init = ambient_init; enum_or(l->flags_init, AUTH_3D_LIGHT_AMBIENT); } bool set[4]; set[0] = !!(l->ambient.flags & AUTH_3D_RGBA_R); set[1] = !!(l->ambient.flags & AUTH_3D_RGBA_G); set[2] = !!(l->ambient.flags & AUTH_3D_RGBA_B); set[3] = !!(l->ambient.flags & AUTH_3D_RGBA_A); data->set_ambient(l->ambient.value, set); } if (l->flags & AUTH_3D_LIGHT_DIFFUSE) { if (!(l->flags_init & AUTH_3D_LIGHT_DIFFUSE)) { vec4 diffuse_init; data->get_diffuse(diffuse_init); l->diffuse_init = diffuse_init; enum_or(l->flags_init, AUTH_3D_LIGHT_DIFFUSE); } bool set[4]; set[0] = !!(l->diffuse.flags & AUTH_3D_RGBA_R); set[1] = !!(l->diffuse.flags & AUTH_3D_RGBA_G); set[2] = !!(l->diffuse.flags & AUTH_3D_RGBA_B); set[3] = !!(l->diffuse.flags & AUTH_3D_RGBA_A); data->set_diffuse(l->diffuse.value, set); } if (l->flags & AUTH_3D_LIGHT_POSITION) data->set_position(l->position.translation_value); if (l->flags & AUTH_3D_LIGHT_SPECULAR) { if (!(l->flags_init & AUTH_3D_LIGHT_SPECULAR)) { vec4 specular_init; data->get_specular(specular_init); l->specular_init = specular_init; enum_or(l->flags_init, AUTH_3D_LIGHT_SPECULAR); } bool set[4]; set[0] = !!(l->specular.flags & AUTH_3D_RGBA_R); set[1] = !!(l->specular.flags & AUTH_3D_RGBA_G); set[2] = !!(l->specular.flags & AUTH_3D_RGBA_B); set[3] = !!(l->specular.flags & AUTH_3D_RGBA_A); data->set_specular(l->specular.value, set); } if (l->flags & AUTH_3D_LIGHT_SPOT_DIRECTION) data->set_spot_direction(l->spot_direction.translation_value); if (l->flags & AUTH_3D_LIGHT_TONE_CURVE) { if (!(l->flags_init & AUTH_3D_LIGHT_TONE_CURVE)) { data->get_tone_curve(l->tone_curve_init); enum_or(l->flags_init, AUTH_3D_LIGHT_TONE_CURVE); } light_tone_curve tone_curve; tone_curve.start_point = l->tone_curve.value.x; tone_curve.end_point = l->tone_curve.value.y; tone_curve.coefficient = l->tone_curve.value.z; data->set_tone_curve(tone_curve); } } static void auth_3d_light_store(auth_3d* auth, auth_3d_light* l, auth_3d_light_file* lf) { if (l->flags & AUTH_3D_LIGHT_AMBIENT) { auth_3d_rgba_store(auth, &l->ambient, &lf->ambient); enum_or(lf->flags, A3DA_LIGHT_AMBIENT); } if (l->flags & AUTH_3D_LIGHT_CONE_ANGLE) { auth_3d_key_store(auth, &l->cone_angle, &lf->cone_angle); enum_or(lf->flags, A3DA_LIGHT_CONE_ANGLE); } if (l->flags & AUTH_3D_LIGHT_CONSTANT) { auth_3d_key_store(auth, &l->constant, &lf->constant); enum_or(lf->flags, A3DA_LIGHT_CONSTANT); } if (l->flags & AUTH_3D_LIGHT_DIFFUSE) { auth_3d_rgba_store(auth, &l->diffuse, &lf->diffuse); enum_or(lf->flags, A3DA_LIGHT_DIFFUSE); } if (l->flags & AUTH_3D_LIGHT_DROP_OFF) { auth_3d_key_store(auth, &l->drop_off, &lf->drop_off); enum_or(lf->flags, A3DA_LIGHT_DROP_OFF); } if (l->flags & AUTH_3D_LIGHT_FAR) { auth_3d_key_store(auth, &l->_far, &lf->_far); enum_or(lf->flags, A3DA_LIGHT_FAR); } lf->id = l->id; if (l->flags & AUTH_3D_LIGHT_INTENSITY) { auth_3d_key_store(auth, &l->intensity, &lf->intensity); enum_or(lf->flags, A3DA_LIGHT_INTENSITY); } if (l->flags & AUTH_3D_LIGHT_LINEAR) { auth_3d_key_store(auth, &l->linear, &lf->linear); enum_or(lf->flags, A3DA_LIGHT_LINEAR); } if (l->flags & AUTH_3D_LIGHT_POSITION) { auth_3d_model_transform_store(auth, &l->position, &lf->position); enum_or(lf->flags, A3DA_LIGHT_POSITION); } if (l->flags & AUTH_3D_LIGHT_QUADRATIC) { auth_3d_key_store(auth, &l->quadratic, &lf->quadratic); enum_or(lf->flags, A3DA_LIGHT_QUADRATIC); } if (l->flags & AUTH_3D_LIGHT_SPECULAR) { auth_3d_rgba_store(auth, &l->specular, &lf->specular); enum_or(lf->flags, A3DA_LIGHT_SPECULAR); } if (l->flags & AUTH_3D_LIGHT_SPOT_DIRECTION) { auth_3d_model_transform_store(auth, &l->spot_direction, &lf->spot_direction); enum_or(lf->flags, A3DA_LIGHT_SPOT_DIRECTION); } if (l->flags & AUTH_3D_LIGHT_TONE_CURVE) { auth_3d_rgba_store(auth, &l->tone_curve, &lf->tone_curve); enum_or(lf->flags, A3DA_LIGHT_TONE_CURVE); } lf->type.assign(l->type); } static void auth_3d_m_object_hrc_get_mat(auth_3d_m_object_hrc* moh, mat4* mat) { for (auth_3d_object_node& i : moh->node) if (i.mat) { *mat = *i.mat; return; } *mat = moh->node.front().model_transform.mat; } static void auth_3d_m_object_hrc_disp(auth_3d_m_object_hrc* moh, auth_3d* auth, render_context* rctx) { if (!auth->visible || !moh->model_transform.visible) return; mdl::DispManager& disp_manager = *rctx->disp_manager; for (auth_3d_object_instance& i : moh->instance) { if (!i.model_transform.visible) continue; mdl::ObjFlags flags = mdl::OBJ_SSS; shadow_type_enum shadow_type = SHADOW_CHARA; if (auth->shadow || i.shadow) { enum_or(flags, mdl::OBJ_4 | mdl::OBJ_SHADOW); shadow_type = SHADOW_STAGE; } if (auth->alpha < 1.0f) enum_or(flags, auth->obj_flags); disp_manager.set_obj_flags(flags); disp_manager.set_shadow_type(shadow_type); Shadow* shad = shadow_ptr_get(); if (shad && (flags & mdl::OBJ_SHADOW)) { disp_manager.set_shadow_type(SHADOW_STAGE); mat4* m = &moh->model_transform.mat; for (auth_3d_object_node& j : moh->node) if (j.mat) { m = j.mat; break; } mat4 mat = i.model_transform.mat; mat4_mul(&mat, m, &mat); vec3 pos = *(vec3*)&mat.row3; pos.y -= 0.2f; shad->field_1D0[shadow_type].push_back(pos); } if (i.mats.size()) disp_manager.entry_obj_by_object_info_object_skin( i.object_info, 0, 0, auth->alpha, i.mats.data(), 0, 0, &i.model_transform.mat); } disp_manager.set_obj_flags(); disp_manager.set_shadow_type(SHADOW_CHARA); } static void auth_3d_m_object_hrc_load(auth_3d* auth, auth_3d_m_object_hrc* moh, auth_3d_m_object_hrc_file* mohf, object_database* obj_db) { size_t node_index = 0; moh->node.resize(mohf->node.size()); for (auth_3d_object_node_file& i : mohf->node) auth_3d_object_node_load(auth, &moh->node[node_index++], &i); auth_3d_object_model_transform_load(auth, &moh->model_transform, &mohf->model_transform); moh->name.assign(mohf->name); size_t instance_index = 0; moh->instance.resize(mohf->instance.size()); for (auth_3d_object_instance_file& i : mohf->instance) auth_3d_object_instance_load(auth, &moh->instance[instance_index++], &i, moh, obj_db); } static void auth_3d_m_object_hrc_nodes_mat_mult(auth_3d_m_object_hrc* moh) { auth_3d_object_node* node = moh->node.data(); for (auth_3d_object_node& i : moh->node) if (i.parent >= 0) i.model_transform.mat_mult(&node[i.parent].model_transform.mat); else i.model_transform.mat = i.model_transform.mat_inner; } static void auth_3d_m_object_hrc_store(auth_3d* auth, auth_3d_m_object_hrc* moh, auth_3d_m_object_hrc_file* mohf) { size_t node_index = 0; mohf->node.resize(moh->node.size()); for (auth_3d_object_node& i : moh->node) auth_3d_object_node_store(auth, &i, &mohf->node[node_index++]); auth_3d_object_model_transform_store(auth, &moh->model_transform, &mohf->model_transform); mohf->name.assign(moh->name); size_t instance_index = 0; mohf->instance.resize(moh->instance.size()); for (auth_3d_object_instance& i : moh->instance) auth_3d_object_instance_store(auth, &i, &mohf->instance[instance_index++], moh); } static void auth_3d_material_list_load(auth_3d* auth, auth_3d_material_list* ml, auth_3d_material_list_file* mlf) { //int32_t ident[24] = {}; if (mlf->flags & A3DA_MATERIAL_LIST_BLEND_COLOR) { auth_3d_rgba_load(auth, &ml->blend_color, &mlf->blend_color); enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_BLEND_COLOR); /*auth_3d_key& r = ml->blend_color.r; auth_3d_key& g = ml->blend_color.g; auth_3d_key& b = ml->blend_color.b; auth_3d_key& a = ml->blend_color.a; switch (r.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[0] = 1; ident[6] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[0] = 1; ident[6] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (r.length == g.length) { ident[0] = 1; kft3* keys1 = r.keys; kft3* keys2 = g.keys; size_t length = r.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[0] = 0; break; } if (ident[0]) { ident[6] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[6] = 0; break; } } } else if (r.length > g.length) { if (g.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = r.keys; kft3* keys2 = g.keys; size_t keys1_length = r.length; size_t keys2_length = g.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[0] = 1; ident[6] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[0] = 1; ident[6] = 1; } break; } } } } else if (r.length < g.length) { if (r.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = g.keys; kft3* keys2 = r.keys; size_t keys1_length = g.length; size_t keys2_length = r.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[0] = 1; ident[6] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[0] = 1; ident[6] = 1; } break; } } } } break; } break; } switch (r.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[1] = 1; ident[7] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[1] = 1; ident[7] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (r.length == b.length) { ident[1] = 1; kft3* keys1 = r.keys; kft3* keys2 = b.keys; size_t length = r.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[1] = 0; break; } if (ident[1]) { ident[7] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[7] = 0; break; } } } else if (r.length > b.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = r.keys; kft3* keys2 = b.keys; size_t keys1_length = r.length; size_t keys2_length = b.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[1] = 1; ident[7] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[1] = 1; ident[7] = 1; } break; } } } } else if (r.length < b.length) { if (r.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = b.keys; kft3* keys2 = r.keys; size_t keys1_length = b.length; size_t keys2_length = r.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[1] = 1; ident[7] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[1] = 1; ident[7] = 1; } break; } } } } break; } break; } switch (r.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[2] = 1; ident[8] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[2] = 1; ident[8] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (r.length == a.length) { ident[2] = 1; kft3* keys1 = r.keys; kft3* keys2 = a.keys; size_t length = r.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[2] = 0; break; } if (ident[2]) { ident[8] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[8] = 0; break; } } } else if (r.length > a.length) { if (a.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = r.keys; kft3* keys2 = a.keys; size_t keys1_length = r.length; size_t keys2_length = a.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[2] = 1; ident[8] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[2] = 1; ident[8] = 1; } break; } } } } else if (r.length < a.length) { if (r.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = a.keys; kft3* keys2 = r.keys; size_t keys1_length = a.length; size_t keys2_length = r.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[2] = 1; ident[8] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[2] = 1; ident[8] = 1; } break; } } } } break; } break; } switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[3] = 1; ident[9] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[3] = 1; ident[9] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (g.length == b.length) { ident[3] = 1; kft3* keys1 = g.keys; kft3* keys2 = b.keys; size_t length = g.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[3] = 0; break; } if (ident[3]) { ident[9] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[9] = 0; break; } } } else if (g.length > b.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = g.keys; kft3* keys2 = b.keys; size_t keys1_length = g.length; size_t keys2_length = b.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[3] = 1; ident[9] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[3] = 1; ident[9] = 1; } break; } } } } else if (g.length < b.length) { if (g.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = b.keys; kft3* keys2 = g.keys; size_t keys1_length = b.length; size_t keys2_length = g.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[3] = 1; ident[9] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[3] = 1; ident[9] = 1; } break; } } } } break; } break; } switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[4] = 1; ident[10] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[4] = 1; ident[10] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (g.length == a.length) { ident[4] = 1; kft3* keys1 = g.keys; kft3* keys2 = a.keys; size_t length = g.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[4] = 0; break; } if (ident[4]) { ident[10] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[10] = 0; break; } } } else if (g.length > a.length) { if (a.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = g.keys; kft3* keys2 = a.keys; size_t keys1_length = g.length; size_t keys2_length = a.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[4] = 1; ident[10] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[4] = 1; ident[10] = 1; } break; } } } } else if (g.length < a.length) { if (g.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = a.keys; kft3* keys2 = g.keys; size_t keys1_length = a.length; size_t keys2_length = g.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[4] = 1; ident[10] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[4] = 1; ident[10] = 1; } break; } } } } break; } break; } switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[5] = 1; ident[11] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[5] = 1; ident[11] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (b.length == a.length) { ident[5] = 1; kft3* keys1 = b.keys; kft3* keys2 = a.keys; size_t length = b.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[5] = 0; break; } if (ident[5]) { ident[11] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[11] = 0; break; } } } else if (b.length > a.length) { if (a.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = b.keys; kft3* keys2 = a.keys; size_t keys1_length = b.length; size_t keys2_length = a.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[5] = 1; ident[11] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[5] = 1; ident[11] = 1; } break; } } } } else if (b.length < a.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = a.keys; kft3* keys2 = b.keys; size_t keys1_length = a.length; size_t keys2_length = b.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[5] = 1; ident[11] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[5] = 1; ident[11] = 1; } break; } } } } break; } break; }*/ } if (mlf->flags & A3DA_MATERIAL_LIST_GLOW_INTENSITY) { auth_3d_key_load(auth, &ml->glow_intensity, &mlf->glow_intensity); enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_GLOW_INTENSITY); } if (mlf->flags & A3DA_MATERIAL_LIST_EMISSION) { auth_3d_rgba_load(auth, &ml->emission, &mlf->emission); enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_EMISSION); /*auth_3d_key& r = ml->emission.r; auth_3d_key& g = ml->emission.g; auth_3d_key& b = ml->emission.b; auth_3d_key& a = ml->emission.a; switch (r.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[12] = 1; ident[18] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[12] = 1; ident[18] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (r.length == g.length) { ident[12] = 1; kft3* keys1 = r.keys; kft3* keys2 = g.keys; size_t length = r.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[12] = 0; break; } if (ident[12]) { ident[18] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[18] = 0; break; } } } else if (b.length > a.length) { if (a.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = b.keys; kft3* keys2 = a.keys; size_t keys1_length = b.length; size_t keys2_length = a.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[12] = 1; ident[18] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[12] = 1; ident[18] = 1; } break; } } } } else if (b.length < a.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = a.keys; kft3* keys2 = b.keys; size_t keys1_length = a.length; size_t keys2_length = b.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[12] = 1; ident[18] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[12] = 1; ident[18] = 1; } break; } } } } break; } break; } switch (r.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[13] = 1; ident[19] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[13] = 1; ident[19] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (r.length == b.length) { ident[13] = 1; kft3* keys1 = r.keys; kft3* keys2 = b.keys; size_t length = r.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[13] = 0; break; } if (ident[13]) { ident[19] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[19] = 0; break; } } } else if (r.length > b.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = r.keys; kft3* keys2 = b.keys; size_t keys1_length = r.length; size_t keys2_length = b.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[13] = 1; ident[19] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[13] = 1; ident[19] = 1; } break; } } } } else if (r.length < b.length) { if (r.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = b.keys; kft3* keys2 = r.keys; size_t keys1_length = b.length; size_t keys2_length = r.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[13] = 1; ident[19] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[13] = 1; ident[19] = 1; } break; } } } } break; } break; } switch (r.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[14] = 1; ident[20] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[14] = 1; ident[20] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (r.length == a.length) { ident[14] = 1; kft3* keys1 = r.keys; kft3* keys2 = a.keys; size_t length = r.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[14] = 0; break; } if (ident[14]) { ident[20] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[20] = 0; break; } } } else if (r.length > a.length) { if (a.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = r.keys; kft3* keys2 = a.keys; size_t keys1_length = r.length; size_t keys2_length = a.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[14] = 1; ident[20] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[14] = 1; ident[20] = 1; } break; } } } } else if (r.length < a.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = a.keys; kft3* keys2 = r.keys; size_t keys1_length = a.length; size_t keys2_length = r.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[14] = 1; ident[20] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[14] = 1; ident[20] = 1; } break; } } } } break; } break; } switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[15] = 1; ident[21] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[15] = 1; ident[21] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (g.length == b.length) { ident[15] = 1; kft3* keys1 = g.keys; kft3* keys2 = b.keys; size_t length = g.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[15] = 0; break; } if (ident[15]) { ident[21] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[21] = 0; break; } } } else if (g.length > b.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = g.keys; kft3* keys2 = b.keys; size_t keys1_length = g.length; size_t keys2_length = b.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[15] = 1; ident[21] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[15] = 1; ident[21] = 1; } break; } } } } else if (g.length < b.length) { if (g.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = b.keys; kft3* keys2 = g.keys; size_t keys1_length = b.length; size_t keys2_length = g.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[15] = 1; ident[21] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[15] = 1; ident[21] = 1; } break; } } } } break; } break; } switch (g.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[16] = 1; ident[22] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[16] = 1; ident[22] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (g.length == a.length) { ident[16] = 1; kft3* keys1 = g.keys; kft3* keys2 = a.keys; size_t length = g.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[16] = 0; break; } if (ident[16]) { ident[22] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[22] = 0; break; } } } else if (g.length > a.length) { if (a.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = g.keys; kft3* keys2 = a.keys; size_t keys1_length = g.length; size_t keys2_length = a.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[16] = 1; ident[22] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[16] = 1; ident[22] = 1; } break; } } } } else if (g.length < a.length) { if (g.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = a.keys; kft3* keys2 = g.keys; size_t keys1_length = a.length; size_t keys2_length = g.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[16] = 1; ident[22] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[16] = 1; ident[22] = 1; } break; } } } } break; } break; } switch (b.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: ident[17] = 1; ident[23] = 1; break; } break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: switch (a.type) { case AUTH_3D_KEY_NONE: case AUTH_3D_KEY_STATIC: ident[17] = 1; ident[23] = 1; break; case AUTH_3D_KEY_LINEAR: case AUTH_3D_KEY_HERMITE: case AUTH_3D_KEY_HOLD: if (b.length == a.length) { ident[17] = 1; kft3* keys1 = b.keys; kft3* keys2 = a.keys; size_t length = b.length; for (size_t i = 0; i < length; i++) if (*(uint32_t*)&keys1[i].frame != *(uint32_t*)&keys2[i].frame) { ident[17] = 0; break; } if (ident[17]) { ident[23] = 1; for (size_t i = 0; i < length; i++) if (*(uint64_t*)&keys1[i].tangent1 != *(uint64_t*)&keys2[i].tangent1) { ident[23] = 0; break; } } } else if (b.length > a.length) { if (a.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = b.keys; kft3* keys2 = a.keys; size_t keys1_length = b.length; size_t keys2_length = a.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[17] = 1; ident[23] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[17] = 1; ident[23] = 1; } break; } } } } else if (b.length < a.length) { if (b.type == AUTH_3D_KEY_LINEAR) { kft3* keys1 = a.keys; kft3* keys2 = b.keys; size_t keys1_length = a.length; size_t keys2_length = b.length; for (size_t i = 0; i < keys1_length; i++) { float_t frame = keys1[i].frame; bool found = false; for (size_t j = 0; j < keys2_length && i < keys1_length; j++) if (frame == keys2[j].frame) { found = true; break; } if (!found) if (frame <= keys2[0].frame || frame >= keys2[keys2_length - 1].frame) { ident[17] = 1; ident[23] = 1; } else for (size_t j = 0; j + 1 < keys2_length && i < keys1_length; j++) if (frame >= keys2[j].frame && keys2[j + 1].frame) { if (*(uint32_t*)&keys2[j].value == *(uint32_t*)&keys2[j + 1].value) { ident[17] = 1; ident[23] = 1; } break; } } } } break; } break; }*/ } /*OutputDebugStringA(auth->file_name.c_str()); OutputDebugStringA("\n"); OutputDebugStringA(mlf->name.c_str()); OutputDebugStringA("\n"); if (ml->flags & AUTH_3D_MATERIAL_LIST_BLEND_COLOR) { if ((ident[0] || ident[1] || ident[2] || ident[4] || ident[5] || ident[6]) && (!ident[0] || !ident[1] || !ident[2] || !ident[4] || !ident[5] || !ident[6])) OutputDebugStringA("A\n"); if (!(ident[0] || ident[1] || ident[2] || ident[3] || ident[4] || ident[5])) OutputDebugStringA("B\n"); if (ident[0] || ident[1] || ident[2] || ident[3] || ident[4] || ident[5]) { if ((ident[6] || ident[7] || ident[8] || ident[9] || ident[10] || ident[11]) && (!ident[6] || !ident[7] || !ident[8] || !ident[9] || !ident[10] || !ident[11])) OutputDebugStringA("C\n"); if (!(ident[6] || ident[7] || ident[8] || ident[9] || ident[10] || ident[11])) OutputDebugStringA("D\n"); } } if (ml->flags & AUTH_3D_MATERIAL_LIST_EMISSION) { if ((ident[12] || ident[13] || ident[14] || ident[15] || ident[16] || ident[17]) && (!ident[12] || !ident[13] || !ident[14] || !ident[15] || !ident[16] || !ident[17])) OutputDebugStringA("E\n"); if (!(ident[12] || ident[13] || ident[14] || ident[15] || ident[16] || ident[17])) OutputDebugStringA("F\n"); if (ident[12] || ident[13] || ident[14] || ident[15] || ident[16] || ident[17]) { if ((ident[18] || ident[19] || ident[20] || ident[21] || ident[22] || ident[23]) && (!ident[18] || !ident[19] || !ident[20] || !ident[21] || !ident[22] || !ident[23])) OutputDebugStringA("G\n"); if (!(ident[18] || ident[19] || ident[20] || ident[21] || ident[22] || ident[23])) OutputDebugStringA("H\n"); } }*/ ml->name.assign(mlf->name); ml->hash = hash_string_murmurhash(ml->name); /*char buf[0x200]; sprintf_s(buf, sizeof(buf), "\n%d %d %d %d %d %d %d %d %d %d %d %d\n" "%d %d %d %d %d %d %d %d %d %d %d %d\n\n", ident[0], ident[1], ident[2], ident[3], ident[4], ident[5], ident[6], ident[7], ident[8], ident[9], ident[10], ident[11], ident[12], ident[13], ident[14], ident[15], ident[16], ident[17], ident[18], ident[19], ident[20], ident[21], ident[22], ident[23]); OutputDebugStringA(buf);*/ } static void auth_3d_material_list_store(auth_3d* auth, auth_3d_material_list* ml, auth_3d_material_list_file* mlf) { if (ml->flags & AUTH_3D_MATERIAL_LIST_BLEND_COLOR) { auth_3d_rgba_store(auth, &ml->blend_color, &mlf->blend_color); enum_or(mlf->flags, A3DA_MATERIAL_LIST_BLEND_COLOR); } if (ml->flags & AUTH_3D_MATERIAL_LIST_GLOW_INTENSITY) { auth_3d_key_store(auth, &ml->glow_intensity, &mlf->glow_intensity); enum_or(mlf->flags, A3DA_MATERIAL_LIST_GLOW_INTENSITY); } if (ml->flags & AUTH_3D_MATERIAL_LIST_EMISSION) { auth_3d_rgba_store(auth, &ml->emission, &mlf->emission); enum_or(mlf->flags, A3DA_MATERIAL_LIST_EMISSION); } mlf->name.assign(ml->name); } static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context* rctx) { if (!o->model_transform.visible) return; if (!auth->visible) { if (auth->pos) spr::put_rgb_cross(o->model_transform.mat); for (auth_3d_object*& i : o->children_object) auth_3d_object_disp(i, auth, rctx); for (auth_3d_object_hrc*& i : o->children_object_hrc) auth_3d_object_hrc_disp(i, auth, rctx); return; } mat4 mat = o->model_transform.mat; mdl::DispManager& disp_manager = *rctx->disp_manager; object_database* obj_db = auth->obj_db; texture_database* tex_db = auth->tex_db; if (auth->chara_id >= 0 && auth->chara_id < ROB_CHARA_COUNT) if (rob_chara_pv_data_array_check_chara_id(auth->chara_id)) { rob_chara* rob_chr = rob_chara_array_get(auth->chara_id); mat4 m; mat4_mul(&rob_chr->data.miku_rot.field_6C, auth->chara_item ? &rob_chr->data.adjust_data.item_mat : &rob_chr->data.adjust_data.mat, &m); mat4_mul(&m, &mat, &mat); disp_manager.set_shadow_type(auth->chara_id ? SHADOW_STAGE : SHADOW_CHARA); } mdl::ObjFlags flags = (mdl::ObjFlags)0; if (auth->shadow) enum_or(flags, mdl::OBJ_4 | mdl::OBJ_SHADOW); if (o->reflect) enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFLECT); if (o->refract) enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFRACT); disp_manager.set_obj_flags(flags); char buf[0x80]; int32_t tex_pat_count = 0; texture_pattern_struct tex_pat[TEXTURE_PATTERN_COUNT]; for (auth_3d_object_texture_pattern& i : o->texture_pattern) { if (!i.pattern.curve || i.name.size() <= 3) continue; else if (tex_pat_count >= TEXTURE_PATTERN_COUNT) break; sprintf_s(buf, sizeof(buf), "%.*s%03d", (int32_t)(i.name.size() - 3), i.name.c_str(), (int32_t)prj::roundf(i.pattern.value)); tex_pat[tex_pat_count].src = texture_id(0x00, i.texture_id); tex_pat[tex_pat_count].dst = texture_id(0x00, tex_db->get_texture_id(buf)); tex_pat_count++; } if (tex_pat_count) disp_manager.set_texture_pattern(tex_pat_count, tex_pat); int32_t tex_trans_count = 0; texture_transform_struct tex_trans[TEXTURE_TRANSFORM_COUNT]; for (auth_3d_object_texture_transform& i : o->texture_transform) { if (tex_trans_count >= TEXTURE_TRANSFORM_COUNT || i.texture_id == -1 || !texture_manager_get_texture(i.texture_id)) continue; tex_trans[tex_trans_count].id = i.texture_id; tex_trans[tex_trans_count].mat = i.mat; tex_trans_count++; } if (tex_trans_count) disp_manager.set_texture_transform(tex_trans_count, tex_trans); const char* uid_name = o->uid_name.c_str(); int32_t uid_name_length = (int32_t)o->uid_name.size(); if (uid_name_length <= 3) disp_manager.entry_obj_by_object_info(&mat, o->object_info); else if (o->morph.curve) { float_t morph = o->morph.value; int32_t morph_int = (int32_t)morph; morph = fmodf(morph, 1.0f); if (morph > 0.0f && morph < 1.0f) { sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int + 1); object_info morph_obj_info = obj_db->get_object_info(buf); if (morph_obj_info.is_null()) morph_obj_info = o->object_info; disp_manager.set_morph(morph_obj_info, morph); sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int); object_info obj_info = obj_db->get_object_info(buf); if (auth->alpha < 0.999f) disp_manager.entry_obj_by_object_info(&mat, obj_info, auth->alpha); else disp_manager.entry_obj_by_object_info(&mat, obj_info); disp_manager.set_morph({}, 0.0f); } else { if (morph >= 1.0f) morph_int++; sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int); object_info obj_info = obj_db->get_object_info(buf); if (obj_info.is_null()) obj_info = o->object_info; disp_manager.entry_obj_by_object_info(&mat, obj_info); } } else if (o->pattern.curve) { sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, (int32_t)prj::roundf(o->pattern.value)); object_info obj_info = obj_db->get_object_info(buf); disp_manager.entry_obj_by_object_info(&mat, obj_info); } else disp_manager.entry_obj_by_object_info(&mat, o->object_info); disp_manager.set_texture_transform(); disp_manager.set_texture_pattern(); disp_manager.set_obj_flags(); if (auth->pos) spr::put_rgb_cross(o->model_transform.mat); for (auth_3d_object*& i : o->children_object) auth_3d_object_disp(i, auth, rctx); for (auth_3d_object_hrc*& i : o->children_object_hrc) auth_3d_object_hrc_disp(i, auth, rctx); } static void auth_3d_object_load(auth_3d* auth, auth_3d_object* o, auth_3d_object_file* of, object_database* obj_db, texture_database* tex_db) { auth_3d_model_transform_load(auth, &o->model_transform, &of->model_transform); auth_3d_object_curve_load(auth, &o->morph, of->morph, of->morph_offset); o->name.assign(of->name); o->parent_name.assign(of->parent_name); o->parent_node.assign(of->parent_node); auth_3d_object_curve_load(auth, &o->pattern, of->pattern, of->pattern_offset); size_t texture_pattern_index = 0; o->texture_pattern.resize(of->texture_pattern.size()); for (auth_3d_object_texture_pattern_file& i : of->texture_pattern) auth_3d_object_texture_pattern_load(auth, &o->texture_pattern[texture_pattern_index++], &i, tex_db); size_t texture_transform_index = 0; o->texture_transform.resize(of->texture_transform.size()); for (auth_3d_object_texture_transform_file& i : of->texture_transform) auth_3d_object_texture_transform_load(auth, &o->texture_transform[texture_transform_index++], &i, tex_db); o->uid_name.assign(of->uid_name); o->reflect = strstr(o->uid_name.c_str(), "_REFLECT") ? true : false; o->refract = strstr(o->uid_name.c_str(), "_REFRACT") ? true : false; o->object_info = obj_db->get_object_info(o->uid_name.c_str()); o->object_hash = hash_string_murmurhash(o->uid_name); } static void auth_3d_object_store(auth_3d* auth, auth_3d_object* o, auth_3d_object_file* of) { auth_3d_model_transform_store(auth, &o->model_transform, &of->model_transform); auth_3d_object_curve_store(auth, &o->morph, of->morph, of->morph_offset); of->name.assign(o->name); of->parent_name.assign(o->parent_name); of->parent_node.assign(o->parent_node); auth_3d_object_curve_store(auth, &o->pattern, of->pattern, of->pattern_offset); size_t texture_pattern_index = 0; of->texture_pattern.resize(o->texture_pattern.size()); for (auth_3d_object_texture_pattern& i : o->texture_pattern) auth_3d_object_texture_pattern_store(auth, &i, &of->texture_pattern[texture_pattern_index++]); size_t texture_transform_index = 0; of->texture_transform.resize(o->texture_transform.size()); for (auth_3d_object_texture_transform& i : o->texture_transform) auth_3d_object_texture_transform_store(auth, &i, &of->texture_transform[texture_transform_index++]); of->uid_name.assign(o->uid_name); } static void auth_3d_object_curve_load(auth_3d* auth, auth_3d_object_curve* oc, std::string& name, float_t frame_offset) { if (!name.size()) return; oc->curve = 0; oc->name.assign(name); oc->frame_offset = 0.0f; oc->value = 0.0f; for (auth_3d_curve& i : auth->curve) if (!oc->name.compare(i.name)) { oc->curve = &i; oc->frame_offset = frame_offset; break; } } static void auth_3d_object_curve_store(auth_3d* auth, auth_3d_object_curve* oc, std::string& name, float_t& frame_offset) { name.assign(oc->name); frame_offset = oc->frame_offset; } static void auth_3d_object_hrc_disp(auth_3d_object_hrc* oh, auth_3d* auth, render_context* rctx) { if (!auth->visible || !oh->node.front().model_transform.visible) return; mdl::DispManager& disp_manager = *rctx->disp_manager; object_database* obj_db = auth->obj_db; texture_database* tex_db = auth->tex_db; mdl::ObjFlags flags = mdl::OBJ_SSS; if (auth->shadow | oh->shadow) enum_or(flags, mdl::OBJ_4 | mdl::OBJ_SHADOW); if (oh->reflect) enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFLECT); if (oh->refract) enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFRACT); if (auth->alpha < 1.0f) enum_or(flags, auth->obj_flags); disp_manager.set_obj_flags(flags); disp_manager.set_shadow_type(SHADOW_CHARA); mat4 mat = mat4_identity; if (auth->chara_id >= 0 && auth->chara_id < ROB_CHARA_COUNT) { if (rob_chara_pv_data_array_check_chara_id(auth->chara_id)) { rob_chara* rob_chr = rob_chara_array_get(auth->chara_id); mat4_mul(&rob_chr->data.miku_rot.field_6C, auth->chara_item ? &rob_chr->data.adjust_data.item_mat : &rob_chr->data.adjust_data.mat, &mat); if (auth->chara_id) disp_manager.set_shadow_type(SHADOW_STAGE); } } else if (flags & mdl::OBJ_SHADOW) { disp_manager.set_shadow_type(SHADOW_STAGE); mat4 mat = oh->node.front().model_transform.mat; for (auth_3d_object_node& i : oh->node) if (i.mat) { mat = *i.mat; break; } Shadow* shad = shadow_ptr_get(); if (shad) { vec3 pos; mat4_get_translation(&mat, &pos); pos.y -= 0.2f; shad->field_1D0[SHADOW_STAGE].push_back(pos); } } if (oh->mats.size()) disp_manager.entry_obj_by_object_info_object_skin( oh->object_info, 0, 0, auth->alpha, oh->mats.data(), 0, 0, &mat); disp_manager.set_obj_flags(); disp_manager.set_shadow_type(SHADOW_CHARA); for (auth_3d_object*& i : oh->children_object) auth_3d_object_disp(i, auth, rctx); for (auth_3d_object_hrc*& i : oh->children_object_hrc) auth_3d_object_hrc_disp(i, auth, rctx); } static void auth_3d_object_hrc_load(auth_3d* auth, auth_3d_object_hrc* oh, auth_3d_object_hrc_file* ohf, object_database* obj_db) { oh->name.assign(ohf->name); size_t node_index = 0; oh->node.resize(ohf->node.size()); for (auth_3d_object_node_file& i : ohf->node) auth_3d_object_node_load(auth, &oh->node[node_index++], &i); oh->parent_name.assign(ohf->parent_name); oh->parent_node.assign(ohf->parent_node); oh->shadow = ohf->shadow; oh->uid_name.assign(ohf->uid_name); oh->reflect = strstr(oh->uid_name.c_str(), "_REFLECT") ? true : false; oh->refract = strstr(oh->uid_name.c_str(), "_REFRACT") ? true : false; oh->object_info = obj_db->get_object_info(oh->uid_name.c_str()); oh->object_hash = hash_string_murmurhash(oh->uid_name); obj_skin* skin = objset_info_storage_get_obj_skin(oh->object_info); if (!skin) return; oh->mats.resize(skin->num_bone); mat4* mats = oh->mats.data(); for (auth_3d_object_node& i : oh->node) { i.bone_id = -1; uint64_t name_hash = hash_string_xxh3_64bits(i.name); for (int32_t j = 0; j < skin->num_bone; j++) if (hash_utf8_xxh3_64bits(skin->bone_array[j].name) == name_hash) { i.bone_id = skin->bone_array[j].id; break; } if (i.bone_id > -1 && !(i.bone_id & 0x8000)) i.mat = &mats[i.bone_id]; } } static void auth_3d_object_hrc_store(auth_3d* auth, auth_3d_object_hrc* oh, auth_3d_object_hrc_file* ohf) { ohf->name.assign(oh->name); size_t node_index = 0; ohf->node.resize(oh->node.size()); for (auth_3d_object_node& i : oh->node) auth_3d_object_node_store(auth, &i, &ohf->node[node_index++]); ohf->parent_name.assign(oh->parent_name); ohf->parent_node.assign(oh->parent_node); ohf->shadow = oh->shadow; ohf->uid_name.assign(oh->uid_name); } static bool auth_3d_object_hrc_replace_chara(auth_3d_object_hrc* oh, chara_index src_chara, chara_index dst_chara, object_database* obj_db) { if (src_chara < 0 || src_chara >= CHARA_MAX || dst_chara < 0 || dst_chara >= CHARA_MAX || src_chara == dst_chara) return false; std::string src_chara_str = chara_index_get_auth_3d_name(src_chara); std::string dst_chara_str = chara_index_get_auth_3d_name(dst_chara); std::string uid_name = oh->uid_name; size_t pos = uid_name.find(src_chara_str); if (pos != -1) uid_name.assign(uid_name.replace(pos, src_chara_str.size(), dst_chara_str)); object_info obj_info = obj_db->get_object_info(uid_name.c_str()); if (obj_info.not_null()) { oh->object_info = obj_info; return true; } return false; } static void auth_3d_object_hrc_nodes_mat_mult(auth_3d_object_hrc* oh, const mat4* mat) { for (auth_3d_object_node& i : oh->node) { mat4 m; if (i.parent >= 0) m = oh->node[i.parent].model_transform.mat; else m = *mat; mat4_mul(&i.joint_orient_mat, &m, &m); i.model_transform.mat_mult(&m); if (i.mat) *i.mat = i.model_transform.mat; } } static void auth_3d_object_instance_load(auth_3d* auth, auth_3d_object_instance* oi, auth_3d_object_instance_file* oif, auth_3d_m_object_hrc* moh, object_database* obj_db) { auth_3d_object_model_transform_load(auth, &oi->model_transform, &oif->model_transform); oi->name.assign(oif->name); oi->shadow = oif->shadow; oi->uid_name.assign(oif->uid_name); oi->object_info = obj_db->get_object_info(oi->uid_name.c_str()); oi->object_hash = hash_string_murmurhash(oi->uid_name); obj_skin* skin = objset_info_storage_get_obj_skin(oi->object_info); if (!skin) return; oi->object_bone_indices.resize(skin->num_bone); int32_t* object_bone_indices = oi->object_bone_indices.data(); oi->mats.resize(skin->num_bone); mat4* mats = oi->mats.data(); for (int32_t i = 0; i < skin->num_bone; i++) { uint64_t name_hash = hash_utf8_xxh3_64bits(skin->bone_array[i].name); for (auth_3d_object_node& j : moh->node) if (hash_string_xxh3_64bits(j.name) == name_hash) { int32_t bone_id = skin->bone_array[i].id; if (!(bone_id & 0x8000)) object_bone_indices[bone_id] = (int32_t)(&j - moh->node.data()); break; } } } static void auth_3d_object_instance_store(auth_3d* auth, auth_3d_object_instance* oi, auth_3d_object_instance_file* oif, auth_3d_m_object_hrc* moh) { auth_3d_object_model_transform_store(auth, &oi->model_transform, &oif->model_transform); oif->name.assign(oi->name); oif->shadow = oi->shadow; oif->uid_name.assign(oi->uid_name); } static void auth_3d_object_model_transform_load(auth_3d* auth, auth_3d_object_model_transform* omt, auth_3d_model_transform_file* mtf) { omt->mat = mat4_identity; omt->mat_inner = mat4_identity; omt->mat_rot = mat4_identity; omt->translation_value = 0.0f; omt->rotation_value = 0.0f; omt->scale_value = 1.0f; omt->visible = false; omt->frame = -1.0f; omt->has_rotation = false; omt->has_translation = false; omt->has_scale = false; omt->has_visibility = false; auth_3d_vec3_load(auth, &omt->translation, &mtf->translation); auth_3d_vec3_load(auth, &omt->rotation, &mtf->rotation); auth_3d_vec3_load(auth, &omt->scale, &mtf->scale); auth_3d_key_load(auth, &omt->visibility, &mtf->visibility); if (omt->scale.x.type == AUTH_3D_KEY_STATIC && fabsf(1.0f - omt->scale.x.value) <= 0.000001f && omt->scale.y.type == AUTH_3D_KEY_STATIC && fabsf(1.0f - omt->scale.y.value) <= 0.000001f && omt->scale.z.type == AUTH_3D_KEY_STATIC && fabsf(1.0f - omt->scale.z.value) <= 0.000001f) { omt->has_scale = false; omt->scale_value = 1.0f; } else omt->has_scale = true; if (omt->visibility.type == AUTH_3D_KEY_STATIC) { omt->has_visibility = false; omt->visible = omt->visibility.value >= 0.999f; } else omt->has_visibility = true; } static void auth_3d_object_model_transform_store(auth_3d* auth, auth_3d_object_model_transform* omt, auth_3d_model_transform_file* mtf) { auth_3d_vec3_store(auth, &omt->translation, &mtf->translation); auth_3d_vec3_store(auth, &omt->rotation, &mtf->rotation); auth_3d_vec3_store(auth, &omt->scale, &mtf->scale); auth_3d_key_store(auth, &omt->visibility, &mtf->visibility); } static void auth_3d_object_node_load(auth_3d* auth, auth_3d_object_node* on, auth_3d_object_node_file* onf) { if (onf->flags & A3DA_OBJECT_NODE_JOINT_ORIENT) { on->joint_orient = onf->joint_orient; mat4_rotate_zyx(&on->joint_orient, &on->joint_orient_mat); enum_or(on->flags, AUTH_3D_OBJECT_NODE_JOINT_ORIENT); } else { on->joint_orient = 0.0f; on->joint_orient_mat = mat4_identity; } auth_3d_object_model_transform_load(auth, &on->model_transform, &onf->model_transform); on->name.assign(onf->name); on->parent = onf->parent; } static void auth_3d_object_node_store(auth_3d* auth, auth_3d_object_node* on, auth_3d_object_node_file* onf) { if (on->flags & AUTH_3D_OBJECT_NODE_JOINT_ORIENT) { onf->joint_orient = on->joint_orient; enum_or(onf->flags, A3DA_OBJECT_NODE_JOINT_ORIENT); } else onf->joint_orient = 0.0f; auth_3d_object_model_transform_store(auth, &on->model_transform, &onf->model_transform); onf->name.assign(on->name); onf->parent = on->parent; } static void auth_3d_object_texture_pattern_load(auth_3d* auth, auth_3d_object_texture_pattern* otp, auth_3d_object_texture_pattern_file* otpf, texture_database* tex_db) { otp->name.assign(otpf->name); auth_3d_object_curve_load(auth, &otp->pattern, otpf->pattern, otpf->pattern_offset); otp->texture_id = tex_db->get_texture_id(otp->name.c_str()); } static void auth_3d_object_texture_pattern_store(auth_3d* auth, auth_3d_object_texture_pattern* otp, auth_3d_object_texture_pattern_file* otpf) { otpf->name.assign(otp->name); auth_3d_object_curve_store(auth, &otp->pattern, otpf->pattern, otpf->pattern_offset); } static void auth_3d_object_texture_transform_load(auth_3d* auth, auth_3d_object_texture_transform* ott, auth_3d_object_texture_transform_file* ottf, texture_database* tex_db) { if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_COVERAGE_U) { auth_3d_key_load(auth, &ott->coverage_u, &ottf->coverage_u); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_COVERAGE_U); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_COVERAGE_V) { auth_3d_key_load(auth, &ott->coverage_v, &ottf->coverage_v); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_COVERAGE_V); } ott->name.assign(ottf->name); if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_OFFSET_U) { auth_3d_key_load(auth, &ott->offset_u, &ottf->offset_u); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_OFFSET_U); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_OFFSET_V) { auth_3d_key_load(auth, &ott->offset_v, &ottf->offset_v); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_OFFSET_V); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_REPEAT_U) { auth_3d_key_load(auth, &ott->repeat_u, &ottf->repeat_u); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_REPEAT_U); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_REPEAT_V) { auth_3d_key_load(auth, &ott->repeat_v, &ottf->repeat_v); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_REPEAT_V); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_ROTATE) { auth_3d_key_load(auth, &ott->rotate, &ottf->rotate); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_ROTATE); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_ROTATE_FRAME) { auth_3d_key_load(auth, &ott->rotate_frame, &ottf->rotate_frame); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_ROTATE_FRAME); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_U) { auth_3d_key_load(auth, &ott->translate_frame_u, &ottf->translate_frame_u); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_U); } if (ottf->flags & A3DA_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_V) { auth_3d_key_load(auth, &ott->translate_frame_v, &ottf->translate_frame_v); enum_or(ott->flags, AUTH_3D_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_V); } ott->texture_id = tex_db->get_texture_id(ott->name.c_str()); } static void auth_3d_object_texture_transform_store(auth_3d* auth, auth_3d_object_texture_transform* ott, auth_3d_object_texture_transform_file* ottf) { if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_COVERAGE_U) { auth_3d_key_store(auth, &ott->coverage_u, &ottf->coverage_u); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_COVERAGE_U); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_COVERAGE_V) { auth_3d_key_store(auth, &ott->coverage_v, &ottf->coverage_v); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_COVERAGE_V); } ottf->name.assign(ott->name); if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_OFFSET_U) { auth_3d_key_store(auth, &ott->offset_u, &ottf->offset_u); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_OFFSET_U); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_OFFSET_V) { auth_3d_key_store(auth, &ott->offset_v, &ottf->offset_v); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_OFFSET_V); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_REPEAT_U) { auth_3d_key_store(auth, &ott->repeat_u, &ottf->repeat_u); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_REPEAT_U); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_REPEAT_V) { auth_3d_key_store(auth, &ott->repeat_v, &ottf->repeat_v); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_REPEAT_V); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_ROTATE) { auth_3d_key_store(auth, &ott->rotate, &ottf->rotate); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_ROTATE); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_ROTATE_FRAME) { auth_3d_key_store(auth, &ott->rotate_frame, &ottf->rotate_frame); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_ROTATE_FRAME); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_U) { auth_3d_key_store(auth, &ott->translate_frame_u, &ottf->translate_frame_u); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_U); } if (ott->flags & AUTH_3D_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_V) { auth_3d_key_store(auth, &ott->translate_frame_v, &ottf->translate_frame_v); enum_or(ottf->flags, A3DA_OBJECT_TEXTURE_TRANSFORM_TRANSLATE_FRAME_V); } } static void auth_3d_play_control_load(auth_3d* auth, auth_3d_play_control_file* pcf) { auth_3d_play_control* pc = &auth->play_control; pc->begin = pcf->begin; if (pcf->flags & A3DA_PLAY_CONTROL_DIV) { pc->div = pcf->div; enum_or(pc->flags, AUTH_3D_PLAY_CONTROL_DIV); } pc->fps = pcf->fps; if (pcf->flags & A3DA_PLAY_CONTROL_OFFSET) { pc->div = pcf->div; enum_or(pc->flags, AUTH_3D_PLAY_CONTROL_OFFSET); } pc->size = pcf->size; } static void auth_3d_play_control_store(auth_3d* auth, auth_3d_play_control_file* pcf) { auth_3d_play_control* pc = &auth->play_control; pcf->begin = pc->begin; if (pc->flags & AUTH_3D_PLAY_CONTROL_DIV) { pcf->div = pc->div; enum_or(pcf->flags, A3DA_PLAY_CONTROL_DIV); } pcf->fps = pc->fps; if (pc->flags & AUTH_3D_PLAY_CONTROL_OFFSET) { pcf->div = pc->div; enum_or(pcf->flags, A3DA_PLAY_CONTROL_OFFSET); } pcf->size = pc->size; } static void auth_3d_point_disp(auth_3d_point* p, auth_3d* auth, render_context* rctx) { if (auth->pos) { p->model_transform.set_mat(&auth->mat); spr::put_rgb_cross(p->model_transform.mat); } } static void auth_3d_point_load(auth_3d* auth, auth_3d_point* p, auth_3d_point_file* pf) { auth_3d_model_transform_load(auth, &p->model_transform, &pf->model_transform); p->name.assign(pf->name); } static void auth_3d_point_store(auth_3d* auth, auth_3d_point* p, auth_3d_point_file* pf) { auth_3d_model_transform_store(auth, &p->model_transform, &pf->model_transform); pf->name.assign(p->name); } static void auth_3d_post_process_load(auth_3d* auth, auth_3d_post_process* pp, auth_3d_post_process_file* ppf) { if (ppf->flags & A3DA_POST_PROCESS_INTENSITY) { auth_3d_rgba_load(auth, &pp->intensity, &ppf->intensity); enum_or(pp->flags, AUTH_3D_POST_PROCESS_INTENSITY); } if (ppf->flags & A3DA_POST_PROCESS_LENS_FLARE) { auth_3d_key_load(auth, &pp->lens_flare, &ppf->lens_flare); enum_or(pp->flags, AUTH_3D_POST_PROCESS_LENS_FLARE); } if (ppf->flags & A3DA_POST_PROCESS_LENS_GHOST) { auth_3d_key_load(auth, &pp->lens_ghost, &ppf->lens_ghost); enum_or(pp->flags, AUTH_3D_POST_PROCESS_LENS_GHOST); } if (ppf->flags & A3DA_POST_PROCESS_LENS_SHAFT) { auth_3d_key_load(auth, &pp->lens_shaft, &ppf->lens_shaft); enum_or(pp->flags, AUTH_3D_POST_PROCESS_LENS_SHAFT); } if (ppf->flags & A3DA_POST_PROCESS_RADIUS) { auth_3d_rgba_load(auth, &pp->radius, &ppf->radius); enum_or(pp->flags, AUTH_3D_POST_PROCESS_RADIUS); } if (ppf->flags & A3DA_POST_PROCESS_SCENE_FADE) { auth_3d_rgba_load(auth, &pp->scene_fade, &ppf->scene_fade); enum_or(pp->flags, AUTH_3D_POST_PROCESS_SCENE_FADE); } } static void auth_3d_post_process_restore_prev_value(auth_3d_post_process* pp, render_context* rctx) { if (pp->flags_init & AUTH_3D_POST_PROCESS_INTENSITY) rctx->render.set_intensity(pp->intensity_init); if (pp->flags_init & (AUTH_3D_POST_PROCESS_LENS_FLARE | AUTH_3D_POST_PROCESS_LENS_GHOST | AUTH_3D_POST_PROCESS_LENS_SHAFT)) { vec3 value = rctx->render.get_lens(); if (pp->flags_init & AUTH_3D_POST_PROCESS_LENS_FLARE) value.x = pp->lens_init.x; if (pp->flags_init & AUTH_3D_POST_PROCESS_LENS_SHAFT) value.y = pp->lens_init.y; if (pp->flags_init & AUTH_3D_POST_PROCESS_LENS_GHOST) value.z = pp->lens_init.z; rctx->render.set_lens(value); } if (pp->flags_init & AUTH_3D_POST_PROCESS_RADIUS) rctx->render.set_radius(pp->radius_init); if (pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE) rctx->render.set_scene_fade(pp->scene_fade_init, 0); } static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* rctx) { if (pp->flags & AUTH_3D_POST_PROCESS_INTENSITY) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_INTENSITY)) { pp->intensity_init = rctx->render.get_intensity(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_INTENSITY); } rctx->render.set_intensity(*(vec3*)&pp->intensity.value); } if (pp->flags & (AUTH_3D_POST_PROCESS_LENS_GHOST | AUTH_3D_POST_PROCESS_LENS_SHAFT | AUTH_3D_POST_PROCESS_LENS_FLARE)) { vec3 value = rctx->render.get_lens(); if (pp->flags & AUTH_3D_POST_PROCESS_LENS_FLARE) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_LENS_FLARE)) pp->lens_init.x = value.x; value.x = pp->lens_value.x; } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_SHAFT) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_LENS_SHAFT)) pp->lens_init.y = value.y; value.y = pp->lens_value.y; } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_GHOST) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_LENS_GHOST)) pp->lens_init.z = value.z; value.z = pp->lens_value.z; } rctx->render.set_lens(value); } if (pp->flags & AUTH_3D_POST_PROCESS_RADIUS) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_RADIUS)) { pp->radius_init = rctx->render.get_radius(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_RADIUS); } rctx->render.set_radius(*(vec3*)&pp->radius.value); } if (pp->flags & AUTH_3D_POST_PROCESS_SCENE_FADE) { if (!(pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE)) { pp->scene_fade_init = rctx->render.get_scene_fade(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_SCENE_FADE); } rctx->render.set_scene_fade(pp->scene_fade.value, 0); } } static void auth_3d_post_process_store(auth_3d* auth, auth_3d_post_process* pp, auth_3d_post_process_file* ppf) { if (pp->flags & AUTH_3D_POST_PROCESS_INTENSITY) { auth_3d_rgba_store(auth, &pp->intensity, &ppf->intensity); enum_or(ppf->flags, A3DA_POST_PROCESS_INTENSITY); } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_FLARE) { auth_3d_key_store(auth, &pp->lens_flare, &ppf->lens_flare); enum_or(ppf->flags, A3DA_POST_PROCESS_LENS_FLARE); } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_GHOST) { auth_3d_key_store(auth, &pp->lens_ghost, &ppf->lens_ghost); enum_or(ppf->flags, A3DA_POST_PROCESS_LENS_GHOST); } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_SHAFT) { auth_3d_key_store(auth, &pp->lens_shaft, &ppf->lens_shaft); enum_or(ppf->flags, A3DA_POST_PROCESS_LENS_SHAFT); } if (pp->flags & AUTH_3D_POST_PROCESS_RADIUS) { auth_3d_rgba_store(auth, &pp->radius, &ppf->radius); enum_or(ppf->flags, A3DA_POST_PROCESS_RADIUS); } if (pp->flags & AUTH_3D_POST_PROCESS_SCENE_FADE) { auth_3d_rgba_store(auth, &pp->scene_fade, &ppf->scene_fade); enum_or(ppf->flags, A3DA_POST_PROCESS_SCENE_FADE); } } static bool auth_3d_data_struct_init(auth_3d_data_struct* auth_3d_data, render_context* rctx) { auth_3d_data->loaded_ids.clear(); auth_3d_data->loaded_ids.shrink_to_fit(); for (int32_t i = 0; i < AUTH_3D_DATA_COUNT; i++) auth_3d_data->data[i].reset(); return true; } static bool auth_3d_data_struct_check_category_loaded( auth_3d_data_struct* auth_3d_data, const char* category_name) { if (category_name) { auth_3d_farc* a3da_farc = auth_3d_data_struct_get_farc(auth_3d_data, category_name); if (a3da_farc) return a3da_farc->state == 2; } return true; } static bool auth_3d_data_struct_check_category_loaded( auth_3d_data_struct* auth_3d_data, uint32_t category_hash) { if (!category_hash || category_hash == hash_murmurhash_empty) return true; auto elem = auth_3d_data->farcs_modern.find(category_hash); if (elem != auth_3d_data->farcs_modern.end()) return elem->second.state == 2; return true; } static bool auth_3d_data_struct_ctrl(auth_3d_data_struct* auth_3d_data, render_context* rctx) { for (int32_t& i : auth_3d_data->loaded_ids) if (i >= 0 && (i & 0x7FFF) < AUTH_3D_DATA_COUNT) { auth_3d* auth = &auth_3d_data->data[i & 0x7FFF]; if (auth && auth->id == i) auth->ctrl(rctx); } return false; } static void auth_3d_data_struct_disp(auth_3d_data_struct* auth_3d_data, render_context* rctx) { for (int32_t& i : auth_3d_data->loaded_ids) if (i >= 0 && (i & 0x7FFF) < AUTH_3D_DATA_COUNT) { auth_3d* auth = &auth_3d_data->data[i & 0x7FFF]; if (auth && auth->id == i) auth->disp(rctx); } } static auth_3d_farc* auth_3d_data_struct_get_farc( auth_3d_data_struct* auth_3d_data, const char* category_name) { if (!category_name || !auth_3d_data->farcs.size()) return 0; uint64_t name_hash = hash_utf8_xxh3_64bits(category_name); for (auth_3d_farc& i : auth_3d_data->farcs) if (hash_string_xxh3_64bits(i.name) == name_hash) return &i; return 0; } static void auth_3d_data_struct_load_category(auth_3d_data_struct* auth_3d_data, const char* category_name, const char* mdata_dir) { if (!category_name) return; auth_3d_farc* a3da_farc = auth_3d_data_struct_get_farc(auth_3d_data, category_name); if (a3da_farc) auth_3d_farc_load(a3da_farc, mdata_dir); } static void auth_3d_data_struct_load_category(auth_3d_data_struct* auth_3d_data, void* data, const char* category_name, uint32_t category_hash) { if (!category_hash || category_hash == hash_murmurhash_empty) return; auto elem = auth_3d_data->farcs_modern.find(category_hash); if (elem == auth_3d_data->farcs_modern.end()) { elem = auth_3d_data->farcs_modern.insert({ category_hash, {} }).first; auth_3d_farc* a3da_farc = &elem->second; a3da_farc->name.assign(category_name); } auth_3d_farc* a3da_farc = &elem->second; if (a3da_farc) auth_3d_farc_load_modern(a3da_farc, data); } static void auth_3d_data_struct_unload_category( auth_3d_data_struct* auth_3d_data, const char* category_name) { if (!category_name) return; auth_3d_farc* a3da_farc = auth_3d_data_struct_get_farc(auth_3d_data, category_name); if (a3da_farc) auth_3d_farc_unload(a3da_farc); } static void auth_3d_data_struct_unload_category( auth_3d_data_struct* auth_3d_data, uint32_t category_hash) { if (!category_hash || category_hash == hash_murmurhash_empty) return; auto elem = auth_3d_data->farcs_modern.find(category_hash); if (elem == auth_3d_data->farcs_modern.end()) return; auth_3d_farc_unload(&elem->second); if (elem->second.load_count <= 0) auth_3d_data->farcs_modern.erase(elem); } static void auth_3d_farc_load(auth_3d_farc* a3da_farc, const char* mdata_dir) { if (a3da_farc->load_count) { a3da_farc->load_count++; return; } a3da_farc->load_count = 1; auth_3d_farc_read_file(a3da_farc, mdata_dir); } static void auth_3d_farc_load_modern(auth_3d_farc* a3da_farc, void* data) { if (a3da_farc->load_count) { a3da_farc->load_count++; return; } a3da_farc->load_count = 1; auth_3d_farc_read_file_modern(a3da_farc, data); } static void auth_3d_farc_read_file(auth_3d_farc* a3da_farc, const char* mdata_dir) { if (a3da_farc->state) { a3da_farc->state = 2; return; } a3da_farc->state = 1; if (mdata_dir && *mdata_dir) { a3da_farc->path.assign(mdata_dir); a3da_farc->path.append("rom/auth_3d/"); } else a3da_farc->path.assign("rom/auth_3d/"); a3da_farc->file.assign(a3da_farc->name); a3da_farc->file.append(".farc"); if (a3da_farc->file_handler.read_file(&data_list[DATA_AFT], a3da_farc->path.c_str(), a3da_farc->file.c_str())) a3da_farc->file_handler.set_callback_data(0, (PFNFILEHANDLERCALLBACK*)auth_3d_farc_read_func, a3da_farc); else a3da_farc->state = 2; } static void auth_3d_farc_read_file_modern(auth_3d_farc* a3da_farc, void* data) { if (a3da_farc->state) { a3da_farc->state = 2; return; } a3da_farc->state = 1; a3da_farc->path.assign("root+/auth_3d/"); a3da_farc->file.assign(a3da_farc->name); a3da_farc->file.append(".farc"); if (a3da_farc->file_handler.read_file(data, a3da_farc->path.c_str(), hash_string_murmurhash(a3da_farc->name), ".farc")) a3da_farc->file_handler.set_callback_data(0, (PFNFILEHANDLERCALLBACK*)auth_3d_farc_read_func, a3da_farc); else a3da_farc->state = 2; } static bool auth_3d_farc_read_func(auth_3d_farc* a3da_farc, const void* data, size_t size) { if (a3da_farc->state == 1) { a3da_farc->state = 2; a3da_farc->data = data; a3da_farc->size = size; } if (!a3da_farc->farc) a3da_farc->farc = new farc; if (!a3da_farc->farc) return false; a3da_farc->farc->read(a3da_farc->data, a3da_farc->size, true); return true; } static void auth_3d_farc_reset(auth_3d_farc* a3da_farc) { if (a3da_farc->state == 1) a3da_farc->file_handler.call_free_callback(); else if (a3da_farc->state == 2) { delete a3da_farc->farc; a3da_farc->farc = 0; a3da_farc->file_handler.reset(); } a3da_farc->path.clear(); a3da_farc->path.shrink_to_fit(); a3da_farc->file.clear(); a3da_farc->file.shrink_to_fit(); a3da_farc->data = 0; a3da_farc->size = 0; a3da_farc->state = 0; } static void auth_3d_farc_unload(auth_3d_farc* a3da_farc) { if (--a3da_farc->load_count < 0) a3da_farc->load_count = 0; else if (!a3da_farc->load_count) auth_3d_farc_reset(a3da_farc); } static void auth_3d_uid_file_load(auth_3d_uid_file* uid_file) { uid_file->state = 1; auth_3d_farc_load(uid_file->farc, 0); } static void auth_3d_uid_file_modern_load(auth_3d_uid_file_modern* uid_file) { uid_file->state = 1; auth_3d_farc_load(uid_file->farc, 0); } static void auth_3d_uid_file_load_file(auth_3d_uid_file* uid_file, auth_3d_database* auth_3d_db) { if (uid_file->load_count) uid_file->load_count++; else if (uid_file->state) return; uid_file->state = 2; if (uid_file->uid >= auth_3d_db->uid.size()) return; auth_3d_database_uid* db_uid = &auth_3d_db->uid[uid_file->uid]; if (!db_uid->enabled) return; uid_file->name = db_uid->name.c_str(); uid_file->file_name.assign(db_uid->name); uid_file->file_name.append(".a3da"); auth_3d_farc* farc = auth_3d_data_struct_get_farc(auth_3d_data, db_uid->category.c_str()); uid_file->farc = farc; if (farc) { uid_file->load_count = 1; auth_3d_uid_file_load(uid_file); } } static void auth_3d_uid_file_modern_load_file(auth_3d_uid_file_modern* uid_file) { if (uid_file->load_count) uid_file->load_count++; else if (uid_file->state) return; uid_file->state = 2; auth_3d_farc* farc = 0; for (auto& i : auth_3d_data->farcs_modern) if (i.second.farc && i.second.farc->has_file(uid_file->hash)) { farc = &i.second; break; } if (!farc) return; uid_file->file_name.assign(farc->farc->get_file_name(uid_file->hash)); uid_file->farc = farc; if (farc) { uid_file->load_count = 1; auth_3d_uid_file_modern_load(uid_file); } } static void auth_3d_uid_file_unload(auth_3d_uid_file* uid_file) { if (--uid_file->load_count < 0) uid_file->load_count = 0; else if (!uid_file->load_count) auth_3d_uid_file_unload_file(uid_file); } static void auth_3d_uid_file_modern_unload(auth_3d_uid_file_modern* uid_file) { if (--uid_file->load_count < 0) uid_file->load_count = 0; else if (!uid_file->load_count) auth_3d_uid_file_modern_unload_file(uid_file); } static void auth_3d_uid_file_unload_file(auth_3d_uid_file* uid_file) { if (uid_file->state == 1 || uid_file->state == 2) auth_3d_farc_unload(uid_file->farc); uid_file->name = 0; uid_file->farc = 0; uid_file->state = 0; } static void auth_3d_uid_file_modern_unload_file(auth_3d_uid_file_modern* uid_file) { if (uid_file->state == 1 || uid_file->state == 2) auth_3d_farc_unload(uid_file->farc); uid_file->name.clear(); uid_file->name.shrink_to_fit(); uid_file->farc = 0; uid_file->state = 0; auth_3d_data->uid_files_modern.erase(uid_file->hash); } static size_t auth_3d_time_event_radix_index_func_frame(auth_3d_time_event* data, size_t index) { return *(uint32_t*)&data[index].frame; }