Loading of complex scene graphs is now working well!

Managed to load a huge glb file, not included in commit cause I don't want to use
lots of storage in git lfs
This commit is contained in:
sergeypdev 2024-02-25 03:32:53 +04:00
parent 892c2c643a
commit e0e951c46b
9 changed files with 86 additions and 341 deletions

View File

@ -1,2 +0,0 @@
# Blender 4.0.2 MTL File: 'None'
# www.blender.org

View File

@ -1,303 +0,0 @@
# Blender 4.0.2
# www.blender.org
mtllib test_scene.mtl
o Cube
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 8/5/2 7/6/2
f 7/6/3 8/5/3 6/7/3 5/8/3
f 5/8/4 6/7/4 2/9/4 1/10/4
f 3/11/5 7/6/5 5/8/5 1/12/5
f 8/5/6 4/13/6 2/14/6 6/7/6
o Cylinder
v -4.365820 -1.000000 -1.000000
v -4.365820 1.000000 -1.000000
v -4.170730 -1.000000 -0.980785
v -4.170730 1.000000 -0.980785
v -3.983137 -1.000000 -0.923880
v -3.983137 1.000000 -0.923880
v -3.810250 -1.000000 -0.831470
v -3.810250 1.000000 -0.831470
v -3.658714 -1.000000 -0.707107
v -3.658714 1.000000 -0.707107
v -3.534351 -1.000000 -0.555570
v -3.534351 1.000000 -0.555570
v -3.441941 -1.000000 -0.382683
v -3.441941 1.000000 -0.382683
v -3.385035 -1.000000 -0.195090
v -3.385035 1.000000 -0.195090
v -3.365820 -1.000000 0.000000
v -3.365820 1.000000 0.000000
v -3.385035 -1.000000 0.195090
v -3.385035 1.000000 0.195090
v -3.441941 -1.000000 0.382683
v -3.441941 1.000000 0.382683
v -3.534351 -1.000000 0.555570
v -3.534351 1.000000 0.555570
v -3.658714 -1.000000 0.707107
v -3.658714 1.000000 0.707107
v -3.810250 -1.000000 0.831470
v -3.810250 1.000000 0.831470
v -3.983137 -1.000000 0.923880
v -3.983137 1.000000 0.923880
v -4.170730 -1.000000 0.980785
v -4.170730 1.000000 0.980785
v -4.365820 -1.000000 1.000000
v -4.365820 1.000000 1.000000
v -4.560911 -1.000000 0.980785
v -4.560911 1.000000 0.980785
v -4.748504 -1.000000 0.923880
v -4.748504 1.000000 0.923880
v -4.921391 -1.000000 0.831470
v -4.921391 1.000000 0.831470
v -5.072927 -1.000000 0.707107
v -5.072927 1.000000 0.707107
v -5.197290 -1.000000 0.555570
v -5.197290 1.000000 0.555570
v -5.289700 -1.000000 0.382683
v -5.289700 1.000000 0.382683
v -5.346606 -1.000000 0.195090
v -5.346606 1.000000 0.195090
v -5.365820 -1.000000 0.000000
v -5.365820 1.000000 0.000000
v -5.346606 -1.000000 -0.195090
v -5.346606 1.000000 -0.195090
v -5.289700 -1.000000 -0.382683
v -5.289700 1.000000 -0.382683
v -5.197290 -1.000000 -0.555570
v -5.197290 1.000000 -0.555570
v -5.072927 -1.000000 -0.707107
v -5.072927 1.000000 -0.707107
v -4.921391 -1.000000 -0.831470
v -4.921391 1.000000 -0.831470
v -4.748504 -1.000000 -0.923880
v -4.748504 1.000000 -0.923880
v -4.560911 -1.000000 -0.980785
v -4.560911 1.000000 -0.980785
vn 0.0980 -0.0000 -0.9952
vn 0.2903 -0.0000 -0.9569
vn 0.4714 -0.0000 -0.8819
vn 0.6344 -0.0000 -0.7730
vn 0.7730 -0.0000 -0.6344
vn 0.8819 -0.0000 -0.4714
vn 0.9569 -0.0000 -0.2903
vn 0.9952 -0.0000 -0.0980
vn 0.9952 -0.0000 0.0980
vn 0.9569 -0.0000 0.2903
vn 0.8819 -0.0000 0.4714
vn 0.7730 -0.0000 0.6344
vn 0.6344 -0.0000 0.7730
vn 0.4714 -0.0000 0.8819
vn 0.2903 -0.0000 0.9569
vn 0.0980 -0.0000 0.9952
vn -0.0980 -0.0000 0.9952
vn -0.2903 -0.0000 0.9569
vn -0.4714 -0.0000 0.8819
vn -0.6344 -0.0000 0.7730
vn -0.7730 -0.0000 0.6344
vn -0.8819 -0.0000 0.4714
vn -0.9569 -0.0000 0.2903
vn -0.9952 -0.0000 0.0980
vn -0.9952 -0.0000 -0.0980
vn -0.9569 -0.0000 -0.2903
vn -0.8819 -0.0000 -0.4714
vn -0.7730 -0.0000 -0.6344
vn -0.6344 -0.0000 -0.7730
vn -0.4714 -0.0000 -0.8819
vn -0.0000 1.0000 -0.0000
vn -0.2903 -0.0000 -0.9569
vn -0.0980 -0.0000 -0.9952
vn -0.0000 -1.0000 -0.0000
vt 1.000000 0.500000
vt 1.000000 1.000000
vt 0.968750 1.000000
vt 0.968750 0.500000
vt 0.937500 1.000000
vt 0.937500 0.500000
vt 0.906250 1.000000
vt 0.906250 0.500000
vt 0.875000 1.000000
vt 0.875000 0.500000
vt 0.843750 1.000000
vt 0.843750 0.500000
vt 0.812500 1.000000
vt 0.812500 0.500000
vt 0.781250 1.000000
vt 0.781250 0.500000
vt 0.750000 1.000000
vt 0.750000 0.500000
vt 0.718750 1.000000
vt 0.718750 0.500000
vt 0.687500 1.000000
vt 0.687500 0.500000
vt 0.656250 1.000000
vt 0.656250 0.500000
vt 0.625000 1.000000
vt 0.625000 0.500000
vt 0.593750 1.000000
vt 0.593750 0.500000
vt 0.562500 1.000000
vt 0.562500 0.500000
vt 0.531250 1.000000
vt 0.531250 0.500000
vt 0.500000 1.000000
vt 0.500000 0.500000
vt 0.468750 1.000000
vt 0.468750 0.500000
vt 0.437500 1.000000
vt 0.437500 0.500000
vt 0.406250 1.000000
vt 0.406250 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt 0.343750 1.000000
vt 0.343750 0.500000
vt 0.312500 1.000000
vt 0.312500 0.500000
vt 0.281250 1.000000
vt 0.281250 0.500000
vt 0.250000 1.000000
vt 0.250000 0.500000
vt 0.218750 1.000000
vt 0.218750 0.500000
vt 0.187500 1.000000
vt 0.187500 0.500000
vt 0.156250 1.000000
vt 0.156250 0.500000
vt 0.125000 1.000000
vt 0.125000 0.500000
vt 0.093750 1.000000
vt 0.093750 0.500000
vt 0.062500 1.000000
vt 0.062500 0.500000
vt 0.296822 0.485388
vt 0.250000 0.490000
vt 0.203178 0.485388
vt 0.158156 0.471731
vt 0.116663 0.449553
vt 0.080294 0.419706
vt 0.050447 0.383337
vt 0.028269 0.341844
vt 0.014612 0.296822
vt 0.010000 0.250000
vt 0.014612 0.203178
vt 0.028269 0.158156
vt 0.050447 0.116663
vt 0.080294 0.080294
vt 0.116663 0.050447
vt 0.158156 0.028269
vt 0.203178 0.014612
vt 0.250000 0.010000
vt 0.296822 0.014612
vt 0.341844 0.028269
vt 0.383337 0.050447
vt 0.419706 0.080294
vt 0.449553 0.116663
vt 0.471731 0.158156
vt 0.485388 0.203178
vt 0.490000 0.250000
vt 0.485388 0.296822
vt 0.471731 0.341844
vt 0.449553 0.383337
vt 0.419706 0.419706
vt 0.383337 0.449553
vt 0.341844 0.471731
vt 0.031250 1.000000
vt 0.031250 0.500000
vt 0.000000 1.000000
vt 0.000000 0.500000
vt 0.750000 0.490000
vt 0.796822 0.485388
vt 0.841844 0.471731
vt 0.883337 0.449553
vt 0.919706 0.419706
vt 0.949553 0.383337
vt 0.971731 0.341844
vt 0.985388 0.296822
vt 0.990000 0.250000
vt 0.985388 0.203178
vt 0.971731 0.158156
vt 0.949553 0.116663
vt 0.919706 0.080294
vt 0.883337 0.050447
vt 0.841844 0.028269
vt 0.796822 0.014612
vt 0.750000 0.010000
vt 0.703178 0.014612
vt 0.658156 0.028269
vt 0.616663 0.050447
vt 0.580294 0.080294
vt 0.550447 0.116663
vt 0.528269 0.158156
vt 0.514612 0.203178
vt 0.510000 0.250000
vt 0.514612 0.296822
vt 0.528269 0.341844
vt 0.550447 0.383337
vt 0.580294 0.419706
vt 0.616663 0.449553
vt 0.658156 0.471731
vt 0.703178 0.485388
s 0
f 9/15/7 10/16/7 12/17/7 11/18/7
f 11/18/8 12/17/8 14/19/8 13/20/8
f 13/20/9 14/19/9 16/21/9 15/22/9
f 15/22/10 16/21/10 18/23/10 17/24/10
f 17/24/11 18/23/11 20/25/11 19/26/11
f 19/26/12 20/25/12 22/27/12 21/28/12
f 21/28/13 22/27/13 24/29/13 23/30/13
f 23/30/14 24/29/14 26/31/14 25/32/14
f 25/32/15 26/31/15 28/33/15 27/34/15
f 27/34/16 28/33/16 30/35/16 29/36/16
f 29/36/17 30/35/17 32/37/17 31/38/17
f 31/38/18 32/37/18 34/39/18 33/40/18
f 33/40/19 34/39/19 36/41/19 35/42/19
f 35/42/20 36/41/20 38/43/20 37/44/20
f 37/44/21 38/43/21 40/45/21 39/46/21
f 39/46/22 40/45/22 42/47/22 41/48/22
f 41/48/23 42/47/23 44/49/23 43/50/23
f 43/50/24 44/49/24 46/51/24 45/52/24
f 45/52/25 46/51/25 48/53/25 47/54/25
f 47/54/26 48/53/26 50/55/26 49/56/26
f 49/56/27 50/55/27 52/57/27 51/58/27
f 51/58/28 52/57/28 54/59/28 53/60/28
f 53/60/29 54/59/29 56/61/29 55/62/29
f 55/62/30 56/61/30 58/63/30 57/64/30
f 57/64/31 58/63/31 60/65/31 59/66/31
f 59/66/32 60/65/32 62/67/32 61/68/32
f 61/68/33 62/67/33 64/69/33 63/70/33
f 63/70/34 64/69/34 66/71/34 65/72/34
f 65/72/35 66/71/35 68/73/35 67/74/35
f 67/74/36 68/73/36 70/75/36 69/76/36
f 12/77/37 10/78/37 72/79/37 70/80/37 68/81/37 66/82/37 64/83/37 62/84/37 60/85/37 58/86/37 56/87/37 54/88/37 52/89/37 50/90/37 48/91/37 46/92/37 44/93/37 42/94/37 40/95/37 38/96/37 36/97/37 34/98/37 32/99/37 30/100/37 28/101/37 26/102/37 24/103/37 22/104/37 20/105/37 18/106/37 16/107/37 14/108/37
f 69/76/38 70/75/38 72/109/38 71/110/38
f 71/110/39 72/109/39 10/111/39 9/112/39
f 9/113/40 11/114/40 13/115/40 15/116/40 17/117/40 19/118/40 21/119/40 23/120/40 25/121/40 27/122/40 29/123/40 31/124/40 33/125/40 35/126/40 37/127/40 39/128/40 41/129/40 43/130/40 45/131/40 47/132/40 49/133/40 51/134/40 53/135/40 55/136/40 57/137/40 59/138/40 61/139/40 63/140/40 65/141/40 67/142/40 69/143/40 71/144/40

View File

@ -150,6 +150,9 @@ const asset_extensions = [_][]const u8{
"png",
"jpg",
"exr",
"fbx",
"gltf",
"glb",
};
// Find all assets and cook them using assetc
@ -208,13 +211,11 @@ fn buildAssetCompiler(b: *Build, optimize: std.builtin.OptimizeMode, assets_mod:
.target = b.host,
.optimize = optimize,
//.formats = @as([]const u8, "3DS,3MF,AC,AMF,ASE,Assbin,Assjson,Assxml,B3D,Blender,BVH,C4D,COB,Collada,CSM,DXF,FBX,glTF,glTF2,HMP,IFC,Irr,LWO,LWS,M3D,MD2,MD3,MD5,MDC,MDL,MMD,MS3D,NDO,NFF,Obj,OFF,Ogre,OpenGEX,Ply,Q3BSP,Q3D,Raw,SIB,SMD,Step,STEPParser,STL,Terragen,Unreal,X,X3D,XGL"),
.formats = @as([]const u8, "Obj"),
.formats = @as([]const u8, "Obj,FBX,glTF,glTF2,Blend"),
});
const zalgebra_dep = b.dependency("zalgebra", .{});
const assimp_lib = assimp_dep.artifact("assimp");
// HACK: fix in assimp
assimp_lib.defineCMacro("AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER", "\"AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER\"");
const assetc = b.addExecutable(.{
.name = "assetc",

View File

@ -20,8 +20,8 @@
.hash = "1220483cbb42231cb056f4ea6669894c68ccd560d3af5832d6e9c84c61844bc20b7d",
},
.@"zig-assimp" = .{
.url = "https://github.com/sergeypdev/zig-assimp/tarball/64b31e9c01132352246955f496642332cb611577",
.hash = "1220a57ac5fe4f45eae98d9b26f7cba93dca90782d631ef73a740b0190559d424054",
.url = "https://github.com/sergeypdev/zig-assimp/tarball/59c2f0202bf1e5110f3eb219669f3762e3db2768",
.hash = "122015247b178258ee2fd9f7fbd3f8025138e8e38b5cbecdc94262974da49bd1c225",
},
.zalgebra = .{
.url = "git+https://github.com/sergeypdev/zalgebra.git#232ff76712dc7cc270b6c48cedc84617536f3a59",

View File

@ -269,9 +269,7 @@ export fn game_init(global_allocator: *std.mem.Allocator) void {
}
}
const test_scene_root = globals.g_mem.world.createScene(globals.g_assetman.resolveScene(a.Scenes.test_scene.scene));
std.log.debug("test scene root idx {}\n", .{test_scene_root.idx});
// const test_scene_root = globals.g_mem.world.createScene(globals.g_assetman.resolveScene(a.Scenes.test_scene.scene));
}
export fn game_update() bool {

View File

@ -55,7 +55,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
// Random bytes to make WriteFile unique. Refresh this with
// new random bytes when GenerateAssetManifest implementation is modified
// in a non-backwards-compatible way.
man.hash.add(@as(u32, 0xd767ee71));
man.hash.add(@as(u32, 0xd767ee75));
// TODO: sort generated asset lists to make sure cache is predictable
@ -153,7 +153,7 @@ fn writeAssetManifest(arena: std.mem.Allocator, writer: anytype, assets: []Asset
// TODO: think about building a perfect hashmap
// AssetId -> Asset path mapping
try writer.writeAll(
\\var buf: [4096]u8 = undefined;
\\var buf: [1024 * 1024]u8 = undefined;
\\var fba = std.heap.FixedBufferAllocator.init(&buf);
\\pub var asset_paths = std.AutoHashMapUnmanaged(u64, []const u8){};
\\var initialized = false;
@ -166,6 +166,7 @@ fn writeAssetManifest(arena: std.mem.Allocator, writer: anytype, assets: []Asset
);
for (assets) |asset_list_entry| {
const path = try asset_list_entry.getOutputPath(&buf);
std.log.debug("asset output path: {s}\n", .{path});
try std.fmt.format(writer, " asset_paths.put(fba.allocator(), {}, \"{}\") catch @panic(\"OOM\");\n", .{ asset_list_entry.getAssetId(), std.zig.fmtEscapes(path) });
}
try writer.writeAll("}\n\n");
@ -191,7 +192,6 @@ const NestedAssetDef = union(enum) {
path: types.AssetPath,
asset_list_entry: AssetListEntry,
) !void {
std.log.debug("NestedAssetDef.put {s}", .{path.getPath()});
var iter = try std.fs.path.componentIterator(path.getPath());
const filename = iter.last().?.name;
_ = iter.first();
@ -199,10 +199,8 @@ const NestedAssetDef = union(enum) {
var current = &self.path;
while (iter.next()) |comp| {
std.log.debug("NestedAssetDef comp next {s}\n", .{comp.name});
if (comp.name.ptr == filename.ptr) break;
const gop = try current.getOrPut(allocator, comp.name);
std.log.debug("NestedAssetDef put path {s}\n", .{comp.name});
if (!gop.found_existing) {
gop.value_ptr.* = NestedAssetDef{ .path = .{} };
}
@ -216,7 +214,6 @@ const NestedAssetDef = union(enum) {
}
try gop.value_ptr.put(allocator, .{ .simple = sub_path }, asset_list_entry);
} else {
std.log.debug("NestedAssetDef put filename {s}\n", .{std.fs.path.stem(filename)});
try current.put(allocator, std.fs.path.stem(filename), NestedAssetDef{
.asset = asset_list_entry,
});

View File

@ -9,6 +9,7 @@ const Vector2 = formats.Vector2;
const Vector3 = formats.Vector3;
const za = @import("zalgebra");
const Vec3 = za.Vec3;
const Mat4 = za.Mat4;
const c = @cImport({
@cInclude("assimp/cimport.h");
@cInclude("assimp/scene.h");
@ -23,9 +24,18 @@ const c = @cImport({
const ASSET_MAX_BYTES = 1024 * 1024 * 1024;
const scene_formats = [_][]const u8{
".obj",
".fbx",
".gltf",
".glb",
};
pub fn resolveAssetTypeByExtension(path: []const u8) ?AssetType {
if (std.mem.endsWith(u8, path, ".obj") or std.mem.endsWith(u8, path, ".fbx")) {
return .Scene;
for (scene_formats) |ext| {
if (std.mem.endsWith(u8, path, ext)) {
return .Scene;
}
}
if (std.mem.endsWith(u8, path, ".prog")) {
return .ShaderProgram;
@ -68,7 +78,7 @@ pub fn main() !void {
var buf_asset_list_writer = std.io.bufferedWriter(std.io.getStdOut().writer());
const asset_list_writer = buf_asset_list_writer.writer();
std.log.debug("rel_input: {s}", .{rel_input});
std.log.debug("type: {s}, rel_input: {s}", .{ @tagName(asset_type), rel_input });
switch (asset_type) {
.Scene => try processScene(allocator, rel_input, output_dir, asset_list_writer),
@ -129,6 +139,12 @@ fn createOutput(_type: AssetType, asset_path: AssetPath, output_dir: std.fs.Dir,
/// It all depends on the source asset.
fn processScene(allocator: std.mem.Allocator, input: []const u8, output_dir: std.fs.Dir, asset_list_writer: anytype) !void {
const input_z = try std.mem.concatWithSentinel(allocator, u8, &.{input}, 0);
const config: *c.aiPropertyStore = @as(?*c.aiPropertyStore, @ptrCast(c.aiCreatePropertyStore())) orelse return error.PropertyStore;
defer c.aiReleasePropertyStore(config);
// Remove point and line meshes
c.aiSetImportPropertyInteger(config, c.AI_CONFIG_PP_SBP_REMOVE, c.aiPrimitiveType_POINT | c.aiPrimitiveType_LINE);
const maybe_scene: ?*const c.aiScene = @ptrCast(c.aiImportFile(
input_z.ptr,
c.aiProcess_CalcTangentSpace | c.aiProcess_Triangulate | c.aiProcess_JoinIdenticalVertices | c.aiProcess_SortByPType | c.aiProcess_GenNormals,
@ -158,8 +174,9 @@ fn processScene(allocator: std.mem.Allocator, input: []const u8, output_dir: std
for (meshes) |mesh| {
const name = mesh.mName.data[0..mesh.mName.length];
std.log.debug("mesh name {s}\n", .{name});
var output = try createOutput(.Mesh, base_asset_path.subPath(name), output_dir, asset_list_writer);
var output = try createOutput(.Mesh, base_asset_path.subPath(try allocator.dupe(u8, name)), output_dir, asset_list_writer);
defer output.file.close();
try mesh_outputs.append(output.list_entry);
@ -201,21 +218,35 @@ fn processScene(allocator: std.mem.Allocator, input: []const u8, output_dir: std
const ent = &entities.items[idx];
// TODO: extract transform
var mat = Mat4.fromSlice(@ptrCast(&node.mTransformation));
mat = mat.transpose();
const mat_decomp = mat.decompose();
ent.transform.pos = mat_decomp.t;
ent.transform.rot = mat_decomp.r;
ent.transform.scale = mat_decomp.s;
if (node.mMeshes != null) {
const mesh_indices = node.mMeshes[0..node.mNumMeshes];
for (mesh_indices) |mesh_idx| {
const mesh_entry = mesh_outputs.items[@intCast(mesh_idx)];
ent.flags.mesh = true;
ent.flags.rotate = true;
if (mesh_indices.len == 1) {
const mesh_entry = mesh_outputs.items[mesh_indices[0]];
// TODO: turn multiple meshes into sub-entities
ent.mesh = .{
.handle = .{ .id = mesh_entry.src_path.hash() },
// TODO: extract material
};
ent.rotate = .{ .axis = Vec3.up(), .rate = 80 };
ent.flags.mesh = true;
ent.mesh.handle = .{ .id = mesh_entry.src_path.hash() };
} else {
for (mesh_indices) |mesh_idx| {
const mesh_entry = mesh_outputs.items[@intCast(mesh_idx)];
try entities.append(.{});
const sub_idx = entities.items.len - 1;
try parents.append(@intCast(idx));
const sub_ent = &entities.items[sub_idx];
sub_ent.flags.mesh = true;
sub_ent.mesh = .{
.handle = .{ .id = mesh_entry.src_path.hash() },
};
}
}
}
}
@ -273,7 +304,7 @@ fn processMesh(allocator: std.mem.Allocator, scene: *const c.aiScene, mesh: *con
}
for (0..mesh.mNumFaces) |i| {
std.debug.assert(mesh.mFaces[i].mNumIndices == 3);
if (mesh.mFaces[i].mNumIndices != 3) continue;
for (0..3) |j| {
const index = mesh.mFaces[i].mIndices[j];
if (index > std.math.maxInt(formats.Index)) {

View File

@ -16,6 +16,7 @@ pub const AssetListEntry = struct {
// TODO: might be a better way to do this
pub fn getOutputPath(self: *const AssetListEntry, out_buf: []u8) ![]u8 {
const path_len = self.src_path.strLen();
if (path_len == 0) return error.InvalidSrcPath;
const len = path_len + self.type.ext().len + 1;
if (out_buf.len < len) {
return error.BufferTooSmall;
@ -24,8 +25,13 @@ pub const AssetListEntry = struct {
_ = try self.src_path.toStringSep(out_buf, std.fs.path.sep);
var end = path_len;
const ext_len = std.fs.path.extension(out_buf[0..path_len]).len;
end -= ext_len;
switch (self.src_path) {
.simple => {
const ext_len = std.fs.path.extension(out_buf[0..path_len]).len;
end -= ext_len;
},
else => {},
}
// Extension
out_buf[end] = '.';
@ -38,17 +44,18 @@ pub const AssetListEntry = struct {
pub fn writeAssetListEntryText(writer: anytype, entry: AssetListEntry) !void {
try writer.writeAll(@tagName(entry.type));
try writer.writeByte(' ');
try writer.writeByte(0);
try entry.src_path.writeString(writer);
try writer.writeByte(0);
try writer.writeByte('\n');
}
pub fn readAssetListEntryText(alloc: std.mem.Allocator, reader: anytype) !AssetListEntry {
var buf: [std.fs.MAX_PATH_BYTES * 2 + 1]u8 = undefined;
const asset_type_str = try alloc.dupe(u8, try reader.readUntilDelimiterOrEof(&buf, ' ') orelse return error.MissingAssetType);
const asset_type_str = try alloc.dupe(u8, try reader.readUntilDelimiterOrEof(&buf, 0) orelse return error.MissingAssetType);
const asset_type = std.meta.stringToEnum(AssetType, asset_type_str) orelse return error.InvalidAssetType;
const src_path_str = try alloc.dupe(u8, try reader.readUntilDelimiterOrEof(&buf, ' ') orelse return error.MissingSrcPath);
const src_path_str = try alloc.dupe(u8, try reader.readUntilDelimiterOrEof(&buf, 0) orelse return error.MissingSrcPath);
const src_path = AssetPath.fromString(src_path_str);
return AssetListEntry{

View File

@ -29,6 +29,7 @@ pub const AssetType = enum {
};
pub const AssetPath = union(enum) {
invalid: void, // translates to handle with id: 0
simple: []const u8,
nested: struct {
path: []const u8,
@ -36,6 +37,10 @@ pub const AssetPath = union(enum) {
},
pub fn hash(self: AssetPath) u64 {
switch (self) {
.invalid => return 0,
else => {},
}
var hasher = std.hash.Wyhash.init(0);
std.hash.autoHashStrat(&hasher, self.getPath(), .Deep);
std.hash.autoHashStrat(&hasher, self.getSubPath(), .Deep);
@ -44,6 +49,7 @@ pub const AssetPath = union(enum) {
pub fn subPath(self: AssetPath, sub_path: []const u8) AssetPath {
return switch (self) {
.invalid => self,
.simple => |path| AssetPath{ .nested = .{ .path = path, .sub_path = sub_path } },
.nested => |nested| AssetPath{ .nested = .{ .path = nested.path, .sub_path = sub_path } },
};
@ -51,6 +57,7 @@ pub const AssetPath = union(enum) {
pub fn getPath(self: AssetPath) []const u8 {
return switch (self) {
.invalid => "",
.simple => |path| path,
.nested => |nested| nested.path,
};
@ -58,6 +65,7 @@ pub const AssetPath = union(enum) {
pub fn getSubPath(self: AssetPath) ?[]const u8 {
return switch (self) {
.invalid => null,
.nested => |nested| nested.sub_path,
else => null,
};
@ -65,6 +73,7 @@ pub const AssetPath = union(enum) {
pub inline fn strLen(self: AssetPath) usize {
return switch (self) {
.invalid => 0,
.simple => |path| path.len,
.nested => |nested| return nested.path.len + nested.sub_path.len + 1,
};
@ -72,6 +81,7 @@ pub const AssetPath = union(enum) {
pub fn writeString(self: AssetPath, writer: anytype) !void {
switch (self) {
.invalid => {},
.simple => |path| {
try writer.writeAll(path);
},
@ -93,6 +103,9 @@ pub const AssetPath = union(enum) {
}
switch (self) {
.invalid => {
return out_buf[0..0];
},
.simple => |path| {
@memcpy(out_buf[0..path.len], path);
return out_buf[0..path.len];
@ -113,7 +126,10 @@ pub const AssetPath = union(enum) {
}
pub fn fromString(str: []const u8) AssetPath {
if (std.mem.lastIndexOf(u8, str, "#")) |sep_idx| {
if (str.len == 0) {
return .invalid;
}
if (std.mem.indexOf(u8, str, "#")) |sep_idx| {
return .{
.nested = .{
.path = str[0..sep_idx],