Load inverse bind matrices into model

This commit is contained in:
Camden Dixie O'Brien committed 2025-10-01 14:28:05 +01:00
1 parent 2e1a604d7b
commit ec29f44db0
3 files changed
+37 -3

No files matched your search

+5 -1
View File
@@ -29,6 +29,10 @@ void model_cleanup(model_t *m)
if (m->bones != nullptr) { if (m->bones != nullptr) {
free(m->bones); free(m->bones);
m->bones = nullptr; m->bones = nullptr;
m->bone_count = 0;
} }
if (m->inverse_bind_matrices != nullptr) {
free(m->inverse_bind_matrices);
m->inverse_bind_matrices = nullptr;
}
m->vertex_count = m->index_count = m->bone_count = 0;
} }
+1
View File
@@ -26,6 +26,7 @@ typedef struct {
vertex_t *vertices; vertex_t *vertices;
index_t *indices; index_t *indices;
bone_t *bones; bone_t *bones;
mat4_t *inverse_bind_matrices;
size_t vertex_count; size_t vertex_count;
size_t index_count; size_t index_count;
size_t bone_count; size_t bone_count;
+31 -2
View File
@@ -98,6 +98,7 @@ typedef struct {
accessor_t bone_indices; accessor_t bone_indices;
accessor_t weights; accessor_t weights;
accessor_t indices; accessor_t indices;
accessor_t inverse_bind_matrices;
} accessors_t; } accessors_t;
typedef struct { typedef struct {
@@ -112,6 +113,7 @@ typedef struct {
view_t bone_indices; view_t bone_indices;
view_t weights; view_t weights;
view_t indices; view_t indices;
view_t inverse_bind_matrices;
} views_t; } views_t;
typedef struct { typedef struct {
@@ -126,6 +128,7 @@ typedef struct {
gltf_info_member_t bone_indices; gltf_info_member_t bone_indices;
gltf_info_member_t weights; gltf_info_member_t weights;
gltf_info_member_t indices; gltf_info_member_t indices;
gltf_info_member_t inverse_bind_matrices;
size_t vertex_count, index_count, bone_count; size_t vertex_count, index_count, bone_count;
} gltf_info_t; } gltf_info_t;
@@ -580,7 +583,7 @@ static accessor_t read_accessor(const uint8_t **p)
return accessor; return accessor;
} }
static accessors_t read_accessors(const uint8_t *p, mesh_t mesh) static accessors_t read_accessors(const uint8_t *p, mesh_t mesh, skin_t skin)
{ {
accessors_t accessors = {}; accessors_t accessors = {};
assert(*p == '['); assert(*p == '[');
@@ -596,11 +599,20 @@ static accessors_t read_accessors(const uint8_t *p, mesh_t mesh)
accessors.weights = read_accessor(&p); accessors.weights = read_accessor(&p);
else if (i == mesh.indices) else if (i == mesh.indices)
accessors.indices = read_accessor(&p); accessors.indices = read_accessor(&p);
else if (i == skin.inverse_bind_matrices)
accessors.inverse_bind_matrices = read_accessor(&p);
else else
skip_value(&p); skip_value(&p);
if (*p == ',') if (*p == ',')
++p; ++p;
} }
assert(accessors.normals.count != 0);
assert(accessors.positions.count != 0);
assert(accessors.bone_indices.count != 0);
assert(accessors.weights.count != 0);
assert(accessors.indices.count != 0);
assert(accessors.inverse_bind_matrices.count != 0);
return accessors; return accessors;
} }
@@ -652,6 +664,8 @@ static views_t read_views(const uint8_t *p, accessors_t accessors)
views.weights = read_view(&p); views.weights = read_view(&p);
else if (i == accessors.indices.view) else if (i == accessors.indices.view)
views.indices = read_view(&p); views.indices = read_view(&p);
else if (i == accessors.inverse_bind_matrices.view)
views.inverse_bind_matrices = read_view(&p);
else else
skip_value(&p); skip_value(&p);
@@ -667,6 +681,7 @@ static views_t read_views(const uint8_t *p, accessors_t accessors)
assert(views.bone_indices.len != 0); assert(views.bone_indices.len != 0);
assert(views.weights.len != 0); assert(views.weights.len != 0);
assert(views.indices.len != 0); assert(views.indices.len != 0);
assert(views.inverse_bind_matrices.len != 0);
return views; return views;
} }
@@ -728,7 +743,7 @@ static gltf_info_t read_json(const uint8_t *json)
assert(bones != nullptr); assert(bones != nullptr);
read_joints(nodes_json, skin, bones); read_joints(nodes_json, skin, bones);
const accessors_t accessors = read_accessors(accessors_json, mesh); const accessors_t accessors = read_accessors(accessors_json, mesh, skin);
const views_t views = read_views(views_json, accessors); const views_t views = read_views(views_json, accessors);
// Verify data types // Verify data types
@@ -747,6 +762,9 @@ static gltf_info_t read_json(const uint8_t *json)
assert( assert(
accessors.indices.component == COMPONENT_TYPE_U16 accessors.indices.component == COMPONENT_TYPE_U16
&& accessors.indices.type == ACCESSOR_TYPE_SCALAR); && accessors.indices.type == ACCESSOR_TYPE_SCALAR);
assert(
accessors.inverse_bind_matrices.component == COMPONENT_TYPE_F32
&& accessors.inverse_bind_matrices.type == ACCESSOR_TYPE_MAT4);
// Ensure the vertex count is consistent // Ensure the vertex count is consistent
assert( assert(
@@ -754,6 +772,9 @@ static gltf_info_t read_json(const uint8_t *json)
&& accessors.positions.count == accessors.bone_indices.count && accessors.positions.count == accessors.bone_indices.count
&& accessors.positions.count == accessors.weights.count); && accessors.positions.count == accessors.weights.count);
// Ensure the joint count is consistent
assert(accessors.inverse_bind_matrices.count == skin.joint_count);
return (gltf_info_t) { return (gltf_info_t) {
.bones = bones, .bones = bones,
.positions = info_member(accessors.positions, views.positions), .positions = info_member(accessors.positions, views.positions),
@@ -764,6 +785,8 @@ static gltf_info_t read_json(const uint8_t *json)
.indices = info_member(accessors.indices, views.indices), .indices = info_member(accessors.indices, views.indices),
.vertex_count = accessors.positions.count, .vertex_count = accessors.positions.count,
.index_count = accessors.indices.count, .index_count = accessors.indices.count,
.inverse_bind_matrices = info_member(
accessors.inverse_bind_matrices, views.inverse_bind_matrices),
.bone_count = skin.joint_count, .bone_count = skin.joint_count,
}; };
} }
@@ -817,6 +840,12 @@ model_t model_format_glb_read(const char *path)
(const u16_vec4_t *)(bin_data + info.bone_indices.offset), (const u16_vec4_t *)(bin_data + info.bone_indices.offset),
(const vec4_t *)(bin_data + info.weights.offset), info.vertex_count); (const vec4_t *)(bin_data + info.weights.offset), info.vertex_count);
memcpy(model.indices, bin_data + info.indices.offset, info.indices.len); memcpy(model.indices, bin_data + info.indices.offset, info.indices.len);
model.inverse_bind_matrices = calloc(info.bone_count, sizeof(mat4_t));
assert(model.inverse_bind_matrices != nullptr);
memcpy(
model.inverse_bind_matrices,
bin_data + info.inverse_bind_matrices.offset,
info.inverse_bind_matrices.len);
munmap(file, len); munmap(file, len);
return model; return model;