1 Commits

Author SHA1 Message Date
879e442ac6 New iterator attempt 2026-03-29 00:45:35 +01:00
3 changed files with 57 additions and 60 deletions

View File

@@ -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);
}

View File

@@ -96,37 +96,8 @@ pub fn main() !void {
const floor = initFloor(floor_texture);
defer floor.delete();
var shape = Shape.initCube();
defer shape.deinit();
shape.unweld();
shape.computeNormals();
shape.translate(-0.5, -1, -0.5);
var chest = shape.clone();
defer chest.deinit();
chest.scale(0.3, 0.4, 0.15);
var model_data = Tree(Model.JointData).init(.{
.mesh = Mesh.initShape(chest, robot_texture, .triangles),
.translation = zm.translation(0, 0.425 + 0.4, 0),
.rotation = zm.qidentity(),
});
var head = shape.clone();
defer head.deinit();
head.scale(0.1, 0.1, 0.1);
try model_data.root.append(allocator, .{
.mesh = Mesh.initShape(head, robot_texture, .triangles),
.translation = zm.translation(0, 0.425 + 0.4 + 0.1, 0),
.rotation = zm.qidentity(),
});
var robot = Model.init(model_data);
// var robot = try initRobot(allocator, robot_texture);
defer robot.deinit(allocator);
var robot = try initRobot(allocator, robot_texture);
defer robot.deinit(allocator) catch {};
// uniform data
var light_color = zm.f32x4(1, 1, 1, 1);
@@ -192,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 => {},
}

View File

@@ -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 = &current.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);
}
}