jak1, jak2, jak3: fix custom model visibility (#4070)

Resolves #3698

This is a known issue confirmed by HatKid after the release of the build
actor tool as something that came up during testing.

There is a problem which is you can't go over 255 vertices or faces in a
single collision primitive. The solution then is to split a single
object into two different primitives. This is what's done in the real
game.

The problem here is that the build actor tool also doesn't support
splitting an object into multiple objects in Blender. If you do, any
subsequent objects appear invisible. This is because the pipeline for
building materials is single-object. If you have a material on multiple
objects in Blender, only one gets built and any subsequent uses get
skipped as they were presumed to have already been built.

This simple fix adds an additional check to check both materials AND
objects when building materials.

This is a pretty important fix, as there's no way to get around the 255
hex limit, so at that point you have no choice but to separate objects
into two separate Blender objects. At this point, it doesn't make sense
to not be able to display the same material on multiple Blender objects.

This affects BOTH collision meshes as well as visual meshes.

This is also a particular issue for non-armature actors.


[Here](https://discord.com/channels/967812267351605298/989587365884485732/1310328952069296290)
is an example of others stumbling across this problem. The solution
found was to make sure all objects were in a single object.

Before this PR:

<video controls
src="https://github.com/user-attachments/assets/fabcd951-d855-4d52-8ed0-0aeea0b75414"></video>

After this PR:

<video controls
src="https://github.com/user-attachments/assets/3e3b7d53-e4ed-43bb-aef1-08cc147d44c0"></video>
This commit is contained in:
Grateful Forest 2025-12-09 09:21:33 +10:30 committed by GitHub
parent e2f14f459d
commit c60ae23e59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 5 additions and 5 deletions

View File

@ -14,7 +14,7 @@ void extract(const std::string& name,
u32 tex_offset) {
ASSERT(out.new_vertices.empty());
std::map<int, tfrag3::MercDraw> draw_by_material;
std::map<std::pair<int, int>, tfrag3::MercDraw> draw_by_material;
int mesh_count = 0;
int prim_count = 0;
int joints = 3;
@ -77,7 +77,7 @@ void extract(const std::string& name,
}
// real draw details will be filled out in the next loop.
auto& draw = draw_by_material[prim.material];
auto& draw = draw_by_material[{prim.material, n.node_idx}];
draw.mode = gltf_util::make_default_draw_mode(); // todo rm
draw.tree_tex_id = 0; // todo rm
draw.num_triangles += prim_indices.size() / 3;
@ -96,8 +96,8 @@ void extract(const std::string& name,
out.new_model.max_bones = joints;
out.new_model.max_draws = 0;
for (const auto& [mat_idx, d_] : draw_by_material) {
const auto& mat = model.materials[mat_idx];
for (const auto& [key, d_] : draw_by_material) {
int mat_idx = key.first;
if (mat_idx < 0 || !gltf_util::material_has_envmap(model.materials[mat_idx]) ||
!gltf_util::envmap_is_valid(model.materials[mat_idx])) {
gltf_util::process_normal_merc_draw(model, out, tex_offset, e, mat_idx, d_);