From ec058221b58515973f4bf6c5e32662ae94ee13ab Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sat, 9 Sep 2023 11:56:18 -0400 Subject: [PATCH] [jak1] Fix duplicated tie extract (#2972) Fix a bug where meshes are extracted too many times. --- decompiler/level_extractor/fr3_to_gltf.cpp | 52 +++++++++++++--------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/decompiler/level_extractor/fr3_to_gltf.cpp b/decompiler/level_extractor/fr3_to_gltf.cpp index ad6fddade4..0ed11afafd 100644 --- a/decompiler/level_extractor/fr3_to_gltf.cpp +++ b/decompiler/level_extractor/fr3_to_gltf.cpp @@ -51,24 +51,32 @@ void unstrip_shrub_draws(const std::vector& stripped_indices, } void unstrip_tie_wind(std::vector& unstripped, - std::vector& draw_to_start, - std::vector& draw_to_count, + std::vector>& draw_to_starts, + std::vector>& draw_to_counts, const std::vector& draws) { for (auto& draw : draws) { - draw_to_start.push_back(unstripped.size()); + auto& starts = draw_to_starts.emplace_back(); + auto& counts = draw_to_counts.emplace_back(); - for (size_t i = 2; i < draw.vertex_index_stream.size(); i++) { - u32 a = draw.vertex_index_stream[i]; - u32 b = draw.vertex_index_stream[i - 1]; - u32 c = draw.vertex_index_stream[i - 2]; - if (a == UINT32_MAX || b == UINT32_MAX || c == UINT32_MAX) { - continue; + int grp_offset = 0; + + for (const auto& grp : draw.instance_groups) { + starts.push_back(unstripped.size()); + + for (size_t i = grp_offset + 2; i < grp_offset + grp.num; i++) { + u32 a = draw.vertex_index_stream.at(i); + u32 b = draw.vertex_index_stream.at(i - 1); + u32 c = draw.vertex_index_stream.at(i - 2); + if (a == UINT32_MAX || b == UINT32_MAX || c == UINT32_MAX) { + continue; + } + unstripped.push_back(a); + unstripped.push_back(b); + unstripped.push_back(c); } - unstripped.push_back(a); - unstripped.push_back(b); - unstripped.push_back(c); + counts.push_back(unstripped.size() - starts.back()); + grp_offset += grp.num; } - draw_to_count.push_back(unstripped.size() - draw_to_start.back()); } } @@ -408,10 +416,10 @@ int make_tfrag_tie_index_buffer_view(const std::vector& indices, int make_tie_wind_index_buffer_view(const std::vector& draws, tinygltf::Model& model, - std::vector& draw_to_start, - std::vector& draw_to_count) { + std::vector>& draw_to_starts, + std::vector>& draw_to_counts) { std::vector unstripped; - unstrip_tie_wind(unstripped, draw_to_start, draw_to_count, draws); + unstrip_tie_wind(unstripped, draw_to_starts, draw_to_counts, draws); // first create a buffer: int buffer_idx = (int)model.buffers.size(); @@ -666,15 +674,16 @@ void add_tie(const tfrag3::Level& level, } if (!tie.instanced_wind_draws.empty()) { - std::vector draw_to_start, draw_to_count; + std::vector> draw_to_starts, draw_to_counts; int wind_index_buffer_view = make_tie_wind_index_buffer_view(tie.instanced_wind_draws, model, - draw_to_start, draw_to_count); + draw_to_starts, draw_to_counts); for (size_t draw_idx = 0; draw_idx < tie.instanced_wind_draws.size(); draw_idx++) { const auto& wind_draw = tie.instanced_wind_draws[draw_idx]; int mat = add_material_for_tex(level, model, wind_draw.tree_tex_id, tex_image_map, wind_draw.mode); - for (const auto& grp : wind_draw.instance_groups) { + for (size_t grp_idx = 0; grp_idx < wind_draw.instance_groups.size(); grp_idx++) { + const auto& grp = wind_draw.instance_groups[grp_idx]; int c_node_idx = (int)model.nodes.size(); auto& c_node = model.nodes.emplace_back(); model.nodes[node_idx].children.push_back(c_node_idx); @@ -692,8 +701,9 @@ void add_tie(const tfrag3::Level& level, } prim.material = mat; - prim.indices = make_index_buffer_accessor( - model, draw_to_start.at(draw_idx), draw_to_count.at(draw_idx), wind_index_buffer_view); + prim.indices = make_index_buffer_accessor(model, draw_to_starts.at(draw_idx).at(grp_idx), + draw_to_counts.at(draw_idx).at(grp_idx), + wind_index_buffer_view); prim.attributes["POSITION"] = position_buffer_accessor; prim.attributes["TEXCOORD_0"] = texture_buffer_accessor; for (int i = 0; i < kMaxColor; i++) {