diff --git a/src/gl_helper/model.zig b/src/gl_helper/model.zig index 01d8d98..1f53405 100644 --- a/src/gl_helper/model.zig +++ b/src/gl_helper/model.zig @@ -21,15 +21,16 @@ pub fn init( return .{ .data = data }; } -pub fn draw(self: *@This(), shader: Shader) void { +pub fn draw(self: *@This(), allocator: std.mem.Allocator, shader: Shader) !void { var iter = self.data.depthFirstIterator(); - while (iter.next()) |node| { - var rotation = node.val.rotation; - var current = node; - while (current.parent) |parent| { - rotation = zm.qmul(rotation, parent.val.rotation); - current = parent; - } + defer iter.deinit(allocator); + while (try iter.next(allocator)) |node| { + const rotation = node.val.rotation; + // var current = node; + // while (current.parent) |parent| { + // rotation = zm.qmul(rotation, parent.val.rotation); + // current = parent; + // } const model_matrix = zm.mul(zm.quatToMat(rotation), node.val.translation); const normal_matrix = zm.transpose(zm.inverse(model_matrix)); @@ -39,6 +40,6 @@ pub fn draw(self: *@This(), shader: Shader) void { } } -pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void { - self.data.deinit(allocator); +pub fn deinit(self: *@This(), allocator: std.mem.Allocator) !void { + try self.data.deinit(allocator); } diff --git a/src/main.zig b/src/main.zig index 36c50fe..0fc4e36 100644 --- a/src/main.zig +++ b/src/main.zig @@ -97,7 +97,7 @@ pub fn main() !void { defer floor.delete(); var robot = try initRobot(allocator, robot_texture); - defer robot.deinit(allocator); + defer robot.deinit(allocator) catch {}; // uniform data var light_color = zm.f32x4(1, 1, 1, 1); @@ -163,7 +163,7 @@ pub fn main() !void { floor.draw(model_shader); // animateRobot(&frame_counter, robot); - robot.draw(model_shader); + try robot.draw(allocator, model_shader); }, .fish => {}, } diff --git a/src/tree.zig b/src/tree.zig index 21a31f2..076468b 100644 --- a/src/tree.zig +++ b/src/tree.zig @@ -1,5 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; +const ArrayList = std.ArrayList; pub fn Tree(comptime T: type) type { return struct { @@ -7,71 +8,90 @@ pub fn Tree(comptime T: type) type { root: Node, - const Children = std.ArrayList(Node); + const Children = ArrayList(Node); const Node = struct { val: T, - parent: ?*Node, - index: usize, - children: std.ArrayList(Node), + // index: usize, + children: ArrayList(Node), - pub fn init(val: T, parent: ?*Node, index: usize) Node { + pub fn init(val: T) Node { return .{ .val = val, .children = .empty, - .parent = parent, - .index = index, }; } pub fn append(self: *Node, allocator: Allocator, val: T) !void { - const child = Node.init(val, self, self.children.items.len); + const child = Node.init(val); try self.children.append(allocator, child); } }; pub fn init(val: T) @This() { - return .{ .root = .init(val, null, 0) }; + return .{ .root = .init(val) }; } pub const DepthFirstIterator = struct { + const Frame = struct { + parent: ?*Node, + index: usize, + }; const State = enum { GoDeeper, GoBroader, }; tree: *Tree(T), current: ?*Node, + path: ArrayList(Frame), state: State, pub fn init(tree: *Tree(T)) DepthFirstIterator { return DepthFirstIterator{ .tree = tree, .current = &tree.root, + .path = .empty, .state = State.GoDeeper, }; } - pub fn next(it: *DepthFirstIterator) ?*Node { + pub fn next(it: *DepthFirstIterator, allocator: Allocator) !?*Node { // State machine while (it.current) |current| { switch (it.state) { State.GoDeeper => { // Follow child node until deepest possible level if (current.children.items.len > 0) { + try it.path.append(allocator, .{ + .index = 0, + .parent = current, + }); it.current = ¤t.children.items[0]; } else { it.state = State.GoBroader; + _ = it.path.pop(); return current; } }, State.GoBroader => { - if (current.parent) |parent| { - if (parent.children.items.len - 1 > (current.index)) { - it.current = &parent.children.items[current.index + 1]; - it.state = .GoDeeper; + const last_frame = it.path.pop(); + if (last_frame) |frame| { + if (frame.parent) |parent| { + if (parent.children.items.len > frame.index + 1) { + it.current = &parent.children.items[frame.index + 1]; + } else { + it.current = parent; + // return it.path.pop().?.parent; + } } else { - it.current = current.parent; - return current.parent; + return null; } + // if (parent.children.items.len > current.index + 1) { + // it.current = &parent.children.items[current.index + 1]; + // it.state = .GoDeeper; + // } else { + // it.current = current.parent; + // return current.parent; + // } } else { return null; } @@ -84,15 +104,20 @@ pub fn Tree(comptime T: type) type { pub fn reset(it: *DepthFirstIterator) void { it.current = it.tree.root; } + + pub fn deinit(self: *DepthFirstIterator, allocator: Allocator) void { + self.path.deinit(allocator); + } }; pub fn depthFirstIterator(tree: *@This()) DepthFirstIterator { return DepthFirstIterator.init(tree); } - pub fn deinit(self: *@This(), allocator: Allocator) void { + pub fn deinit(self: *@This(), allocator: Allocator) !void { var iterator = self.depthFirstIterator(); - while (iterator.next()) |node| { + defer iterator.deinit(allocator); + while (try iterator.next(allocator)) |node| { node.children.deinit(allocator); } }