Skip to content

Commit

Permalink
Round out some edges in scene and obj parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
SinclaM committed Jul 25, 2023
1 parent 2470724 commit 7d3f1a1
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 20 deletions.
4 changes: 3 additions & 1 deletion scenes/dragons.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
{
"name": "dragon",
"value": {
"type": { "from-obj": "dragon.obj" },
"type": {
"from-obj": { "file": "dragon.obj", "normalize": false }
},
"transform": [
{ "translate": [0, 0.1217, 0] },
{ "scale": [0.268, 0.268, 0.268] }
Expand Down
4 changes: 3 additions & 1 deletion scenes/teapot.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
}
},
{
"type": { "from-obj": "teapot.obj" },
"type": {
"from-obj": { "file": "teapot.obj" }
},
"transform": [
{ "translate": [0, 0.5, 0] },
{ "rotate-y": -0.4 }
Expand Down
34 changes: 20 additions & 14 deletions src/parsing/obj.zig
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub fn ObjParser(comptime T: type) type {
}

fn handleFace(
self: *Self, tokens: *std.mem.TokenIterator(u8, .scalar), material: ?Material(T)
self: *Self, tokens: *std.mem.TokenIterator(u8, .scalar), state: InheritedState
) !void {
const first = try Self.handleFaceHelper(tokens.next() orelse { return Self.Error.IncompleteFace; });

Expand Down Expand Up @@ -139,7 +139,8 @@ pub fn ObjParser(comptime T: type) type {
break :blk Shape(T).triangle(p1, p2, p3);
};

triangle.material = material orelse Material(T).new();
triangle.material = state.material orelse Material(T).new();
triangle.casts_shadow = state.casts_shadow orelse true;

try self.active_group.addChild(triangle);

Expand All @@ -166,15 +167,15 @@ pub fn ObjParser(comptime T: type) type {
self.active_group = g;
}

fn handleLine(self: *Self, line: []const u8, material: ?Material(T)) !void {
fn handleLine(self: *Self, line: []const u8, state: InheritedState) !void {
var tokens = std.mem.tokenizeScalar(u8, line, ' ');
if (tokens.next()) |first| {
if (std.mem.eql(u8, first, "v")) {
try self.handleVertex(&tokens);
} else if (std.mem.eql(u8, first, "vn")) {
try self.handleVertexNormal(&tokens);
} else if (std.mem.eql(u8, first, "f")) {
try self.handleFace(&tokens, material);
try self.handleFace(&tokens, state);
} else if (std.mem.eql(u8, first, "g")) {
try self.handleNamedGroup(&tokens);
} else {
Expand All @@ -185,7 +186,12 @@ pub fn ObjParser(comptime T: type) type {
}
}

pub fn loadObj(self: *Self, obj: []const u8, material: ?Material(T), normalize: bool) void {
const InheritedState = struct {
material: ?Material(T) = null,
casts_shadow: ?bool = null,
};

pub fn loadObj(self: *Self, obj: []const u8, state: InheritedState, normalize: bool) void {
var lines = std.mem.tokenizeScalar(u8, obj, '\n');

if (normalize) {
Expand Down Expand Up @@ -267,7 +273,7 @@ pub fn ObjParser(comptime T: type) type {
var l = lines.next();

while (l) |line| : (l = lines.next()) {
self.handleLine(line, material) catch { self.lines_ignored += 1; };
self.handleLine(line, state) catch { self.lines_ignored += 1; };
}
}

Expand All @@ -294,7 +300,7 @@ test "Ignoring unrecognized lines" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(gibberish, null, false);
parser.loadObj(gibberish, .{}, false);

try testing.expectEqual(parser.lines_ignored, 5);
}
Expand All @@ -314,7 +320,7 @@ test "Vertex records" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(obj, null, false);
parser.loadObj(obj, .{}, false);

try testing.expectEqual(parser.lines_ignored, 0);

Expand Down Expand Up @@ -349,7 +355,7 @@ test "Parsing triangle faces" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(obj, null, false);
parser.loadObj(obj, .{}, false);

try testing.expectEqual(parser.lines_ignored, 0);

Expand Down Expand Up @@ -383,7 +389,7 @@ test "Triangulating polygons" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(obj, null, false);
parser.loadObj(obj, .{}, false);

try testing.expectEqual(parser.lines_ignored, 0);
try testing.expectEqual(parser.default_group.variant.group.children.items.len, 3);
Expand Down Expand Up @@ -422,7 +428,7 @@ test "Triangles in groups" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(obj, null, false);
parser.loadObj(obj, .{}, false);

try testing.expectEqual(parser.lines_ignored, 0);

Expand Down Expand Up @@ -459,7 +465,7 @@ test "Converting an OBJ file to a group" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(obj, null, false);
parser.loadObj(obj, .{}, false);

try testing.expectEqual(parser.lines_ignored, 0);

Expand All @@ -486,7 +492,7 @@ test "Vertex normal records" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(obj, null, false);
parser.loadObj(obj, .{}, false);

try testing.expectEqual(parser.lines_ignored, 0);

Expand Down Expand Up @@ -520,7 +526,7 @@ test "Faces with normals" {
var parser = try ObjParser(f32).new(allocator);
defer parser.destroy();

parser.loadObj(obj, null, false);
parser.loadObj(obj, .{}, false);

try testing.expectEqual(parser.lines_ignored, 0);

Expand Down
11 changes: 7 additions & 4 deletions src/parsing/scene.zig
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ fn ObjectConfig(comptime T: type) type {
return struct {
@"type": union(enum) {
@"from-definition": []const u8,
@"from-obj": []const u8,
@"from-obj": *struct {
file: []const u8,
normalize: bool = true
},
sphere: void,
cube: void,
cylinder: *struct {
Expand Down Expand Up @@ -332,22 +335,22 @@ fn parseObject(
return SceneParseError.UnknownDefinition;
}
},
.@"from-obj" => |file_name| blk: {
.@"from-obj" => |from| blk: {
if (target.cpu.arch == .wasm32) {
return SceneParseError.NotImplemented;
} else {
var obj_dir = try std.fs.cwd().openDir("obj", .{});
defer obj_dir.close();

const obj = try obj_dir.readFileAlloc(
allocator, file_name, std.math.pow(usize, 2, 32)
allocator, from.file, std.math.pow(usize, 2, 32)
);
defer allocator.free(obj);

var parser = try ObjParser(T).new(allocator);
defer parser.destroy();

parser.loadObj(obj, material, false);
parser.loadObj(obj, .{ .material = material, .casts_shadow = casts_shadow }, from.normalize);

break :blk parser.toGroup().*;
}
Expand Down

0 comments on commit 7d3f1a1

Please sign in to comment.