@@ -18,8 +18,8 @@ pub const Node = struct {
18
18
mesh : ? u16 ,
19
19
children : []const u16 ,
20
20
scale : [3 ]f32 ,
21
- rotation : [3 ]f32 ,
22
21
translation : [3 ]f32 ,
22
+ rotation : [4 ]f32 ,
23
23
};
24
24
25
25
pub const Mesh = struct {
@@ -28,10 +28,12 @@ pub const Mesh = struct {
28
28
29
29
pub const Material = struct {
30
30
pbr : ? PBR ,
31
+ normal : ? Texture ,
31
32
32
33
const PBR = struct {
33
34
base_color_factor : @Vector (4 , f32 ),
34
- base_color_texture : ? Texture ,
35
+ base_color : ? Texture ,
36
+ metallic_roughness : ? Texture ,
35
37
};
36
38
};
37
39
@@ -68,8 +70,8 @@ const JsonChunk = struct {
68
70
mesh : ? u16 = null ,
69
71
children : []u16 = &.{},
70
72
scale : @Vector (3 , f32 ) = .{ 1 , 1 , 1 },
71
- rotation : @Vector (3 , f32 ) = .{ 0 , 0 , 0 },
72
73
translation : @Vector (3 , f32 ) = .{ 0 , 0 , 0 },
74
+ rotation : @Vector (4 , f32 ) = .{ 0 , 0 , 0 , 1 },
73
75
},
74
76
meshes : []struct {
75
77
primitives : []struct {
@@ -84,14 +86,18 @@ const JsonChunk = struct {
84
86
indices : ? u16 = null ,
85
87
material : ? u16 = null ,
86
88
},
87
- },
89
+ } = &.{} ,
88
90
materials : []struct {
89
91
name : ? []const u8 = null ,
90
92
pbrMetallicRoughness : ? struct {
91
93
baseColorFactor : @Vector (4 , f32 ) = .{ 1 , 1 , 1 , 1 },
92
- baseColorTexture : ? struct {
93
- index : u16 ,
94
- } = null ,
94
+ baseColorTexture : ? struct { index : u16 } = null ,
95
+ metallicRoughnessTexture : ? struct { index : u16 } = null ,
96
+ } = null ,
97
+ normalTexture : ? struct {
98
+ index : u16 ,
99
+ scale : u16 = 1 ,
100
+ texcoord : u16 = 0 ,
95
101
} = null ,
96
102
} = &.{},
97
103
textures : []struct {
@@ -187,7 +193,7 @@ const Target = enum(u16) {
187
193
ELEMENT_ARRAY_BUFFER = 34963 ,
188
194
};
189
195
190
- pub fn parseGLB (allocator : std.mem.Allocator , data : []const u8 ) ! GLTF {
196
+ pub fn parseGLB (allocator : std.mem.Allocator , data : []const u8 , no_materials : bool ) ! GLTF {
191
197
var fbs = std .io .fixedBufferStream (data );
192
198
const reader = fbs .reader ();
193
199
@@ -257,61 +263,66 @@ pub fn parseGLB(allocator: std.mem.Allocator, data: []const u8) !GLTF {
257
263
258
264
const out_nodes = try fba .alloc (Node , metadata .nodes .len );
259
265
const out_meshes = try fba .alloc (Mesh , metadata .meshes .len );
260
- const out_materials = try fba .alloc (Material , metadata .materials .len );
266
+ const out_materials = try fba .alloc (Material , if ( no_materials ) 0 else metadata .materials .len );
261
267
262
268
alloc_zone .end ();
263
269
264
270
for (metadata .nodes , out_nodes ) | node , * out_node | {
265
271
out_node .* = .{
266
- // According to tracy, even calls to alloc/dupe/free with 0 size has significant time costs
272
+ // According to tracy, even calls to alloc/dupe/free with 0 size has significant time cost
267
273
.children = if (node .children .len > 0 ) try fba .dupe (u16 , node .children ) else &.{},
268
274
.mesh = node .mesh ,
269
275
.scale = node .scale ,
270
- .rotation = node .rotation ,
271
276
.translation = node .translation ,
277
+ .rotation = node .rotation ,
272
278
};
273
279
}
274
280
275
- for (metadata .materials , out_materials ) | material , * out_material | {
276
- if (material .pbrMetallicRoughness ) | pbr | {
277
- var base_color_texture : ? Texture = null ;
278
- if (pbr .baseColorTexture ) | base_tex | {
279
- const tex = metadata .textures [base_tex .index ];
280
- const img = metadata .images [tex .source ];
281
- const buffer_view = metadata .bufferViews [img .bufferView ];
282
- assert (buffer_view .byteStride == null );
283
-
284
- const ptr = buffer [buffer_view .byteOffset .. ][0.. buffer_view .byteLength ];
281
+ if (! no_materials ) {
282
+ for (metadata .materials , out_materials ) | material , * out_material | {
283
+ var pbr : ? Material.PBR = null ;
284
+ var normal : ? Texture = null ;
285
+ if (material .pbrMetallicRoughness ) | pbr_metallic_roughness | {
286
+ var base_color : ? Texture = null ;
287
+
288
+ if (pbr_metallic_roughness .baseColorTexture ) | tex_index | {
289
+ const tex = metadata .textures [tex_index .index ];
290
+ const img = metadata .images [tex .source ];
291
+ const buffer_view = metadata .bufferViews [img .bufferView ];
292
+ assert (buffer_view .byteStride == null );
293
+ const ptr = buffer [buffer_view .byteOffset .. ][0.. buffer_view .byteLength ];
294
+ base_color = try loadTexture (ptr );
295
+ }
285
296
286
- var width : c_int = 0 ;
287
- var height : c_int = 0 ;
288
- var channels_in_file : c_int = 0 ;
289
- var image : [:0 ]u8 = undefined ;
290
-
291
- if (! @hasDecl (@import ("root" ), "BENCHMARK_GLTF" )) {
292
- const image_c = stbi .stbi_load_from_memory (
293
- ptr .ptr ,
294
- @intCast (ptr .len ),
295
- & width ,
296
- & height ,
297
- & channels_in_file ,
298
- 4 ,
299
- );
300
- image = @ptrCast (image_c [0.. @intCast (width * height * 4 + 1 )]);
297
+ var metallic_roughness : ? Texture = null ;
298
+ if (pbr_metallic_roughness .metallicRoughnessTexture ) | tex_index | {
299
+ const tex = metadata .textures [tex_index .index ];
300
+ const img = metadata .images [tex .source ];
301
+ const buffer_view = metadata .bufferViews [img .bufferView ];
302
+ assert (buffer_view .byteStride == null );
303
+ const ptr = buffer [buffer_view .byteOffset .. ][0.. buffer_view .byteLength ];
304
+ metallic_roughness = try loadTexture (ptr );
301
305
}
302
306
303
- base_color_texture = .{
304
- .width = @intCast ( width ) ,
305
- .height = @intCast ( height ) ,
306
- .data = image ,
307
+ pbr = .{
308
+ .base_color_factor = pbr_metallic_roughness . baseColorFactor ,
309
+ .base_color = base_color ,
310
+ .metallic_roughness = metallic_roughness ,
307
311
};
308
312
}
309
313
314
+ if (material .normalTexture ) | tex_index | {
315
+ const tex = metadata .textures [tex_index .index ];
316
+ const img = metadata .images [tex .source ];
317
+ const buffer_view = metadata .bufferViews [img .bufferView ];
318
+ assert (buffer_view .byteStride == null );
319
+ const ptr = buffer [buffer_view .byteOffset .. ][0.. buffer_view .byteLength ];
320
+ normal = try loadTexture (ptr );
321
+ }
322
+
310
323
out_material .* = .{
311
- .pbr = .{
312
- .base_color_factor = pbr .baseColorFactor ,
313
- .base_color_texture = base_color_texture ,
314
- },
324
+ .pbr = pbr ,
325
+ .normal = normal ,
315
326
};
316
327
}
317
328
}
@@ -339,6 +350,7 @@ pub fn parseGLB(allocator: std.mem.Allocator, data: []const u8) !GLTF {
339
350
.{ prim .attributes .POSITION , .position },
340
351
.{ prim .attributes .NORMAL , .normal },
341
352
.{ prim .attributes .TANGENT , .tangent },
353
+ .{ prim .attributes .COLOR_0 , .color_0 },
342
354
.{ prim .attributes .TEXCOORD_0 , .texcoord_0 },
343
355
.{ prim .attributes .TEXCOORD_1 , .texcoord_1 },
344
356
}) | entry | if (entry .@"0" ) | attr | {
@@ -434,7 +446,6 @@ pub fn parseGLB(allocator: std.mem.Allocator, data: []const u8) !GLTF {
434
446
.f32 = > @bitCast (slice [0.. @sizeOf ([4 ]f32 )].* ),
435
447
else = > unreachable ,
436
448
};
437
- assert (color_0 >= .{ 0 , 0 , 0 , 0 });
438
449
}
439
450
} else if (accessor .type == .VEC3 ) {
440
451
while (iter .next ()) | slice | : (i += 1 ) {
@@ -445,7 +456,6 @@ pub fn parseGLB(allocator: std.mem.Allocator, data: []const u8) !GLTF {
445
456
else = > unreachable ,
446
457
};
447
458
color_0 .? [i ] = .{ color_rgb [0 ], color_rgb [1 ], color_rgb [2 ], 1 };
448
- assert (color_0 <= .{ 1 , 1 , 1 , 1 });
449
459
}
450
460
} else unreachable ;
451
461
},
@@ -476,9 +486,6 @@ pub fn parseGLB(allocator: std.mem.Allocator, data: []const u8) !GLTF {
476
486
}
477
487
};
478
488
479
- // TODO: joints_0
480
- // TODO: weights_0
481
-
482
489
out_prim .* = .{
483
490
.material = prim .material ,
484
491
.indices = indices ,
@@ -510,9 +517,34 @@ pub fn deinit(gltf: GLTF, allocator: std.mem.Allocator) void {
510
517
if (! @hasDecl (@import ("root" ), "BENCHMARK_GLTF" )) {
511
518
for (gltf .materials ) | material | {
512
519
if (material .pbr ) | pbr | {
513
- if (pbr .base_color_texture ) | tex | stbi .stbi_image_free (tex .data .ptr );
520
+ if (pbr .base_color ) | tex | stbi .stbi_image_free (tex .data .ptr );
514
521
}
515
522
}
516
523
}
517
524
allocator .free (gltf .fba_buf );
518
525
}
526
+
527
+ fn loadTexture (ptr : []const u8 ) ! Texture {
528
+ var width : c_int = 0 ;
529
+ var height : c_int = 0 ;
530
+ var channels_in_file : c_int = 0 ;
531
+ var image : [:0 ]u8 = undefined ;
532
+
533
+ if (! @hasDecl (@import ("root" ), "BENCHMARK_GLTF" )) {
534
+ const image_c = stbi .stbi_load_from_memory (
535
+ ptr .ptr ,
536
+ @intCast (ptr .len ),
537
+ & width ,
538
+ & height ,
539
+ & channels_in_file ,
540
+ 4 ,
541
+ ) orelse return error .LoadingImageFailed ;
542
+ image = @ptrCast (image_c [0.. @intCast (width * height * 4 + 1 )]);
543
+ }
544
+
545
+ return .{
546
+ .width = @intCast (width ),
547
+ .height = @intCast (height ),
548
+ .data = image ,
549
+ };
550
+ }
0 commit comments