1 Commits

Author SHA1 Message Date
40dc03ff58 inlined robot init 2026-03-28 23:12:50 +01:00
3 changed files with 60 additions and 57 deletions

View File

@@ -21,16 +21,15 @@ pub fn init(
return .{ .data = data }; return .{ .data = data };
} }
pub fn draw(self: *@This(), allocator: std.mem.Allocator, shader: Shader) !void { pub fn draw(self: *@This(), shader: Shader) void {
var iter = self.data.depthFirstIterator(); var iter = self.data.depthFirstIterator();
defer iter.deinit(allocator); while (iter.next()) |node| {
while (try iter.next(allocator)) |node| { var rotation = node.val.rotation;
const rotation = node.val.rotation; var current = node;
// var current = node; while (current.parent) |parent| {
// while (current.parent) |parent| { rotation = zm.qmul(rotation, parent.val.rotation);
// rotation = zm.qmul(rotation, parent.val.rotation); current = parent;
// current = parent; }
// }
const model_matrix = zm.mul(zm.quatToMat(rotation), node.val.translation); const model_matrix = zm.mul(zm.quatToMat(rotation), node.val.translation);
const normal_matrix = zm.transpose(zm.inverse(model_matrix)); const normal_matrix = zm.transpose(zm.inverse(model_matrix));
@@ -40,6 +39,6 @@ pub fn draw(self: *@This(), allocator: std.mem.Allocator, shader: Shader) !void
} }
} }
pub fn deinit(self: *@This(), allocator: std.mem.Allocator) !void { pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
try self.data.deinit(allocator); self.data.deinit(allocator);
} }

View File

@@ -96,8 +96,37 @@ pub fn main() !void {
const floor = initFloor(floor_texture); const floor = initFloor(floor_texture);
defer floor.delete(); defer floor.delete();
var robot = try initRobot(allocator, robot_texture); var shape = Shape.initCube();
defer robot.deinit(allocator) catch {}; 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);
// uniform data // uniform data
var light_color = zm.f32x4(1, 1, 1, 1); var light_color = zm.f32x4(1, 1, 1, 1);
@@ -163,7 +192,7 @@ pub fn main() !void {
floor.draw(model_shader); floor.draw(model_shader);
// animateRobot(&frame_counter, robot); // animateRobot(&frame_counter, robot);
try robot.draw(allocator, model_shader); robot.draw(model_shader);
}, },
.fish => {}, .fish => {},
} }

View File

@@ -1,6 +1,5 @@
const std = @import("std"); const std = @import("std");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const ArrayList = std.ArrayList;
pub fn Tree(comptime T: type) type { pub fn Tree(comptime T: type) type {
return struct { return struct {
@@ -8,93 +7,74 @@ pub fn Tree(comptime T: type) type {
root: Node, root: Node,
const Children = ArrayList(Node); const Children = std.ArrayList(Node);
const Node = struct { const Node = struct {
val: T, val: T,
// index: usize, parent: ?*Node,
children: ArrayList(Node), index: usize,
children: std.ArrayList(Node),
pub fn init(val: T) Node { pub fn init(val: T, parent: ?*Node, index: usize) Node {
return .{ return .{
.val = val, .val = val,
.children = .empty, .children = .empty,
.parent = parent,
.index = index,
}; };
} }
pub fn append(self: *Node, allocator: Allocator, val: T) !void { pub fn append(self: *Node, allocator: Allocator, val: T) !void {
const child = Node.init(val); const child = Node.init(val, self, self.children.items.len);
try self.children.append(allocator, child); try self.children.append(allocator, child);
} }
}; };
pub fn init(val: T) @This() { pub fn init(val: T) @This() {
return .{ .root = .init(val) }; return .{ .root = .init(val, null, 0) };
} }
pub const DepthFirstIterator = struct { pub const DepthFirstIterator = struct {
const Frame = struct {
parent: ?*Node,
index: usize,
};
const State = enum { const State = enum {
GoDeeper, GoDeeper,
GoBroader, GoBroader,
}; };
tree: *Tree(T), tree: *Tree(T),
current: ?*Node, current: ?*Node,
path: ArrayList(Frame),
state: State, state: State,
pub fn init(tree: *Tree(T)) DepthFirstIterator { pub fn init(tree: *Tree(T)) DepthFirstIterator {
return DepthFirstIterator{ return DepthFirstIterator{
.tree = tree, .tree = tree,
.current = &tree.root, .current = &tree.root,
.path = .empty,
.state = State.GoDeeper, .state = State.GoDeeper,
}; };
} }
pub fn next(it: *DepthFirstIterator, allocator: Allocator) !?*Node { pub fn next(it: *DepthFirstIterator) ?*Node {
// State machine // State machine
while (it.current) |current| { while (it.current) |current| {
switch (it.state) { switch (it.state) {
State.GoDeeper => { State.GoDeeper => {
// Follow child node until deepest possible level // Follow child node until deepest possible level
if (current.children.items.len > 0) { if (current.children.items.len > 0) {
try it.path.append(allocator, .{
.index = 0,
.parent = current,
});
it.current = &current.children.items[0]; it.current = &current.children.items[0];
} else { } else {
it.state = State.GoBroader; it.state = State.GoBroader;
_ = it.path.pop();
return current; return current;
} }
}, },
State.GoBroader => { State.GoBroader => {
const last_frame = it.path.pop(); if (current.parent) |parent| {
if (last_frame) |frame| { if (parent.children.items.len - 1 > (current.index)) {
if (frame.parent) |parent| { it.current = &parent.children.items[current.index + 1];
if (parent.children.items.len > frame.index + 1) { it.state = .GoDeeper;
it.current = &parent.children.items[frame.index + 1];
} else { } else {
it.current = parent; it.current = current.parent;
// return it.path.pop().?.parent; return current.parent;
} }
} else { } else {
return null; 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;
}
}, },
} }
} }
@@ -104,20 +84,15 @@ pub fn Tree(comptime T: type) type {
pub fn reset(it: *DepthFirstIterator) void { pub fn reset(it: *DepthFirstIterator) void {
it.current = it.tree.root; it.current = it.tree.root;
} }
pub fn deinit(self: *DepthFirstIterator, allocator: Allocator) void {
self.path.deinit(allocator);
}
}; };
pub fn depthFirstIterator(tree: *@This()) DepthFirstIterator { pub fn depthFirstIterator(tree: *@This()) DepthFirstIterator {
return DepthFirstIterator.init(tree); return DepthFirstIterator.init(tree);
} }
pub fn deinit(self: *@This(), allocator: Allocator) !void { pub fn deinit(self: *@This(), allocator: Allocator) void {
var iterator = self.depthFirstIterator(); var iterator = self.depthFirstIterator();
defer iterator.deinit(allocator); while (iterator.next()) |node| {
while (try iterator.next(allocator)) |node| {
node.children.deinit(allocator); node.children.deinit(allocator);
} }
} }