Skip to content

Commit 7093895

Browse files
authored
Merge pull request #27 from Interrupt/features/skinned-animation
Skinned Animation Support
2 parents 0ac066b + fc46ef7 commit 7093895

File tree

23 files changed

+9757
-34
lines changed

23 files changed

+9757
-34
lines changed

3rdparty/zmesh/src/io.zig

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub fn appendMeshPrimitive(
3232
normals: ?*std.ArrayList([3]f32),
3333
texcoords0: ?*std.ArrayList([2]f32),
3434
tangents: ?*std.ArrayList([4]f32),
35+
joints: ?*std.ArrayList([4]f32),
36+
weights: ?*std.ArrayList([4]f32),
3537
) !void {
3638
assert(mesh_index < data.meshes_count);
3739
assert(prim_index < data.meshes.?[mesh_index].primitives_count);
@@ -42,6 +44,8 @@ pub fn appendMeshPrimitive(
4244
const num_vertices: u32 = @as(u32, @intCast(prim.attributes[0].data.count));
4345
const num_indices: u32 = @as(u32, @intCast(prim.indices.?.count));
4446

47+
const start_indices: u32 = @intCast(positions.items.len);
48+
4549
// Indices.
4650
{
4751
try indices.ensureTotalCapacity(indices.items.len + num_indices);
@@ -50,7 +54,7 @@ pub fn appendMeshPrimitive(
5054
const buffer_view = accessor.buffer_view.?;
5155

5256
assert(accessor.stride == buffer_view.stride or buffer_view.stride == 0);
53-
assert(accessor.stride * accessor.count == buffer_view.size);
57+
// assert(accessor.stride * accessor.count == buffer_view.size);
5458
assert(buffer_view.buffer.data != null);
5559

5660
const data_addr = @as([*]const u8, @ptrCast(buffer_view.buffer.data)) +
@@ -61,21 +65,21 @@ pub fn appendMeshPrimitive(
6165
const src = @as([*]const u8, @ptrCast(data_addr));
6266
var i: u32 = 0;
6367
while (i < num_indices) : (i += 1) {
64-
indices.appendAssumeCapacity(src[i]);
68+
indices.appendAssumeCapacity(src[i] + start_indices);
6569
}
6670
} else if (accessor.stride == 2) {
6771
assert(accessor.component_type == .r_16u);
6872
const src = @as([*]const u16, @ptrCast(@alignCast(data_addr)));
6973
var i: u32 = 0;
7074
while (i < num_indices) : (i += 1) {
71-
indices.appendAssumeCapacity(src[i]);
75+
indices.appendAssumeCapacity(src[i] + start_indices);
7276
}
7377
} else if (accessor.stride == 4) {
7478
assert(accessor.component_type == .r_32u);
7579
const src = @as([*]const u32, @ptrCast(@alignCast(data_addr)));
7680
var i: u32 = 0;
7781
while (i < num_indices) : (i += 1) {
78-
indices.appendAssumeCapacity(src[i]);
82+
indices.appendAssumeCapacity(src[i] + start_indices);
7983
}
8084
} else {
8185
unreachable;
@@ -87,44 +91,92 @@ pub fn appendMeshPrimitive(
8791
const attributes = prim.attributes[0..prim.attributes_count];
8892
for (attributes) |attrib| {
8993
const accessor = attrib.data;
90-
assert(accessor.component_type == .r_32f);
94+
// assert(accessor.component_type == .r_32f);
9195

9296
const buffer_view = accessor.buffer_view.?;
9397
assert(buffer_view.buffer.data != null);
9498

9599
assert(accessor.stride == buffer_view.stride or buffer_view.stride == 0);
96-
assert(accessor.stride * accessor.count == buffer_view.size);
100+
// assert(accessor.stride * accessor.count == buffer_view.size);
97101

98102
const data_addr = @as([*]const u8, @ptrCast(buffer_view.buffer.data)) +
99103
accessor.offset + buffer_view.offset;
100104

101105
if (attrib.type == .position) {
106+
assert(accessor.component_type == .r_32f);
102107
assert(accessor.type == .vec3);
103108
const slice = @as([*]const [3]f32, @ptrCast(@alignCast(data_addr)))[0..num_vertices];
104109
try positions.appendSlice(slice);
105110
} else if (attrib.type == .normal) {
106111
if (normals) |n| {
112+
assert(accessor.component_type == .r_32f);
107113
assert(accessor.type == .vec3);
108114
const slice = @as([*]const [3]f32, @ptrCast(@alignCast(data_addr)))[0..num_vertices];
109115
try n.appendSlice(slice);
110116
}
111117
} else if (attrib.type == .texcoord) {
112118
if (texcoords0) |tc| {
119+
assert(accessor.component_type == .r_32f);
113120
assert(accessor.type == .vec2);
114121
const slice = @as([*]const [2]f32, @ptrCast(@alignCast(data_addr)))[0..num_vertices];
115122
try tc.appendSlice(slice);
116123
}
117124
} else if (attrib.type == .tangent) {
118125
if (tangents) |tan| {
126+
assert(accessor.component_type == .r_32f);
119127
assert(accessor.type == .vec4);
120128
const slice = @as([*]const [4]f32, @ptrCast(@alignCast(data_addr)))[0..num_vertices];
121129
try tan.appendSlice(slice);
122130
}
131+
} else if (attrib.type == .joints) {
132+
if (joints) |j| {
133+
if (accessor.component_type == .r_8u) {
134+
const slice = @as([*]const [4]u8, @ptrCast(@alignCast(data_addr)))[0..num_vertices];
135+
for (slice) |v| {
136+
try j.append([4]f32{ @floatFromInt(v[0]), @floatFromInt(v[1]), @floatFromInt(v[2]), @floatFromInt(v[3]) });
137+
}
138+
} else if (accessor.component_type == .r_16u) {
139+
const slice = @as([*]const [4]u16, @ptrCast(@alignCast(data_addr)))[0..num_vertices];
140+
for (slice) |v| {
141+
try j.append([4]f32{ @floatFromInt(v[0]), @floatFromInt(v[1]), @floatFromInt(v[2]), @floatFromInt(v[3]) });
142+
}
143+
}
144+
}
145+
} else if (attrib.type == .weights) {
146+
if (weights) |w| {
147+
assert(accessor.component_type == .r_32f);
148+
assert(accessor.type == .vec4);
149+
const slice = @as([*]const [4]f32, @ptrCast(@alignCast(data_addr)))[0..num_vertices];
150+
try w.appendSlice(slice);
151+
}
123152
}
124153
}
125154
}
126155
}
127156

157+
pub fn getAnimationSamplerData(accessor: *zcgltf.Accessor) []const f32 {
158+
const buffer_view = accessor.buffer_view.?;
159+
160+
assert(buffer_view.buffer.data != null);
161+
assert(accessor.stride == buffer_view.stride or buffer_view.stride == 0);
162+
163+
const data_addr = @as([*]const u8, @ptrCast(buffer_view.buffer.data)) + accessor.offset + buffer_view.offset;
164+
165+
const slice = @as([*]const f32, @ptrCast(@alignCast(data_addr)))[0 .. accessor.count * zcgltf.Type.numComponents(accessor.type)];
166+
return slice;
167+
}
168+
169+
pub fn computeAnimationDuration(animation: *const zcgltf.Animation) f32 {
170+
var duration: f32 = 0;
171+
172+
for (0..animation.samplers_count, animation.samplers) |_, sampler| {
173+
const samples = getAnimationSamplerData(sampler.input);
174+
duration = @max(duration, samples[samples.len - 1]);
175+
}
176+
177+
return duration;
178+
}
179+
128180
test {
129181
std.testing.refAllDeclsRecursive(@This());
130182
}

0 commit comments

Comments
 (0)