Load animation data into model
This commit is contained in:
1 parent
f24a920e66
commit
ffa0beb55a
3 files changed
+85
-4
No files matched your search
@@ -6,9 +6,9 @@
|
|||||||
model_t model_init(size_t vertex_count, size_t index_count)
|
model_t model_init(size_t vertex_count, size_t index_count)
|
||||||
{
|
{
|
||||||
model_t model = {
|
model_t model = {
|
||||||
.indices = calloc(index_count, sizeof(index_t)),
|
.indices = malloc(index_count * sizeof(index_t)),
|
||||||
.index_count = index_count,
|
.index_count = index_count,
|
||||||
.vertices = calloc(vertex_count, sizeof(vertex_t)),
|
.vertices = malloc(vertex_count * sizeof(vertex_t)),
|
||||||
.vertex_count = vertex_count,
|
.vertex_count = vertex_count,
|
||||||
};
|
};
|
||||||
return model;
|
return model;
|
||||||
@@ -34,5 +34,19 @@ void model_cleanup(model_t *m)
|
|||||||
free(m->inverse_bind_matrices);
|
free(m->inverse_bind_matrices);
|
||||||
m->inverse_bind_matrices = nullptr;
|
m->inverse_bind_matrices = nullptr;
|
||||||
}
|
}
|
||||||
m->vertex_count = m->index_count = m->bone_count = 0;
|
if (m->animation.times != nullptr) {
|
||||||
|
free(m->animation.times);
|
||||||
|
m->animation.times = nullptr;
|
||||||
|
}
|
||||||
|
if (m->animation.bones != nullptr) {
|
||||||
|
for (unsigned i = 0; i < m->bone_count; ++i) {
|
||||||
|
free(m->animation.bones[i].translations);
|
||||||
|
free(m->animation.bones[i].rotations);
|
||||||
|
free(m->animation.bones[i].scales);
|
||||||
|
}
|
||||||
|
free(m->animation.bones);
|
||||||
|
m->animation.bones = nullptr;
|
||||||
|
}
|
||||||
|
m->vertex_count = m->index_count = m->bone_count
|
||||||
|
= m->animation.keyframe_count = 0;
|
||||||
}
|
}
|
||||||
@@ -22,11 +22,24 @@ typedef struct {
|
|||||||
vec3_t scale;
|
vec3_t scale;
|
||||||
} bone_t;
|
} bone_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec3_t *translations;
|
||||||
|
vec4_t *rotations;
|
||||||
|
vec3_t *scales;
|
||||||
|
} animation_bone_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float *times;
|
||||||
|
size_t keyframe_count;
|
||||||
|
animation_bone_t *bones;
|
||||||
|
} animation_t;
|
||||||
|
|
||||||
typedef struct {
|
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;
|
mat4_t *inverse_bind_matrices;
|
||||||
|
animation_t animation;
|
||||||
size_t vertex_count;
|
size_t vertex_count;
|
||||||
size_t index_count;
|
size_t index_count;
|
||||||
size_t bone_count;
|
size_t bone_count;
|
||||||
|
|||||||
+55
-1
@@ -1146,13 +1146,67 @@ 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));
|
model.inverse_bind_matrices = malloc(info.bone_count * sizeof(mat4_t));
|
||||||
assert(model.inverse_bind_matrices != nullptr);
|
assert(model.inverse_bind_matrices != nullptr);
|
||||||
memcpy(
|
memcpy(
|
||||||
model.inverse_bind_matrices,
|
model.inverse_bind_matrices,
|
||||||
bin_data + info.inverse_bind_matrices.offset,
|
bin_data + info.inverse_bind_matrices.offset,
|
||||||
info.inverse_bind_matrices.len);
|
info.inverse_bind_matrices.len);
|
||||||
|
|
||||||
|
// Load animation data
|
||||||
|
model.animation.keyframe_count = info.animation.keyframe_count;
|
||||||
|
const size_t times_size = model.animation.keyframe_count * sizeof(float);
|
||||||
|
model.animation.times = malloc(times_size);
|
||||||
|
assert(model.animation.times != nullptr);
|
||||||
|
memcpy(
|
||||||
|
model.animation.times, bin_data + info.animation.times[0].offset,
|
||||||
|
times_size);
|
||||||
|
model.animation.length_us = (size_t)roundf(
|
||||||
|
1'000'000
|
||||||
|
* model.animation.times[model.animation.keyframe_count - 1]);
|
||||||
|
for (unsigned i = 1; i < info.bone_count; ++i) {
|
||||||
|
// Verify that all time series data matches
|
||||||
|
if (info.animation.times[i].offset
|
||||||
|
!= info.animation.times[0].offset) {
|
||||||
|
assert(
|
||||||
|
memcmp(
|
||||||
|
model.animation.times,
|
||||||
|
bin_data + info.animation.times[i].offset, times_size)
|
||||||
|
== 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.animation.bones
|
||||||
|
= malloc(model.bone_count * sizeof(animation_bone_t));
|
||||||
|
assert(model.animation.bones != nullptr);
|
||||||
|
for (unsigned i = 0; i < info.bone_count; ++i) {
|
||||||
|
// Load translations
|
||||||
|
model.animation.bones[i].translations
|
||||||
|
= malloc(model.animation.keyframe_count * sizeof(vec3_t));
|
||||||
|
assert(model.animation.bones[i].translations != nullptr);
|
||||||
|
memcpy(
|
||||||
|
model.animation.bones[i].translations,
|
||||||
|
bin_data + info.animation.translations[i].offset,
|
||||||
|
model.animation.keyframe_count * sizeof(vec3_t));
|
||||||
|
|
||||||
|
// Load rotations
|
||||||
|
model.animation.bones[i].rotations
|
||||||
|
= malloc(model.animation.keyframe_count * sizeof(vec4_t));
|
||||||
|
assert(model.animation.bones[i].rotations != nullptr);
|
||||||
|
memcpy(
|
||||||
|
model.animation.bones[i].rotations,
|
||||||
|
bin_data + info.animation.rotations[i].offset,
|
||||||
|
model.animation.keyframe_count * sizeof(vec4_t));
|
||||||
|
|
||||||
|
// Load scales
|
||||||
|
model.animation.bones[i].scales
|
||||||
|
= malloc(model.animation.keyframe_count * sizeof(vec3_t));
|
||||||
|
assert(model.animation.bones[i].scales != nullptr);
|
||||||
|
memcpy(
|
||||||
|
model.animation.bones[i].scales,
|
||||||
|
bin_data + info.animation.scales[i].offset,
|
||||||
|
model.animation.keyframe_count * sizeof(vec3_t));
|
||||||
|
}
|
||||||
|
|
||||||
munmap(file, len);
|
munmap(file, len);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user