@@ -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+
128180test {
129181 std .testing .refAllDeclsRecursive (@This ());
130182}
0 commit comments