mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-01 11:18:23 +03:00
1295 lines
37 KiB
C++
1295 lines
37 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
*/
|
|
|
|
#include "rob.hpp"
|
|
#include "../../KKdLib/prj/algorithm.hpp"
|
|
#include "../../KKdLib/str_utils.hpp"
|
|
#include "../data.hpp"
|
|
#include "../mdata_manager.hpp"
|
|
#include "skin_param.hpp"
|
|
|
|
struct osage_setting {
|
|
std::map<std::pair<std::string, std::string>, osage_setting_osg_cat> cat;
|
|
std::map<object_info, std::string> obj;
|
|
|
|
osage_setting();
|
|
~osage_setting();
|
|
|
|
void clear();
|
|
const osage_setting_osg_cat* get_cat_value(
|
|
object_info* obj_info, const char* root_node);
|
|
void load();
|
|
void parse(key_val* kv);
|
|
rob_osage_parts parse_parts_string(std::string& s);
|
|
};
|
|
|
|
struct skin_param_file {
|
|
p_file_handler* file_handler;
|
|
item_id id;
|
|
int32_t type;
|
|
std::vector<skin_param_file_data>* data;
|
|
rob_chara* rob_chr;
|
|
|
|
skin_param_file();
|
|
~skin_param_file();
|
|
};
|
|
|
|
struct skin_param_key {
|
|
object_info obj_info;
|
|
uint32_t motion_id;
|
|
int32_t frame;
|
|
|
|
inline skin_param_key() {
|
|
motion_id = -1;
|
|
frame = -1;
|
|
}
|
|
|
|
inline skin_param_key(object_info obj_info) {
|
|
this->obj_info = obj_info;
|
|
motion_id = -1;
|
|
frame = -1;
|
|
}
|
|
|
|
inline skin_param_key(object_info obj_info, uint32_t motion_id) {
|
|
this->obj_info = obj_info;
|
|
this->motion_id = motion_id;
|
|
frame = -1;
|
|
}
|
|
|
|
inline skin_param_key(object_info obj_info, uint32_t motion_id, int32_t frame) {
|
|
this->obj_info = obj_info;
|
|
this->motion_id = motion_id;
|
|
this->frame = frame;
|
|
}
|
|
};
|
|
|
|
constexpr bool operator==(const skin_param_key& left, const skin_param_key& right) {
|
|
return left.obj_info == right.obj_info && left.motion_id == right.motion_id && left.frame == right.frame;
|
|
}
|
|
|
|
constexpr bool operator!=(const skin_param_key& left, const skin_param_key& right) {
|
|
return !(left == right);
|
|
}
|
|
|
|
constexpr bool operator<(const skin_param_key& left, const skin_param_key& right) {
|
|
if (left.obj_info != right.obj_info)
|
|
return left.obj_info < right.obj_info;
|
|
else if (left.motion_id != right.motion_id)
|
|
return left.motion_id < right.motion_id;
|
|
else if (left.frame != right.frame)
|
|
return left.frame < right.frame;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
constexpr bool operator>(const skin_param_key& left, const skin_param_key& right) {
|
|
return right < left;
|
|
}
|
|
|
|
constexpr bool operator<=(const skin_param_key& left, const skin_param_key& right) {
|
|
return !(right < left);
|
|
}
|
|
|
|
constexpr bool operator>=(const skin_param_key& left, const skin_param_key& right) {
|
|
return !(left < right);
|
|
}
|
|
|
|
struct SkinParamManager : public app::Task {
|
|
int32_t state;
|
|
uint8_t index;
|
|
std::vector<osage_init_data> osage_init;
|
|
std::map<skin_param_key, std::vector<skin_param_file_data>*> object_motion_frame;
|
|
std::map<skin_param_key, std::vector<skin_param_file_data>*> object_motion;
|
|
std::map<skin_param_key, std::vector<skin_param_file_data>*> object;
|
|
std::list<skin_param_file*> files;
|
|
|
|
SkinParamManager();
|
|
virtual ~SkinParamManager() override;
|
|
|
|
virtual bool init() override;
|
|
virtual bool ctrl() override;
|
|
virtual bool dest() override;
|
|
virtual void disp() override;
|
|
|
|
bool add_task(std::vector<osage_init_data>& vec);
|
|
|
|
void AddFiles();
|
|
bool CtrlFiles();
|
|
int32_t GetExtSkpFile(const osage_init_data& osage_init,
|
|
const std::string& dir, std::string& file, void* data, const motion_database* mot_db);
|
|
std::vector<skin_param_file_data>* GetSkinParamFileData(
|
|
object_info obj_info, uint32_t motion_id, int32_t frame);
|
|
void Reset();
|
|
};
|
|
|
|
struct sp_skp_db {
|
|
std::map<int32_t, std::shared_ptr<std::map<object_info, uint32_t>>> pv;
|
|
std::map<std::string, std::shared_ptr<std::map<object_info, uint32_t>>> motion;
|
|
std::vector<std::string> farc_list;
|
|
size_t farc_list_count;
|
|
|
|
sp_skp_db();
|
|
~sp_skp_db();
|
|
|
|
void clear();
|
|
void load();
|
|
void parse(key_val* kv);
|
|
|
|
int32_t get_ext_skp_file(const osage_init_data& osage_init,
|
|
const object_info obj_info, std::string& file, std::string& farc,
|
|
void* data, const motion_database* mot_db);
|
|
};
|
|
|
|
static bool osage_setting_data_load_file(void* data, const char* dir, const char* file, uint32_t hash);
|
|
|
|
static SkinParamManager* skin_param_manager_get(int32_t chara_id);
|
|
|
|
static bool sp_skp_db_load_file(void* data, const char* dir, const char* file, uint32_t hash);
|
|
|
|
osage_setting* osage_setting_data;
|
|
sp_skp_db* sp_skp_db_data;
|
|
|
|
SkinParamManager* skin_param_manager;
|
|
|
|
std::map<object_info, prj::shared_ptr<key_val>> skin_param_storage;
|
|
|
|
SkinParam::CollisionParam::CollisionParam() : type(), node_idx(), pos() {
|
|
radius = 0.2f;
|
|
}
|
|
|
|
skin_param_osage_root_normal_ref::skin_param_osage_root_normal_ref() {
|
|
|
|
}
|
|
|
|
skin_param_osage_root_normal_ref::~skin_param_osage_root_normal_ref() {
|
|
|
|
}
|
|
|
|
skin_param_osage_root_boc::skin_param_osage_root_boc() : ed_node(), st_node() {
|
|
|
|
}
|
|
|
|
skin_param_osage_root_boc::~skin_param_osage_root_boc() {
|
|
|
|
}
|
|
|
|
skin_param_osage_root::skin_param_osage_root() : field_0(), force(), force_gain(),
|
|
rot_y(), rot_z(), init_rot_y(), init_rot_z(), coli_r(), yz_order(), stiffness() {
|
|
air_res = 0.5f;
|
|
hinge_y = 90.0f;
|
|
hinge_z = 90.0f;
|
|
name = "NO-PARAM";
|
|
friction = 1.0f;
|
|
wind_afc = 0.5f;
|
|
coli_type = SkinParam::RootCollisionTypeEnd;
|
|
move_cancel = -0.01f;
|
|
coli.resize(13);
|
|
}
|
|
|
|
skin_param_osage_root::~skin_param_osage_root() {
|
|
|
|
}
|
|
|
|
skin_param::skin_param() : friction(), wind_afc(), air_res(), rot(), init_rot(),
|
|
coli_type(), stiffness(), move_cancel(), coli_r(), force(), force_gain(), colli_tgt_osg() {
|
|
reset();
|
|
}
|
|
|
|
skin_param::~skin_param() {
|
|
|
|
}
|
|
|
|
void skin_param::set_skin_param_osage_root(const skin_param_osage_root& skp_root) {
|
|
coli.assign(skp_root.coli.begin(), skp_root.coli.end());
|
|
friction = skp_root.friction;
|
|
wind_afc = skp_root.wind_afc;
|
|
air_res = skp_root.air_res;
|
|
rot.y = skp_root.rot_y * DEG_TO_RAD_FLOAT;
|
|
rot.z = skp_root.rot_z * DEG_TO_RAD_FLOAT;
|
|
init_rot.y = skp_root.init_rot_y * DEG_TO_RAD_FLOAT;
|
|
init_rot.z = skp_root.init_rot_z * DEG_TO_RAD_FLOAT;
|
|
coli_type = skp_root.coli_type;
|
|
stiffness = skp_root.stiffness;
|
|
move_cancel = skp_root.move_cancel;
|
|
coli_r = skp_root.coli_r;
|
|
hinge.ymin = -skp_root.hinge_y;
|
|
hinge.ymax = skp_root.hinge_y;
|
|
hinge.zmin = -skp_root.hinge_z;
|
|
hinge.zmax = skp_root.hinge_z;
|
|
hinge.limit();
|
|
force = skp_root.force;
|
|
force_gain = skp_root.force_gain;
|
|
}
|
|
|
|
skin_param_file_data::skin_param_file_data() : field_88() {
|
|
|
|
}
|
|
|
|
skin_param_file_data::~skin_param_file_data() {
|
|
|
|
}
|
|
|
|
osage_setting_osg_cat::osage_setting_osg_cat() : exf() {
|
|
parts = ROB_OSAGE_PARTS_NONE;
|
|
}
|
|
|
|
const osage_setting_osg_cat* osage_setting_data_get_cat_value(
|
|
object_info* obj_info, const char* root_node) {
|
|
return osage_setting_data->get_cat_value(obj_info, root_node);
|
|
}
|
|
|
|
bool osage_setting_data_obj_has_key(object_info key) {
|
|
return osage_setting_data->obj.find(key) != osage_setting_data->obj.end();
|
|
}
|
|
|
|
void skin_param_data_init() {
|
|
if (!osage_setting_data)
|
|
osage_setting_data = new osage_setting;
|
|
|
|
if (!sp_skp_db_data)
|
|
sp_skp_db_data = new sp_skp_db;
|
|
|
|
if (!skin_param_manager)
|
|
skin_param_manager = new SkinParamManager[ROB_CHARA_COUNT];
|
|
|
|
skin_param_storage = {};
|
|
}
|
|
|
|
void skin_param_data_load() {
|
|
osage_setting_data->load();
|
|
sp_skp_db_data->load();
|
|
}
|
|
|
|
void skin_param_data_free() {
|
|
skin_param_storage.clear();
|
|
|
|
if (skin_param_manager) {
|
|
delete[] skin_param_manager;
|
|
skin_param_manager = 0;
|
|
}
|
|
|
|
if (sp_skp_db_data) {
|
|
delete sp_skp_db_data;
|
|
sp_skp_db_data = 0;
|
|
}
|
|
|
|
if (osage_setting_data) {
|
|
delete osage_setting_data;
|
|
osage_setting_data = 0;
|
|
}
|
|
}
|
|
|
|
bool skin_param_manager_array_check_task_ready() {
|
|
bool ret = false;
|
|
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++)
|
|
ret |= app::TaskWork::check_task_ready(&skin_param_manager[i]);
|
|
return ret;
|
|
}
|
|
|
|
bool skin_param_manager_add_task(int32_t chara_id, std::vector<osage_init_data>& vec) {
|
|
return skin_param_manager[chara_id].add_task(vec);
|
|
}
|
|
|
|
bool skin_param_manager_check_task_ready(int32_t chara_id) {
|
|
return app::TaskWork::check_task_ready(skin_param_manager_get(chara_id));
|
|
}
|
|
|
|
int32_t skin_param_manager_get_ext_skp_file(
|
|
int32_t chara_id, const osage_init_data& osage_init,
|
|
const std::string& dir, std::string& file, void* data, const motion_database* mot_db) {
|
|
return skin_param_manager_get(chara_id)->GetExtSkpFile(osage_init, dir, file, data, mot_db);
|
|
}
|
|
|
|
std::vector<skin_param_file_data>* skin_param_manager_get_skin_param_file_data(
|
|
int32_t chara_id, object_info obj_info, uint32_t motion_id, int32_t frame) {
|
|
return skin_param_manager_get(chara_id)->GetSkinParamFileData(obj_info, motion_id, frame);
|
|
}
|
|
|
|
void skin_param_manager_reset(int32_t chara_id) {
|
|
skin_param_manager_get(chara_id)->Reset();
|
|
}
|
|
|
|
void skin_param_osage_node_parse(void* kv, const char* name,
|
|
std::vector<skin_param_osage_node>* vec, skin_param_osage_root& skp_root) {
|
|
key_val* _kv = (key_val*)kv;
|
|
if (!_kv->open_scope(name))
|
|
return;
|
|
|
|
if (!_kv->open_scope("node")) {
|
|
_kv->close_scope();
|
|
return;
|
|
}
|
|
|
|
int32_t count;
|
|
if (_kv->read("length", count)) {
|
|
size_t c = vec->size();
|
|
if (c < count)
|
|
vec->resize(count);
|
|
}
|
|
else
|
|
vec->clear();
|
|
|
|
int32_t j = 0;
|
|
for (auto i = vec->begin(); i != vec->end(); i++, j++) {
|
|
if (!_kv->open_scope_fmt(j))
|
|
continue;
|
|
|
|
*i = skin_param_osage_node();
|
|
|
|
float_t coli_r = 0.0f;
|
|
if (_kv->read("coli_r", coli_r))
|
|
i->coli_r = coli_r;
|
|
|
|
float_t weight = 0.0f;
|
|
if (_kv->read("weight", weight))
|
|
i->weight = weight;
|
|
|
|
float_t inertial_cancel = 0.0f;
|
|
if (_kv->read("inertial_cancel", inertial_cancel))
|
|
i->inertial_cancel = inertial_cancel;
|
|
|
|
i->hinge.ymin = -skp_root.hinge_y;
|
|
i->hinge.ymax = skp_root.hinge_y;
|
|
i->hinge.zmin = -skp_root.hinge_z;
|
|
i->hinge.zmax = skp_root.hinge_z;
|
|
|
|
float_t hinge_ymax = 0.0f;
|
|
if (_kv->read("hinge_ymax", hinge_ymax))
|
|
i->hinge.ymax = hinge_ymax;
|
|
|
|
float_t hinge_ymin = 0.0f;
|
|
if (_kv->read("hinge_ymin", hinge_ymin))
|
|
i->hinge.ymin = hinge_ymin;
|
|
|
|
float_t hinge_zmax = 0.0f;
|
|
if (_kv->read("hinge_zmax", hinge_zmax))
|
|
i->hinge.zmax = hinge_zmax;
|
|
|
|
float_t hinge_zmin = 0.0f;
|
|
if (_kv->read("hinge_zmin", hinge_zmin))
|
|
i->hinge.zmin = hinge_zmin;
|
|
_kv->close_scope();
|
|
}
|
|
|
|
_kv->close_scope();
|
|
_kv->close_scope();
|
|
}
|
|
|
|
void skin_param_osage_root_parse(void* kv, const char* name,
|
|
skin_param_osage_root& skp_root, const bone_database* bone_data) {
|
|
key_val* _kv = (key_val*)kv;
|
|
if (!_kv->open_scope(name))
|
|
return;
|
|
|
|
int32_t node_length = 0;
|
|
_kv->read("node.length", node_length);
|
|
|
|
if (!_kv->open_scope("root")) {
|
|
_kv->close_scope();
|
|
return;
|
|
}
|
|
|
|
float_t force = 0.0f;
|
|
float_t force_gain = 0.0f;
|
|
if (_kv->read("force", force)
|
|
&& _kv->read("force_gain", force_gain)) {
|
|
skp_root.force = force;
|
|
skp_root.force_gain = force_gain;
|
|
}
|
|
|
|
float_t air_res = 0.0f;
|
|
if (_kv->read("air_res", air_res))
|
|
skp_root.air_res = min_def(air_res, 0.9f);
|
|
|
|
float_t rot_y = 0.0f;
|
|
float_t rot_z = 0.0f;
|
|
if (_kv->read("rot_y", rot_y)
|
|
&& _kv->read("rot_z", rot_z)) {
|
|
skp_root.rot_y = rot_y;
|
|
skp_root.rot_z = rot_z;
|
|
}
|
|
|
|
float_t friction = 0.0f;
|
|
if (_kv->read("friction", friction))
|
|
skp_root.friction = friction;
|
|
|
|
float_t wind_afc = 0;
|
|
if (_kv->read("wind_afc", wind_afc)) {
|
|
skp_root.wind_afc = wind_afc;
|
|
if (!str_utils_compare_length(name, utf8_length(name), "c_opa", 5))
|
|
skp_root.wind_afc = 0.0f;
|
|
}
|
|
|
|
int32_t coli_type = 0;
|
|
if (_kv->read("coli_type", coli_type))
|
|
skp_root.coli_type = (SkinParam::RootCollisionType)coli_type;
|
|
|
|
float_t init_rot_y = 0.0f;
|
|
float_t init_rot_z = 0.0f;
|
|
if (_kv->read("init_rot_y", init_rot_y)
|
|
&& _kv->read("init_rot_z", init_rot_z)) {
|
|
skp_root.init_rot_y = init_rot_y;
|
|
skp_root.init_rot_z = init_rot_z;
|
|
}
|
|
|
|
float_t hinge_y = 0.0f;
|
|
float_t hinge_z = 0.0f;
|
|
if (_kv->read("hinge_y", hinge_y)
|
|
&& _kv->read("hinge_z", hinge_z)) {
|
|
skp_root.hinge_y = hinge_y;
|
|
skp_root.hinge_z = hinge_z;
|
|
}
|
|
|
|
float_t coli_r = 0.0f;
|
|
if (_kv->read("coli_r", coli_r))
|
|
skp_root.coli_r = coli_r;
|
|
|
|
float_t stiffness = 0.0f;
|
|
if (_kv->read("stiffness", stiffness))
|
|
skp_root.stiffness = stiffness;
|
|
|
|
float_t move_cancel = 0.0f;
|
|
if (_kv->read("move_cancel", move_cancel))
|
|
skp_root.move_cancel = move_cancel;
|
|
|
|
int32_t count;
|
|
if (_kv->read("coli", "length", count)) {
|
|
std::vector<SkinParam::CollisionParam>& vc = skp_root.coli;
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!_kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
SkinParam::CollisionParam* c = &vc[i];
|
|
|
|
int32_t type = 0;
|
|
if (!_kv->read("type", type)) {
|
|
_kv->close_scope();
|
|
break;
|
|
}
|
|
c->type = (SkinParam::CollisionType)type;
|
|
|
|
float_t radius = 0;
|
|
if (!_kv->read("radius", radius)) {
|
|
_kv->close_scope();
|
|
break;
|
|
}
|
|
c->radius = radius;
|
|
|
|
const char* bone0_name;
|
|
if (!_kv->read("bone.0.name", bone0_name)) {
|
|
_kv->close_scope();
|
|
break;
|
|
}
|
|
|
|
c->node_idx[0] = bone_data->get_skeleton_object_bone_index(
|
|
bone_database_skeleton_type_to_string(BONE_DATABASE_SKELETON_COMMON), bone0_name);
|
|
|
|
vec3 bone0_pos = 0.0f;
|
|
if (!_kv->read("bone.0.posx", bone0_pos.x)
|
|
|| !_kv->read("bone.0.posy", bone0_pos.y)
|
|
|| !_kv->read("bone.0.posz", bone0_pos.z)) {
|
|
_kv->close_scope();
|
|
break;
|
|
}
|
|
|
|
c->pos[0] = bone0_pos;
|
|
|
|
const char* bone1_name;
|
|
if (_kv->read("bone.1.name", bone1_name)) {
|
|
c->node_idx[1] = bone_data->get_skeleton_object_bone_index(
|
|
bone_database_skeleton_type_to_string(BONE_DATABASE_SKELETON_COMMON), bone1_name);
|
|
|
|
vec3 bone1_pos = 0.0f;
|
|
if (!_kv->read("bone.1.posx", bone1_pos.x)
|
|
|| !_kv->read("bone.1.posy", bone1_pos.y)
|
|
|| !_kv->read("bone.1.posz", bone1_pos.z)) {
|
|
_kv->close_scope();
|
|
break;
|
|
}
|
|
|
|
c->pos[1] = bone1_pos;
|
|
}
|
|
_kv->close_scope();
|
|
}
|
|
_kv->close_scope();
|
|
}
|
|
|
|
if (_kv->read("boc", "length", count)) {
|
|
std::vector<skin_param_osage_root_boc>* vb = &skp_root.boc;
|
|
|
|
vb->reserve(count);
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!_kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
int32_t st_node = 0;
|
|
std::string ed_root;
|
|
int32_t ed_node = 0;
|
|
if (_kv->read("st_node", st_node)
|
|
&& st_node < node_length
|
|
&& _kv->read("ed_root", ed_root)
|
|
&& _kv->read("ed_node", ed_node)
|
|
&& ed_node < node_length) {
|
|
vb->push_back({});
|
|
skin_param_osage_root_boc& b = vb->back();
|
|
b.st_node = st_node;
|
|
b.ed_root.assign(ed_root);
|
|
b.ed_node = ed_node;
|
|
}
|
|
_kv->close_scope();
|
|
}
|
|
_kv->close_scope();
|
|
}
|
|
|
|
std::string colli_tgt_osg;
|
|
if (_kv->read("colli_tgt_osg", colli_tgt_osg))
|
|
skp_root.colli_tgt_osg.assign(colli_tgt_osg);
|
|
|
|
if (_kv->read("normal_ref", "length", count)) {
|
|
std::vector<skin_param_osage_root_normal_ref>* vnr = &skp_root.normal_ref;
|
|
|
|
vnr->reserve(count);
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!_kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
std::string n;
|
|
if (_kv->read("N", n)) {
|
|
vnr->push_back({});
|
|
skin_param_osage_root_normal_ref& nr = vnr->back();
|
|
nr.n.assign(n);
|
|
_kv->read("U", nr.u);
|
|
_kv->read("D", nr.d);
|
|
_kv->read("L", nr.l);
|
|
_kv->read("R", nr.r);
|
|
}
|
|
_kv->close_scope();
|
|
}
|
|
_kv->close_scope();
|
|
}
|
|
|
|
_kv->close_scope();
|
|
_kv->close_scope();
|
|
}
|
|
|
|
key_val* skin_param_storage_get_key_val(object_info obj_info) {
|
|
auto elem = skin_param_storage.find(obj_info);
|
|
if (elem != skin_param_storage.end())
|
|
return elem->second.get();
|
|
return 0;
|
|
}
|
|
|
|
void skin_param_storage_load(std::vector<object_info>& obj_infos,
|
|
void* data, const object_database* obj_db) {
|
|
prj::sort_unique(obj_infos);
|
|
for (const object_info& i : obj_infos) {
|
|
if (i.is_null())
|
|
continue;
|
|
|
|
const char* obj_name = obj_db->get_object_name(i);
|
|
if (!obj_name)
|
|
continue;
|
|
|
|
std::string buf = string_to_lower(sprintf_s_string("ext_skp_%s.txt", obj_name));
|
|
|
|
if (((data_struct*)data)->check_file_exists("rom/skin_param/", buf.c_str())) {
|
|
prj::shared_ptr<key_val> kv = prj::shared_ptr<key_val>(new key_val);
|
|
((data_struct*)data)->load_file(kv.get(), "rom/skin_param/", buf.c_str(), key_val::load_file);
|
|
skin_param_storage.insert({ i, kv });
|
|
}
|
|
}
|
|
}
|
|
|
|
void skin_param_storage_reset() {
|
|
skin_param_storage.clear();
|
|
}
|
|
|
|
osage_setting::osage_setting() {
|
|
|
|
}
|
|
|
|
osage_setting::~osage_setting() {
|
|
|
|
}
|
|
|
|
void osage_setting::clear() {
|
|
cat.clear();
|
|
obj.clear();
|
|
}
|
|
|
|
const osage_setting_osg_cat* osage_setting::get_cat_value(
|
|
object_info* obj_info, const char* root_node) {
|
|
auto elem_obj = osage_setting_data->obj.find(*obj_info);
|
|
if (elem_obj == osage_setting_data->obj.end())
|
|
return 0;
|
|
|
|
auto elem_cat = osage_setting_data->cat.find({ elem_obj->second, root_node });
|
|
if (elem_cat == osage_setting_data->cat.end())
|
|
return 0;
|
|
|
|
return &elem_cat->second;
|
|
}
|
|
|
|
void osage_setting::load() {
|
|
clear();
|
|
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
for (const std::string& i : mdata_manager_get()->GetPrefixes()) {
|
|
std::string file(i);
|
|
file.append("osage_setting.txt");
|
|
aft_data->load_file(this, "rom/skin_param/", file.c_str(), osage_setting_data_load_file);
|
|
}
|
|
}
|
|
|
|
void osage_setting::parse(key_val* kv) {
|
|
int32_t count;
|
|
if (kv->read("cat", "length", count)) {
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
std::string name;
|
|
kv->read("name", name);
|
|
|
|
int32_t count;
|
|
if (kv->read("osg", "length", count)) {
|
|
for (int32_t j = 0; j < count; j++) {
|
|
if (!kv->open_scope_fmt(j))
|
|
continue;
|
|
|
|
int32_t exf = 0;
|
|
kv->read("exf", exf);
|
|
|
|
std::string parts;
|
|
kv->read("parts", parts);
|
|
|
|
std::string root;
|
|
kv->read("root", root);
|
|
|
|
std::pair<std::string, std::string> key = { name, root };
|
|
auto elem = cat.find(key);
|
|
if (elem == cat.end())
|
|
elem = cat.insert({ key, {} }).first;
|
|
|
|
elem->second.exf = exf;
|
|
elem->second.parts = parse_parts_string(parts);
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
object_database* aft_obj_db = &aft_data->data_ft.obj_db;
|
|
|
|
if (kv->read("obj", "length", count)) {
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
std::string cat;
|
|
kv->read("cat", cat);
|
|
|
|
std::string name;
|
|
kv->read("name", name);
|
|
|
|
obj.insert_or_assign(aft_obj_db->get_object_info(name.c_str()), cat);
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
}
|
|
|
|
rob_osage_parts osage_setting::parse_parts_string(std::string& s) {
|
|
static const char* parts_string_array[] = {
|
|
"LEFT", "RIGHT", "CENTER", "LONG_C", "SHORT_L", "SHORT_R",
|
|
"APPEND_L", "APPEND_R", "MUFFLER", "WHITE_ONE_L", "PONY", "ANGEL_L", "ANGEL_R",
|
|
};
|
|
|
|
for (const char*& i : parts_string_array)
|
|
if (!s.compare(i))
|
|
return (rob_osage_parts)(&i - parts_string_array);
|
|
return ROB_OSAGE_PARTS_NONE;
|
|
}
|
|
|
|
skin_param_file::skin_param_file() : file_handler(), id(), type(), data(), rob_chr() {
|
|
|
|
}
|
|
|
|
skin_param_file::~skin_param_file() {
|
|
if (file_handler)
|
|
delete file_handler;
|
|
}
|
|
|
|
static uint8_t skin_param_manager_index = 0;
|
|
|
|
SkinParamManager::SkinParamManager() {
|
|
index = skin_param_manager_index++;
|
|
state = 1;
|
|
}
|
|
|
|
SkinParamManager::~SkinParamManager() {
|
|
state = 1;
|
|
Reset();
|
|
}
|
|
|
|
bool SkinParamManager::init() {
|
|
state = 0;
|
|
AddFiles();
|
|
return true;
|
|
}
|
|
|
|
bool SkinParamManager::ctrl() {
|
|
switch (state) {
|
|
case 0:
|
|
if (CtrlFiles())
|
|
return false;
|
|
|
|
state = 1;
|
|
case 1:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool SkinParamManager::dest() {
|
|
return true;
|
|
}
|
|
|
|
void SkinParamManager::disp() {
|
|
|
|
}
|
|
|
|
bool SkinParamManager::add_task(std::vector<osage_init_data>& vec) {
|
|
if (app::TaskWork::check_task_ready(this) || !app::TaskWork::add_task(this, "SKIN_PARAM_MANAGER"))
|
|
return false;
|
|
|
|
osage_init.assign(vec.begin(), vec.end());
|
|
return true;
|
|
}
|
|
|
|
void SkinParamManager::AddFiles() {
|
|
if (!osage_init.size())
|
|
return;
|
|
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
|
|
|
files.clear();
|
|
for (osage_init_data& i : osage_init) {
|
|
rob_chara_item_equip* rob_itm_equip = i.rob_chr->item_equip;
|
|
for (int32_t j = ITEM_KAMI; j < ITEM_MAX; j++) {
|
|
object_info obj_info = rob_itm_equip->get_object_info((item_id)j);
|
|
if (obj_info.is_null())
|
|
continue;
|
|
|
|
const char* obj_name = object_storage_get_obj_name(obj_info);
|
|
if (!obj_name)
|
|
continue;
|
|
|
|
obj_skin* skin = object_storage_get_obj_skin(obj_info);
|
|
if (!skin || !skin->ex_data)
|
|
return;
|
|
|
|
obj_skin_ex_data* ex_data = skin->ex_data;
|
|
int32_t osage_count = 0;
|
|
int32_t cloth_count = 0;
|
|
|
|
obj_skin_block* b = ex_data->block_array;
|
|
for (int32_t k = ex_data->num_block; k; k--, b++)
|
|
if (b->type == OBJ_SKIN_BLOCK_OSAGE)
|
|
osage_count++;
|
|
else if (b->type == OBJ_SKIN_BLOCK_CLOTH)
|
|
cloth_count++;
|
|
|
|
if (!ex_data || !(osage_count + cloth_count))
|
|
continue;
|
|
|
|
std::string dir;
|
|
std::string farc_file;
|
|
std::string file;
|
|
|
|
dir.assign("rom/skin_param/");
|
|
|
|
farc_file.assign("");
|
|
|
|
file.assign("ext_skp_");
|
|
file.append(obj_name);
|
|
file.append(".txt");
|
|
|
|
skin_param_file* skp_file = new skin_param_file;
|
|
if (!skp_file)
|
|
continue;
|
|
|
|
skp_file->id = (item_id)j;
|
|
skp_file->rob_chr = i.rob_chr;
|
|
skp_file->type = -1;
|
|
|
|
if (i.dir.size()) {
|
|
skp_file->type = GetExtSkpFile(i, i.dir, file, aft_data, aft_mot_db);
|
|
if (skp_file->type != -1)
|
|
dir.assign(i.dir);
|
|
}
|
|
|
|
bool read_farc = false;
|
|
if (skp_file->type == -1) {
|
|
skp_file->type = sp_skp_db_data->get_ext_skp_file(i,
|
|
obj_info, file, farc_file, aft_data, aft_mot_db);
|
|
if (skp_file->type == -1) {
|
|
delete skp_file;
|
|
continue;
|
|
}
|
|
|
|
switch (skp_file->type) {
|
|
case 0:
|
|
case 1:
|
|
read_farc = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
std::vector<skin_param_file_data>* skp_file_data = 0;
|
|
switch (skp_file->type) {
|
|
case 0: {
|
|
skin_param_key key(obj_info, i.motion_id, i.frame);
|
|
auto elem = object_motion_frame.find(key);
|
|
if (elem != object_motion_frame.end()) {
|
|
delete skp_file;
|
|
continue;
|
|
}
|
|
|
|
skp_file_data = new std::vector<skin_param_file_data>;
|
|
object_motion_frame.insert({ key, skp_file_data });
|
|
} break;
|
|
case 1: {
|
|
skin_param_key key(obj_info, i.motion_id);
|
|
auto elem = object_motion.find(key);
|
|
if (elem != object_motion.end()) {
|
|
delete skp_file;
|
|
continue;
|
|
}
|
|
|
|
skp_file_data = new std::vector<skin_param_file_data>;
|
|
object_motion.insert({ key, skp_file_data });
|
|
} break;
|
|
case 2: {
|
|
skin_param_key key(obj_info);
|
|
auto elem = object.find(key);
|
|
if (elem != object.end()) {
|
|
delete skp_file;
|
|
continue;
|
|
}
|
|
|
|
skp_file_data = new std::vector<skin_param_file_data>;
|
|
object.insert({ key, skp_file_data });
|
|
} break;
|
|
}
|
|
|
|
if (!skp_file_data) {
|
|
delete skp_file;
|
|
continue;
|
|
}
|
|
|
|
skp_file_data->resize((size_t)cloth_count + osage_count);
|
|
skp_file->data = skp_file_data;
|
|
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
|
|
p_file_handler* pfhndl = new p_file_handler;
|
|
if (read_farc)
|
|
pfhndl->read_file(aft_data, dir.c_str(), farc_file.c_str(), file.c_str(), false);
|
|
else
|
|
pfhndl->read_file(aft_data, dir.c_str(), file.c_str());
|
|
skp_file->file_handler = pfhndl;
|
|
files.push_back(skp_file);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SkinParamManager::CtrlFiles() {
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
bone_database* aft_bone_data = &aft_data->data_ft.bone_data;
|
|
|
|
for (auto i = files.begin(); i != files.end(); ) {
|
|
skin_param_file* skp_file = *i;
|
|
if (skp_file->file_handler->check_not_ready())
|
|
break;
|
|
else if (skp_file->id <= ITEM_NONE || skp_file->id >= ITEM_MAX) {
|
|
i = files.erase(i);
|
|
continue;
|
|
}
|
|
|
|
rob_chara_item_equip* rob_itm_equip = skp_file->rob_chr->item_equip;
|
|
|
|
key_val kv;
|
|
kv.parse(skp_file->file_handler->get_data(), skp_file->file_handler->get_size());
|
|
|
|
object_info obj_info = rob_itm_equip->get_object_info(skp_file->id);
|
|
if (!obj_info.not_null()) {
|
|
i = files.erase(i);
|
|
continue;
|
|
}
|
|
|
|
rob_chara_item_equip_object* itm_eq_obj = &rob_itm_equip->item_equip_object[skp_file->id];
|
|
|
|
skin_param_file_data* skp_file_data = skp_file->data->data();
|
|
for (ExNodeBlock* j : itm_eq_obj->node_blocks) {
|
|
if (j->type != EX_OSAGE && j->type != EX_CLOTH)
|
|
continue;
|
|
|
|
const char* name = j->name;
|
|
|
|
skin_param_osage_root root;
|
|
skin_param_osage_root_parse(&kv, name, root, aft_bone_data);
|
|
skp_file_data->skin_param.set_skin_param_osage_root(root);
|
|
std::vector<skin_param_osage_node> vec;
|
|
skin_param_osage_node_parse(&kv, name, &vec, root);
|
|
skp_file_data->nodes_data.resize(vec.size());
|
|
rob_itm_equip->skp_load(skp_file->id, root, vec, skp_file_data, aft_bone_data);
|
|
skp_file_data++;
|
|
}
|
|
delete skp_file;
|
|
|
|
i = files.erase(i);
|
|
}
|
|
return !!files.size();
|
|
}
|
|
|
|
int32_t SkinParamManager::GetExtSkpFile(const osage_init_data& osage_init,
|
|
const std::string& dir, std::string& file, void* data, const motion_database* mot_db) {
|
|
if (!dir.size())
|
|
return -1;
|
|
|
|
std::string buf1;
|
|
std::string buf2;
|
|
|
|
if (osage_init.motion_id != -1) {
|
|
const char* motion_name = mot_db->get_motion_name(osage_init.motion_id);
|
|
if (!motion_name)
|
|
return -1;
|
|
|
|
std::string buf;
|
|
if (osage_init.frame > -1) {
|
|
buf = sprintf_s_string("%s_%d_", motion_name, osage_init.frame);
|
|
buf.append(file);
|
|
}
|
|
else {
|
|
buf = sprintf_s_string("%s_", motion_name);
|
|
buf.append(file);
|
|
}
|
|
|
|
buf = string_to_lower(buf);
|
|
|
|
if (((data_struct*)data)->check_file_exists(dir.c_str(), buf.c_str())) {
|
|
file.assign(buf);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (osage_init.pv_id > -1) {
|
|
std::string buf = sprintf_s_string("pv%03d_", osage_init.pv_id);
|
|
buf.append(file);
|
|
|
|
buf = string_to_lower(buf);
|
|
|
|
if (((data_struct*)data)->check_file_exists(dir.c_str(), buf.c_str())) {
|
|
file.assign(buf.c_str());
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (((data_struct*)data)->check_file_exists(dir.c_str(), file.c_str()))
|
|
return 2;
|
|
|
|
return -1;
|
|
}
|
|
|
|
std::vector<skin_param_file_data>* SkinParamManager::GetSkinParamFileData(
|
|
object_info obj_info, uint32_t motion_id, int32_t frame) {
|
|
if (object_motion_frame.size()) {
|
|
auto elem_frame = object_motion_frame.find({ obj_info, motion_id, frame });
|
|
if (elem_frame != object_motion_frame.end())
|
|
return elem_frame->second;
|
|
|
|
auto elem = object_motion_frame.find({ obj_info, motion_id });
|
|
if (elem != object_motion_frame.end())
|
|
return elem->second;
|
|
}
|
|
|
|
if (object_motion.size()) {
|
|
auto elem = object_motion.find({ obj_info, motion_id });
|
|
if (elem != object_motion.end())
|
|
return elem->second;
|
|
}
|
|
|
|
if (object.size()) {
|
|
auto elem = object.find({ obj_info });
|
|
if (elem != object.end())
|
|
return elem->second;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void SkinParamManager::Reset() {
|
|
osage_init.clear();
|
|
|
|
for (auto i : object_motion_frame) {
|
|
if (!i.second)
|
|
continue;
|
|
|
|
delete i.second;
|
|
i.second = 0;
|
|
}
|
|
object_motion_frame.clear();
|
|
|
|
for (auto i : object_motion) {
|
|
if (!i.second)
|
|
continue;
|
|
|
|
delete i.second;
|
|
i.second = 0;
|
|
}
|
|
object_motion.clear();
|
|
|
|
for (auto i : object) {
|
|
if (!i.second)
|
|
continue;
|
|
|
|
delete i.second;
|
|
i.second = 0;
|
|
}
|
|
object.clear();
|
|
|
|
for (skin_param_file*& i : files) {
|
|
if (i->file_handler) {
|
|
delete i->file_handler;
|
|
i->file_handler = 0;
|
|
}
|
|
delete i;
|
|
}
|
|
files.clear();
|
|
|
|
del();
|
|
}
|
|
|
|
sp_skp_db::sp_skp_db() : farc_list_count() {
|
|
|
|
}
|
|
|
|
sp_skp_db::~sp_skp_db() {
|
|
|
|
}
|
|
|
|
void sp_skp_db::clear() {
|
|
pv.clear();
|
|
motion.clear();
|
|
farc_list.clear();
|
|
farc_list.shrink_to_fit();
|
|
farc_list_count = 0;
|
|
}
|
|
|
|
void sp_skp_db::load() {
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
for (const std::string& i : mdata_manager_get()->GetPrefixes()) {
|
|
std::string file(i);
|
|
file.append("sp_skp_db.txt");
|
|
aft_data->load_file(this, "rom/skin_param/", file.c_str(), sp_skp_db_load_file);
|
|
}
|
|
}
|
|
|
|
void sp_skp_db::parse(key_val* kv) {
|
|
data_struct* aft_data = &data_list[DATA_AFT];
|
|
object_database* aft_obj_db = &aft_data->data_ft.obj_db;
|
|
|
|
size_t farc_list_count = this->farc_list_count;
|
|
|
|
int32_t count;
|
|
if (kv->read("motion", "length", count)) {
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
std::string name;
|
|
if (!kv->read("name", name))
|
|
continue;
|
|
|
|
std::shared_ptr<std::map<object_info, uint32_t>> skp
|
|
= std::make_shared< std::map<object_info, uint32_t>>();
|
|
|
|
motion.insert({ name, skp });
|
|
|
|
int32_t count;
|
|
if (kv->read("skp", "length", count)) {
|
|
for (int32_t j = 0; j < count; j++) {
|
|
if (!kv->open_scope_fmt(j))
|
|
continue;
|
|
|
|
const char* obj;
|
|
int32_t farc;
|
|
if (!kv->read("obj", obj) || !kv->read("farc", farc))
|
|
continue;
|
|
|
|
skp->insert({ aft_obj_db->get_object_info(obj),
|
|
(uint32_t)(farc_list_count + farc) });
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
|
|
if (kv->read("pv", "length", count)) {
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
std::string name;
|
|
if (!kv->read("name", name) || name.size() != 5)
|
|
continue;
|
|
|
|
std::shared_ptr<std::map<object_info, uint32_t>> skp
|
|
= std::make_shared< std::map<object_info, uint32_t>>();
|
|
|
|
int32_t pv_id = (name[2] - '0') * 100;
|
|
pv_id += (name[3] - '0') * 10;
|
|
pv_id += name[4] - '0';
|
|
|
|
pv.insert({ pv_id, skp });
|
|
|
|
int32_t count;
|
|
if (kv->read("skp", "length", count)) {
|
|
for (int32_t j = 0; j < count; j++) {
|
|
if (!kv->open_scope_fmt(j))
|
|
continue;
|
|
|
|
const char* obj;
|
|
int32_t farc;
|
|
if (!kv->read("obj", obj) || !kv->read("farc", farc))
|
|
continue;
|
|
|
|
skp->insert({ aft_obj_db->get_object_info(obj),
|
|
(uint32_t)(farc_list_count + farc) });
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
}
|
|
|
|
if (kv->read("farc_list", "length", count)) {
|
|
farc_list.resize(farc_list_count + count);
|
|
std::string* vfl = farc_list.data();
|
|
for (int32_t i = 0; i < count; i++) {
|
|
if (!kv->open_scope_fmt(i))
|
|
continue;
|
|
|
|
kv->read(vfl[farc_list_count + i]);
|
|
kv->close_scope();
|
|
}
|
|
kv->close_scope();
|
|
this->farc_list_count = farc_list_count + count;
|
|
}
|
|
}
|
|
|
|
int32_t sp_skp_db::get_ext_skp_file(const osage_init_data& osage_init,
|
|
const object_info obj_info, std::string& file, std::string& farc,
|
|
void* data, const motion_database* mot_db) {
|
|
if (obj_info.is_null())
|
|
return 2;
|
|
|
|
int32_t type = 2;
|
|
farc.clear();
|
|
if (osage_init.pv_id > -1) {
|
|
auto elem0 = pv.find(osage_init.pv_id);
|
|
if (elem0 != pv.end()) {
|
|
auto elem1 = elem0->second->find(obj_info);
|
|
if (elem1 != elem0->second->end()) {
|
|
type = 1;
|
|
farc.assign(farc_list[elem1->second]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (osage_init.motion_id != -1) {
|
|
const char* motion_name = mot_db->get_motion_name(osage_init.motion_id);
|
|
if (motion_name) {
|
|
std::string buf(motion_name);
|
|
if (osage_init.frame > -1)
|
|
buf = sprintf_s_string("%s_%d", motion_name, osage_init.frame);
|
|
|
|
auto elem0 = motion.find(buf);
|
|
if (elem0 != motion.end()) {
|
|
auto elem1 = elem0->second->find(obj_info);
|
|
if (elem1 != elem0->second->end()) {
|
|
type = 0;
|
|
farc.assign(farc_list[elem1->second]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const char* obj_name = object_storage_get_obj_name(obj_info);
|
|
std::string skp_file = sprintf_s_string("ext_skp_%s.txt", obj_name);
|
|
|
|
switch (type) {
|
|
case 0: {
|
|
std::string motion_name(mot_db->get_motion_name(osage_init.motion_id));
|
|
if (osage_init.frame > -1)
|
|
motion_name = sprintf_s_string("%s_%d", motion_name.c_str(), osage_init.frame);
|
|
|
|
std::string buf = sprintf_s_string("%s_", motion_name.c_str());
|
|
buf.append(skp_file);
|
|
skp_file.assign(buf);
|
|
} break;
|
|
case 1: {
|
|
std::string buf = sprintf_s_string("pv%03d_", osage_init.pv_id);
|
|
buf.append(skp_file);
|
|
skp_file.assign(buf);
|
|
} break;
|
|
}
|
|
|
|
skp_file = string_to_lower(skp_file);
|
|
|
|
if (type == 2 && !((data_struct*)data)->check_file_exists("rom/skin_param/", skp_file.c_str())) {
|
|
file.clear();
|
|
type = -1;
|
|
}
|
|
else
|
|
file.assign(skp_file);
|
|
return type;
|
|
}
|
|
|
|
static bool osage_setting_data_load_file(void* data, const char* dir, const char* file, uint32_t hash) {
|
|
key_val kv;
|
|
if (key_val::load_file(&kv, dir, file, hash)) {
|
|
((osage_setting*)data)->parse(&kv);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static SkinParamManager* skin_param_manager_get(int32_t chara_id) {
|
|
if (chara_id < 0 || chara_id > 6)
|
|
chara_id = 0;
|
|
return &skin_param_manager[chara_id];
|
|
}
|
|
|
|
static bool sp_skp_db_load_file(void* data, const char* dir, const char* file, uint32_t hash) {
|
|
key_val kv;
|
|
if (key_val::load_file(&kv, dir, file, hash)) {
|
|
((sp_skp_db*)data)->parse(&kv);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|