Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom models: option to copy mod/eye draws from original model #3800

Merged
merged 3 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions common/util/gltf_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,4 +756,89 @@ tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector<math::Vector<u8, 4>>&
return colors;
}

void process_normal_merc_draw(const tinygltf::Model& model,
MercExtractData& out,
u32 tex_offset,
tfrag3::MercEffect& eff,
int mat_idx,
const tfrag3::MercDraw& d_) {
const auto& mat = model.materials[mat_idx];
eff.all_draws.push_back(d_);
auto& draw = eff.all_draws.back();
draw.mode = gltf_util::make_default_draw_mode();

if (mat_idx == -1) {
lg::warn("Draw had a material index of -1, using default texture.");
draw.tree_tex_id = 0;
return;
}
int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
if (tex_idx == -1) {
lg::warn("Material {} has no texture, using default texture.", mat.name);
draw.tree_tex_id = 0;
return;
}

const auto& tex = model.textures[tex_idx];
ASSERT(tex.sampler >= 0);
ASSERT(tex.source >= 0);
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(tex.sampler), &draw.mode);
gltf_util::setup_alpha_from_material(mat, &draw.mode);

const auto& img = model.images[tex.source];
draw.tree_tex_id = tex_offset + texture_pool_add_texture(&out.tex_pool, img);
};

void process_envmap_merc_draw(const tinygltf::Model& model,
MercExtractData& out,
u32 tex_offset,
tfrag3::MercEffect& eff,
int mat_idx,
const tfrag3::MercDraw& d_) {
const auto& mat = model.materials[mat_idx];
eff.all_draws.push_back(d_);
auto& draw = eff.all_draws.back();
draw.mode = gltf_util::make_default_draw_mode();

if (mat_idx == -1) {
lg::warn("Envmap draw had a material index of -1, using default texture.");
draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool);
return;
}
int base_tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
if (base_tex_idx == -1) {
lg::warn("Envmap material {} has no texture, using default texture.", mat.name);
draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool);
return;
}

const auto& base_tex = model.textures[base_tex_idx];
ASSERT(base_tex.sampler >= 0);
ASSERT(base_tex.source >= 0);
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode);
gltf_util::setup_alpha_from_material(mat, &draw.mode);
const auto& roughness_tex =
model.textures.at(mat.pbrMetallicRoughness.metallicRoughnessTexture.index);
ASSERT(roughness_tex.sampler >= 0);
ASSERT(roughness_tex.source >= 0);

draw.tree_tex_id =
tex_offset + gltf_util::texture_pool_add_envmap_control_texture(
&out.tex_pool, model, base_tex.source, roughness_tex.source,
!draw.mode.get_clamp_s_enable(), !draw.mode.get_clamp_t_enable());

// now, setup envmap draw:
auto envmap_settings = gltf_util::envmap_settings_from_gltf(mat);
const auto& envmap_tex = model.textures[envmap_settings.texture_idx];
ASSERT(envmap_tex.sampler >= 0);
ASSERT(envmap_tex.source >= 0);
auto env_mode = gltf_util::make_default_draw_mode();
gltf_util::setup_draw_mode_from_sampler(model.samplers.at(envmap_tex.sampler), &env_mode);
eff.envmap_texture = tex_offset + gltf_util::texture_pool_add_texture(
&out.tex_pool, model.images[envmap_tex.source]);
env_mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_0_DST_DST);
env_mode.enable_ab();
eff.envmap_mode = env_mode;
};

} // namespace gltf_util
31 changes: 31 additions & 0 deletions common/util/gltf_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,35 @@ math::Matrix4f matrix_from_trs(const math::Vector3f& trans,

tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector<math::Vector<u8, 4>>& color_palette);

struct MercExtractData {
TexturePool tex_pool;
std::vector<u32> new_indices;
std::vector<tfrag3::PreloadedVertex> new_vertices;
std::vector<math::Vector<u8, 4>> new_colors;
std::vector<math::Vector3f> normals;
std::vector<JointsAndWeights> joints_and_weights;
tfrag3::MercModel new_model;
};

// Data produced by loading a replacement model
struct MercSwapData {
std::vector<u32> new_indices;
std::vector<tfrag3::MercVertex> new_vertices;
std::vector<tfrag3::Texture> new_textures;
tfrag3::MercModel new_model;
};

void process_normal_merc_draw(const tinygltf::Model& model,
MercExtractData& out,
u32 tex_offset,
tfrag3::MercEffect& eff,
int mat_idx,
const tfrag3::MercDraw& d_);
void process_envmap_merc_draw(const tinygltf::Model& model,
MercExtractData& out,
u32 tex_offset,
tfrag3::MercEffect& eff,
int mat_idx,
const tfrag3::MercDraw& d_);

} // namespace gltf_util
4 changes: 4 additions & 0 deletions custom_assets/blender_plugins/opengoal.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def draw_func_ob(self, context):
ob = context.object
layout.prop(ob, "set_invisible")
layout.prop(ob, "enable_custom_weights")
layout.prop(ob, "copy_eye_draws")
layout.prop(ob, "copy_mod_draws")
layout.prop(ob, "set_collision")
if (ob.set_collision):
layout.prop(ob, "ignore")
Expand Down Expand Up @@ -118,6 +120,8 @@ def register():
bpy.types.Object.set_invisible = bpy.props.BoolProperty(name="Invisible")
bpy.types.Object.set_collision = bpy.props.BoolProperty(name="Apply Collision Properties")
bpy.types.Object.enable_custom_weights = bpy.props.BoolProperty(name="Use Custom Bone Weights")
bpy.types.Object.copy_eye_draws = bpy.props.BoolProperty(name="Copy Eye Draws")
bpy.types.Object.copy_mod_draws = bpy.props.BoolProperty(name="Copy Mod Draws")
bpy.types.Object.ignore = bpy.props.BoolProperty(name="ignore")
bpy.types.Object.noedge = bpy.props.BoolProperty(name="No-Edge")
bpy.types.Object.noentity = bpy.props.BoolProperty(name="No-Entity")
Expand Down
3 changes: 0 additions & 3 deletions decompiler/IR2/FormExpressionAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2603,9 +2603,6 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
ASSERT(x->parent_form == m_src);
}

if (auto test0 = m_src->to_string(env) == "(* 0.00024414062 (-> arg0 y))") {
printf("");
}
if (m_src->is_single_element()) {
auto src_as_se = dynamic_cast<SimpleExpressionElement*>(m_src->back());
if (src_as_se) {
Expand Down
10 changes: 10 additions & 0 deletions decompiler/level_extractor/extract_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ void extract_art_groups_from_level(const ObjectFileDB& db,
if (db.obj_files_by_dgo.count(dgo_name)) {
const auto& files = db.obj_files_by_dgo.at(dgo_name);
MercSwapInfo swapped_info;
// build list of models to replace
auto merc_replacements_path = file_util::get_jak_project_dir() / "custom_assets" /
game_version_names[db.version()] / "merc_replacements";
if (file_util::file_exists(merc_replacements_path.string())) {
auto custom_models =
file_util::find_files_in_dir(merc_replacements_path, std::regex(".*\\.glb"));
for (auto& mdl : custom_models) {
swapped_info.add_to_swap_list(mdl.stem().string());
}
}
for (const auto& file : files) {
if (file.name.length() > 3 && !file.name.compare(file.name.length() - 3, 3, "-ag")) {
const auto& ag_file = db.lookup_record(file);
Expand Down
7 changes: 7 additions & 0 deletions decompiler/level_extractor/extract_level.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ namespace decompiler {

// info about what models have been replaced/added per level
struct MercSwapInfo {
std::vector<std::string> swap_list;
std::map<std::string, std::vector<std::string>> per_level_merc_swaps;
std::map<std::string, std::vector<std::string>> per_level_custom_mdls;

bool should_swap(const std::string& model) {
return std::find(swap_list.begin(), swap_list.end(), model) != swap_list.end();
}

bool already_swapped(const std::string& model, const std::string& level) {
auto mdls_it = per_level_merc_swaps.find(level);
if (mdls_it != per_level_merc_swaps.end()) {
Expand All @@ -35,6 +40,8 @@ struct MercSwapInfo {
return false;
}

void add_to_swap_list(const std::string& model) { swap_list.push_back(model); }

void add_to_swapped_list(const std::string& model, const std::string& level) {
per_level_merc_swaps[level].push_back(model);
}
Expand Down
38 changes: 20 additions & 18 deletions decompiler/level_extractor/extract_merc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,7 @@ void replace_model(tfrag3::Level& lvl, tfrag3::MercModel& model, const fs::path&
}
}

auto swap_info = load_replacement_merc_model(model.name, lvl.merc_data.indices.size(),
auto swap_info = load_replacement_merc_model(model, lvl.merc_data.indices.size(),
lvl.merc_data.vertices.size(), lvl.textures.size(),
mdl_path.string(), old_verts, false);
model = swap_info.new_model;
Expand All @@ -1647,8 +1647,8 @@ void add_custom_model_to_level(tfrag3::Level& lvl,
auto lvl_name = lvl.level_name == "" ? "common" : lvl.level_name;
lg::info("Adding custom model {} to {}", name, lvl_name);
auto merc_data =
load_replacement_merc_model(name, lvl.merc_data.indices.size(), lvl.merc_data.vertices.size(),
lvl.textures.size(), mdl_path.string(), {}, true);
load_custom_merc_model(name, lvl.merc_data.indices.size(), lvl.merc_data.vertices.size(),
lvl.textures.size(), mdl_path.string(), {}, true);
for (auto& idx : merc_data.new_indices) {
lvl.merc_data.indices.push_back(idx);
}
Expand Down Expand Up @@ -1798,23 +1798,25 @@ void extract_merc(const ObjectFileData& ag_data,

// do model replacement if present
for (auto& ctrl : ctrls) {
auto merc_replacements_path = file_util::get_jak_project_dir() / "custom_assets" /
game_version_names[version] / "merc_replacements";
if (!swapped_info.already_swapped(ctrl.name, out.level_name)) {
if (file_util::file_exists(merc_replacements_path.string())) {
std::string file_name(ctrl.name + ".glb");
auto mdl_path = merc_replacements_path / file_name;
if (file_util::file_exists(mdl_path.string())) {
auto it = std::find_if(out.merc_data.models.begin(), out.merc_data.models.end(),
[&](const auto& m) { return m.name == ctrl.name; });
if (it != out.merc_data.models.end()) {
auto& model = *it;
replace_model(out, model, mdl_path);
swapped_info.add_to_swapped_list(ctrl.name, out.level_name);
if (swapped_info.should_swap(ctrl.name)) {
auto merc_replacements_path = file_util::get_jak_project_dir() / "custom_assets" /
game_version_names[version] / "merc_replacements";
if (!swapped_info.already_swapped(ctrl.name, out.level_name)) {
if (file_util::file_exists(merc_replacements_path.string())) {
std::string file_name(ctrl.name + ".glb");
auto mdl_path = merc_replacements_path / file_name;
if (file_util::file_exists(mdl_path.string())) {
auto it = std::find_if(out.merc_data.models.begin(), out.merc_data.models.end(),
[&](const auto& m) { return m.name == ctrl.name; });
if (it != out.merc_data.models.end()) {
auto& model = *it;
replace_model(out, model, mdl_path);
swapped_info.add_to_swapped_list(ctrl.name, out.level_name);
}
}
} else {
lg::info("{} in level {} was already swapped, skipping", ctrl.name, out.level_name);
}
} else {
lg::info("{} in level {} was already swapped, skipping", ctrl.name, out.level_name);
}
}

Expand Down
Loading
Loading