ReignEngine: Fix out-of-range material index in .POL

Without this, some maps (e.g. map059) and battle backgrounds
(e.g. bg101) in Toushin Toshi 3 are not rendered correctly.
This commit is contained in:
kichikuou
2022-12-24 16:54:41 +09:00
parent 2de5132803
commit c7cebb9ea9
3 changed files with 18 additions and 12 deletions
+1 -1
View File
@@ -430,7 +430,7 @@ struct pol_triangle {
uint32_t uv_index[3];
uint32_t light_uv_index[3];
vec3 normals[3];
uint32_t material; // index in the material group
uint32_t material_group_index;
};
struct pol_bone {
+3 -3
View File
@@ -214,7 +214,7 @@ static void *buf_alloc(uint8_t **ptr, int size)
return p;
}
static void add_mesh(struct model *model, struct pol_mesh *m, int material_index, int material)
static void add_mesh(struct model *model, struct pol_mesh *m, uint32_t material_group_index, int material)
{
bool has_light_map = m->light_uvs && model->materials[material].light_map;
bool has_normal_map = model->materials[material].normal_map != 0;
@@ -234,7 +234,7 @@ static void add_mesh(struct model *model, struct pol_mesh *m, int material_index
int nr_vertices = 0;
for (uint32_t i = 0; i < m->nr_triangles; i++) {
struct pol_triangle *t = &m->triangles[i];
if (material_index >= 0 && t->material != (uint32_t)material_index)
if (t->material_group_index != material_group_index)
continue;
vec4 tangent[3];
if (has_normal_map)
@@ -465,7 +465,7 @@ struct model *model_load(struct archive *aar, const char *path)
struct pol_material_group *mg = &pol->materials[pol->meshes[i]->material];
int m_off = material_offsets[pol->meshes[i]->material];
if (mg->nr_children == 0) {
add_mesh(model, pol->meshes[i], -1, m_off);
add_mesh(model, pol->meshes[i], 0, m_off);
continue;
}
for (uint32_t j = 0; j < mg->nr_children; j++) {
+14 -8
View File
@@ -134,7 +134,7 @@ static void destroy_vertex(struct pol_vertex *v)
free(v->weights);
}
static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle_index, int unknowns_length)
static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle_index, int unknowns_length, const struct pol_material_group *mg)
{
struct pol_triangle *t = &mesh->triangles[triangle_index];
t->vert_index[0] = buffer_read_int32(r);
@@ -154,7 +154,9 @@ static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle
read_direction(r, t->normals[0]);
read_direction(r, t->normals[1]);
read_direction(r, t->normals[2]);
t->material = buffer_read_int32(r);
t->material_group_index = buffer_read_int32(r);
if (t->material_group_index >= mg->nr_children)
t->material_group_index = 0;
}
static uint32_t parse_mesh_attributes(const char *name)
@@ -173,7 +175,7 @@ static uint32_t parse_mesh_attributes(const char *name)
return flags;
}
static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
static struct pol_mesh *parse_mesh(struct buffer *r, const struct pol *pol)
{
int type = buffer_read_int32(r);
if (type != 0) {
@@ -185,11 +187,15 @@ static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
mesh->name = read_cstring(r);
mesh->flags = parse_mesh_attributes(mesh->name);
mesh->material = buffer_read_int32(r);
if (mesh->material >= pol->nr_materials) {
WARNING("material index out of range (%d >= %d)", mesh->material, pol->nr_materials);
mesh->material = 0;
}
mesh->nr_vertices = buffer_read_int32(r);
mesh->vertices = xcalloc(mesh->nr_vertices, sizeof(struct pol_vertex));
for (uint32_t i = 0; i < mesh->nr_vertices; i++) {
parse_vertex(r, pol_version, &mesh->vertices[i]);
parse_vertex(r, pol->version, &mesh->vertices[i]);
}
mesh->nr_uvs = buffer_read_int32(r);
@@ -209,7 +215,7 @@ static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
}
int triangle_unknowns_length = 12;
if (pol_version == 1) {
if (pol->version == 1) {
int nr_unknown_vecs = buffer_read_int32(r);
buffer_skip(r, nr_unknown_vecs * 12);
} else {
@@ -225,10 +231,10 @@ static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
mesh->nr_triangles = buffer_read_int32(r);
mesh->triangles = xcalloc(mesh->nr_triangles, sizeof(struct pol_triangle));
for (uint32_t i = 0; i < mesh->nr_triangles; i++) {
parse_triangle(r, mesh, i, triangle_unknowns_length);
parse_triangle(r, mesh, i, triangle_unknowns_length, &pol->materials[mesh->material]);
}
if (pol_version == 1) {
if (pol->version == 1) {
if (buffer_read_int32(r) != 1)
WARNING("unexpected mesh footer");
if (buffer_read_int32(r) != 0)
@@ -290,7 +296,7 @@ struct pol *pol_parse(uint8_t *data, size_t size)
pol->nr_meshes = buffer_read_int32(&r);
pol->meshes = xcalloc(pol->nr_meshes, sizeof(struct pol_mesh *));
for (uint32_t i = 0; i < pol->nr_meshes; i++) {
pol->meshes[i] = parse_mesh(&r, pol->version);
pol->meshes[i] = parse_mesh(&r, pol);
}
pol->nr_bones = buffer_read_int32(&r);