starting to fill out entities, materials, textures. cleaned up math a little, still WIP.
This commit is contained in:
parent
78293db515
commit
5887223090
|
@ -0,0 +1,104 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const Vec4f = @import("vec.zig").Vec4f;
|
||||||
|
const Mat4f = @import("vec.zig").Mat4f;
|
||||||
|
|
||||||
|
const BoxData = packed struct {};
|
||||||
|
|
||||||
|
pub fn Box(comptime Vec: type, comptime Shift: comptime_int) type {
|
||||||
|
return packed struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub const empty = Self{
|
||||||
|
.lo = Vec.s(1 << Shift),
|
||||||
|
.hi = Vec.s(-(1 << Shift)),
|
||||||
|
};
|
||||||
|
|
||||||
|
lo: Vec,
|
||||||
|
hi: Vec,
|
||||||
|
|
||||||
|
pub inline fn new(lo: Vec, hi: Vec) Self {
|
||||||
|
return Self{
|
||||||
|
.lo = lo,
|
||||||
|
.hi = hi,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn center(self: Self) Vec {
|
||||||
|
return self.lo.lerpvs(self.hi, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn size(self: Self) Vec {
|
||||||
|
return self.hi.sub(self.lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn extents(self: Self) Vec {
|
||||||
|
return self.size().mulvs(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn contains(self: Self, pt: Vec) bool {
|
||||||
|
return pt.gteq(self.lo).all3() and pt.lteq(self.hi).all3();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn area(self: Self) f32 {
|
||||||
|
const sz = self.size();
|
||||||
|
return sz.x * sz.y * if (Vec.nelem > 2) sz.z else 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn fromPts(pts: []const Vec) Self {
|
||||||
|
var lo = Vec.s(1 << Shift);
|
||||||
|
var hi = Vec.s(-(1 << Shift));
|
||||||
|
for (pts) |pt| {
|
||||||
|
lo = lo.min(pt);
|
||||||
|
hi = hi.max(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Self{
|
||||||
|
.lo = lo,
|
||||||
|
.hi = hi,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn uni(lhs: Self, rhs: Self) Self {
|
||||||
|
return Self{
|
||||||
|
.lo = lhs.lo.min(rhs.lo),
|
||||||
|
.hi = lhs.hi.max(rhs.hi),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn intersect(lhs: Self, rhs: Self) Self {
|
||||||
|
var lo = lhs.lo.min(rhs.lo);
|
||||||
|
var hi = lhs.hi.max(rhs.hi);
|
||||||
|
const mid = lo.lerpvs(hi, 0.5);
|
||||||
|
const inverted = lo.gt(hi);
|
||||||
|
lo = lo.select(mid, inverted);
|
||||||
|
hi = hi.select(mid, inverted);
|
||||||
|
|
||||||
|
return Self{
|
||||||
|
.lo = lo,
|
||||||
|
.hi = hi,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: genericise
|
||||||
|
pub inline fn transform(matrix: Mat4f, box: Self) Self {
|
||||||
|
var ct = box.center();
|
||||||
|
var exts = box.hi.sub(ct);
|
||||||
|
ct = matrix.mulPt(ct);
|
||||||
|
exts = matrix.mulExtents(exts);
|
||||||
|
return Self{
|
||||||
|
.lo = ct.sub(exts),
|
||||||
|
.hi = ct.add(exts),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub const Box2d = Box(Vec2f); // need to understand the shift magic
|
||||||
|
pub const Box3d = Box(Vec4f, 20);
|
||||||
|
|
||||||
|
test "Box3d" {
|
||||||
|
const b1 = Box3d.fromPts(&.{ Vec4f.s(1), Vec4f.s(-1) });
|
||||||
|
try std.testing.expectEqual(@as(f32, 8), b1.area());
|
||||||
|
const v1 = Vec4f.s(0.5);
|
||||||
|
try std.testing.expect(b1.contains(v1));
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const vec = @import("vec.zig");
|
||||||
|
const Vec3f = vec.Vec3f;
|
||||||
|
const Vec4f = vec.Vec4f;
|
||||||
|
|
||||||
|
pub const Mat3f = Mat(3, Vec3f);
|
||||||
|
|
||||||
|
pub const Mat4f = packed struct {
|
||||||
|
const Self = @This();
|
||||||
|
pub const zero = Mat(4, Vec4f).zero;
|
||||||
|
pub const id = Mat(4, Vec4f).id;
|
||||||
|
|
||||||
|
pub usingnamespace Mat(4, Vec4f);
|
||||||
|
|
||||||
|
pub inline fn lookAt(eye: Vec4f, at: Vec4f, up: Vec4f) Self {
|
||||||
|
// right-handed (ew)
|
||||||
|
const f = at.sub(eye).normalize3();
|
||||||
|
const s = f.cross3(up).normalize3();
|
||||||
|
const u = s.cross3(f).normalize3();
|
||||||
|
|
||||||
|
const tx = -s.dot3(eye);
|
||||||
|
const ty = -u.dot3(eye);
|
||||||
|
const tz = f.dot3(eye);
|
||||||
|
return Self{
|
||||||
|
.c0 = .{ .x = s.x, .y = u.x, .z = -f.x, .w = 0 },
|
||||||
|
.c1 = .{ .x = s.y, .y = u.y, .z = -f.y, .w = 0 },
|
||||||
|
.c2 = .{ .x = s.z, .y = u.z, .z = -f.z, .w = 0 },
|
||||||
|
.c3 = .{ .x = tx, .y = ty, .z = tz, .w = 1 },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn glPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self {
|
||||||
|
const t = std.math.tan(fov_y * 0.5);
|
||||||
|
var m = zero;
|
||||||
|
m.c0.x = 1.0 / (aspect * t);
|
||||||
|
m.c1.y = 1.0 / t;
|
||||||
|
m.c2.z = -1.0 * (z_far * z_near) / (z_far - z_near);
|
||||||
|
m.c3.z = -2.0 * (z_far * z_near) / (z_far - z_near);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn vkPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self {
|
||||||
|
var m = glPerspective(fov_y, aspect, z_near, z_far);
|
||||||
|
m.c1.y *= -1.0;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn Mat(comptime nelem: comptime_int, comptime Vec: type) type {
|
||||||
|
return packed struct {
|
||||||
|
const Self = @This();
|
||||||
|
pub const nelem = nelem;
|
||||||
|
|
||||||
|
pub const zero = Self{};
|
||||||
|
pub const id = Self{
|
||||||
|
.c0 = .{ .x = 1 },
|
||||||
|
.c1 = .{ .y = 1 },
|
||||||
|
.c2 = if (nelem > 2 and Vec.nelem > 2) .{ .z = 1 } else {},
|
||||||
|
.c3 = if (nelem > 3 and Vec.nelem > 3) .{ .w = 1 } else {},
|
||||||
|
};
|
||||||
|
|
||||||
|
c0: Vec = .{},
|
||||||
|
c1: Vec = .{},
|
||||||
|
c2: if (nelem > 2) Vec else void = if (nelem > 2) .{} else {},
|
||||||
|
c3: if (nelem > 3) Vec else void = if (nelem > 3) .{} else {},
|
||||||
|
|
||||||
|
pub inline fn mulCol(self: Self, col: Vec) Vec {
|
||||||
|
const a = self.c0.mulvs(col.x);
|
||||||
|
const b = self.c1.mulvs(col.y);
|
||||||
|
const c = if (nelem > 2 and Vec.nelem > 2) self.c2.mulvs(col.z) else {};
|
||||||
|
const d = if (nelem > 3 and Vec.nelem > 2) self.c0.mulvs(col.w) else {};
|
||||||
|
return a.add(b).add(if (nelem > 2) if (nelem > 3) c.add(d) else c else Vec.zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn mul(a: Self, b: Self) Self {
|
||||||
|
return Self{
|
||||||
|
.c0 = a.mulCol(b.c0),
|
||||||
|
.c1 = a.mulCol(b.c1),
|
||||||
|
.c2 = if (nelem > 2) a.mulCol(b.c2) else {},
|
||||||
|
.c3 = if (nelem > 3) a.mulCol(b.c3) else {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
144
src/math/vec.zig
144
src/math/vec.zig
|
@ -13,18 +13,65 @@ pub const Vec2u = Vec(2, u32);
|
||||||
pub const Vec3u = Vec(3, u32);
|
pub const Vec3u = Vec(3, u32);
|
||||||
pub const Vec4u = Vec(4, u32);
|
pub const Vec4u = Vec(4, u32);
|
||||||
|
|
||||||
pub fn Vec(comptime nelem: comptime_int, comptime T: anytype) type {
|
pub const Vec2b = BoolVec(2);
|
||||||
|
pub const Vec3b = BoolVec(3);
|
||||||
|
pub const Vec4b = BoolVec(4);
|
||||||
|
|
||||||
|
pub fn BoolVec(comptime nelem: comptime_int) type {
|
||||||
assert(nelem > 1);
|
assert(nelem > 1);
|
||||||
assert(nelem <= 4);
|
assert(nelem <= 4);
|
||||||
|
|
||||||
return packed struct {
|
return packed struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
x: bool = false,
|
||||||
|
y: bool = false,
|
||||||
|
z: if (nelem > 2) bool else void = if (nelem > 2) false else {},
|
||||||
|
w: if (nelem > 3) bool else void = if (nelem > 3) false else {},
|
||||||
|
|
||||||
|
pub inline fn all2(self: Self) bool {
|
||||||
|
return self.x and self.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3-element operations
|
||||||
|
pub usingnamespace if (nelem >= 3) struct {
|
||||||
|
pub inline fn all3(self: Self) bool {
|
||||||
|
return self.all2() and if (nelem > 2) self.z else true;
|
||||||
|
}
|
||||||
|
} else struct {};
|
||||||
|
|
||||||
|
pub usingnamespace if (nelem >= 4) struct {
|
||||||
|
pub inline fn all4(self: Self) bool {
|
||||||
|
return self.all3() and if (nelem > 3) self.w else true;
|
||||||
|
}
|
||||||
|
} else struct {};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Vec(comptime nelem: comptime_int, comptime T: type) type {
|
||||||
|
assert(nelem > 1);
|
||||||
|
assert(nelem <= 4);
|
||||||
|
|
||||||
|
return packed struct {
|
||||||
|
const Self = @This();
|
||||||
|
pub const nelem = nelem;
|
||||||
|
pub const T = T;
|
||||||
|
const Vecnb = BoolVec(Self.nelem);
|
||||||
|
|
||||||
x: T = 0,
|
x: T = 0,
|
||||||
y: T = 0,
|
y: T = 0,
|
||||||
z: if (nelem > 2) T else void = if (nelem > 2) 0 else {},
|
z: if (nelem > 2) T else void = if (nelem > 2) 0 else {},
|
||||||
w: if (nelem > 3) T else void = if (nelem > 3) 0 else {},
|
w: if (nelem > 3) T else void = if (nelem > 3) 0 else {},
|
||||||
|
|
||||||
|
pub inline fn s(a: T) Self {
|
||||||
|
return Self{
|
||||||
|
.x = a,
|
||||||
|
.y = a,
|
||||||
|
.z = if (nelem > 2) a else {},
|
||||||
|
.w = if (nelem > 3) a else {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn add(lhs: Self, rhs: Self) Self {
|
pub inline fn add(lhs: Self, rhs: Self) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.x = lhs.x + rhs.x,
|
.x = lhs.x + rhs.x,
|
||||||
|
@ -65,6 +112,15 @@ pub fn Vec(comptime nelem: comptime_int, comptime T: anytype) type {
|
||||||
return lhs.mulvs(1 / rhs);
|
return lhs.mulvs(1 / rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn min(a: Self, b: Self) Self {
|
||||||
|
return Self{
|
||||||
|
.x = @minimum(a.x, b.x),
|
||||||
|
.y = @minimum(a.y, b.y),
|
||||||
|
.z = if (nelem > 2) @minimum(a.z, b.z) else {},
|
||||||
|
.w = if (nelem > 3) @minimum(a.w, b.w) else {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn max(a: Self, b: Self) Self {
|
pub inline fn max(a: Self, b: Self) Self {
|
||||||
return Self{
|
return Self{
|
||||||
.x = @maximum(a.x, b.x),
|
.x = @maximum(a.x, b.x),
|
||||||
|
@ -90,6 +146,24 @@ pub fn Vec(comptime nelem: comptime_int, comptime T: anytype) type {
|
||||||
return self.divvs(self.length());
|
return self.divvs(self.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn lteq(lhs: Self, rhs: Self) Vecnb {
|
||||||
|
return Vecnb{
|
||||||
|
.x = lhs.x <= rhs.x,
|
||||||
|
.y = lhs.y <= rhs.y,
|
||||||
|
.z = if (nelem > 2) lhs.z <= rhs.z else {},
|
||||||
|
.w = if (nelem > 3) lhs.w <= rhs.w else {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn gteq(lhs: Self, rhs: Self) Vecnb {
|
||||||
|
return Vecnb{
|
||||||
|
.x = lhs.x >= rhs.x,
|
||||||
|
.y = lhs.y >= rhs.y,
|
||||||
|
.z = if (nelem > 2) lhs.z >= rhs.z else {},
|
||||||
|
.w = if (nelem > 3) lhs.w >= rhs.w else {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// 3-element operations
|
// 3-element operations
|
||||||
pub usingnamespace if (nelem >= 3) struct {
|
pub usingnamespace if (nelem >= 3) struct {
|
||||||
pub inline fn sum3(self: Self) T {
|
pub inline fn sum3(self: Self) T {
|
||||||
|
@ -158,71 +232,3 @@ test "vec" {
|
||||||
|
|
||||||
try std.testing.expectEqual(@as(i32, 6), boop.sum());
|
try std.testing.expectEqual(@as(i32, 6), boop.sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: comptime magic?
|
|
||||||
pub const Float4x4 = packed struct {
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
pub const zero = Self{};
|
|
||||||
pub const id = Self{
|
|
||||||
.c0 = .{ .x = 1, .y = 0, .z = 0, .w = 0 },
|
|
||||||
.c1 = .{ .x = 0, .y = 1, .z = 0, .w = 0 },
|
|
||||||
.c2 = .{ .x = 0, .y = 0, .z = 1, .w = 0 },
|
|
||||||
.c3 = .{ .x = 0, .y = 0, .z = 0, .w = 1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
c0: Vec4f = .{},
|
|
||||||
c1: Vec4f = .{},
|
|
||||||
c2: Vec4f = .{},
|
|
||||||
c3: Vec4f = .{},
|
|
||||||
|
|
||||||
pub inline fn mulCol(self: Self, col: Vec4f) Vec4f {
|
|
||||||
const a = self.c0.mulvs(col.x);
|
|
||||||
const b = self.c1.mulvs(col.y);
|
|
||||||
const c = self.c2.mulvs(col.z);
|
|
||||||
const d = self.c0.mulvs(col.w);
|
|
||||||
return a.add(b).add(c.add(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn mul(a: Self, b: Self) Self {
|
|
||||||
return Self{
|
|
||||||
.c0 = a.mulCol(b.c0),
|
|
||||||
.c1 = a.mulCol(b.c1),
|
|
||||||
.c2 = a.mulCol(b.c2),
|
|
||||||
.c3 = a.mulCol(b.c3),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn lookAt(eye: Vec4f, at: Vec4f, up: Vec4f) Float4x4 {
|
|
||||||
// right-handed (ew)
|
|
||||||
const f = at.sub(eye).normalize3();
|
|
||||||
const s = f.cross3(up).normalize3();
|
|
||||||
const u = s.cross3(f).normalize3();
|
|
||||||
|
|
||||||
const tx = -s.dot3(eye);
|
|
||||||
const ty = -u.dot3(eye);
|
|
||||||
const tz = f.dot3(eye);
|
|
||||||
return Float4x4{
|
|
||||||
.c0 = .{ .x = s.x, .y = u.x, .z = -f.x, .w = 0 },
|
|
||||||
.c1 = .{ .x = s.y, .y = u.y, .z = -f.y, .w = 0 },
|
|
||||||
.c2 = .{ .x = s.z, .y = u.z, .z = -f.z, .w = 0 },
|
|
||||||
.c3 = .{ .x = tx, .y = ty, .z = tz, .w = 1 },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn glPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self {
|
|
||||||
const t = std.math.tan(fov_y * 0.5);
|
|
||||||
var m = zero;
|
|
||||||
m.c0.x = 1.0 / (aspect * t);
|
|
||||||
m.c1.y = 1.0 / t;
|
|
||||||
m.c2.z = -1.0 * (z_far * z_near) / (z_far - z_near);
|
|
||||||
m.c3.z = -2.0 * (z_far * z_near) / (z_far - z_near);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn vkPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self {
|
|
||||||
var m = glPerspective(fov_y, aspect, z_near, z_far);
|
|
||||||
m.c1.y *= -1.0;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Vec4f = @import("../math/vec.zig").Vec4f;
|
const Vec4f = @import("../math/vec.zig").Vec4f;
|
||||||
const Float4x4 = @import("../math/vec.zig").Float4x4;
|
const Mat4f = @import("../math/mat.zig").Mat4f;
|
||||||
const Quat = @import("../math/quat.zig").Quat;
|
const Quat = @import("../math/quat.zig").Quat;
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
@ -17,16 +17,16 @@ pub fn get() Self {
|
||||||
return s_camera;
|
return s_camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn getProj(self: *const Self, aspect: f32) Float4x4 {
|
pub inline fn getProj(self: *const Self, aspect: f32) Mat4f {
|
||||||
return Float4x4.vkPerspective(std.math.degreesToRadians(f32, self.fov_y), aspect, self.z_near, self.z_far);
|
return Mat4f.vkPerspective(std.math.degreesToRadians(f32, self.fov_y), aspect, self.z_near, self.z_far);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn getView(self: *const Self) Float4x4 {
|
pub inline fn getView(self: *const Self) Mat4f {
|
||||||
const pos = self.position;
|
const pos = self.position;
|
||||||
const rot = self.rotation;
|
const rot = self.rotation;
|
||||||
return Float4x4.lookAt(pos, pos.add(rot.fwd()), rot.up());
|
return Mat4f.lookAt(pos, pos.add(rot.fwd()), rot.up());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn getWorldToClip(self: *const Self, aspect: f32) Float4x4 {
|
pub inline fn getWorldToClip(self: *const Self, aspect: f32) Mat4f {
|
||||||
return self.getProj(aspect).mul(self.getView());
|
return self.getProj(aspect).mul(self.getView());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
const UUID = @import("../common/uuid.zig").UUID;
|
||||||
|
|
||||||
|
const mat = @import("../math/mat.zig");
|
||||||
|
const Mat4f = mat.Mat4f;
|
||||||
|
const Mat3f = mat.Mat3f;
|
||||||
|
const vec = @import("../math/vec.zig");
|
||||||
|
const Vec4f = vec.Vec4f;
|
||||||
|
const Quat = @import("../math/quat.zig").Quat;
|
||||||
|
const Box3d = @import("../math/box.zig").Box3d;
|
||||||
|
const Mesh = @import("meshes.zig").Mesh;
|
||||||
|
const Material = @import("materials.zig").Material;
|
||||||
|
|
||||||
|
// TODO memory
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
|
const Entities = @This();
|
||||||
|
|
||||||
|
var s_entities: Entities = undefined;
|
||||||
|
|
||||||
|
names: std.ArrayList(UUID),
|
||||||
|
meshes: std.ArrayList(Mesh.Id),
|
||||||
|
bounds: std.ArrayList(Box3d),
|
||||||
|
materials: std.ArrayList(Material),
|
||||||
|
matrices: std.ArrayList(Mat4f),
|
||||||
|
inv_matrices: std.ArrayList(Mat3f),
|
||||||
|
translations: std.ArrayList(Vec4f),
|
||||||
|
rotations: std.ArrayList(Quat),
|
||||||
|
scales: std.ArrayList(Vec4f),
|
||||||
|
mod_time: std.time.Instant,
|
||||||
|
|
||||||
|
pub fn init() void {
|
||||||
|
s_entities.names = std.ArrayList(UUID).init(allocator);
|
||||||
|
s_entities.meshes = std.ArrayList(Mesh.Id).init(allocator);
|
||||||
|
s_entities.bounds = std.ArrayList(Box3d).init(allocator);
|
||||||
|
s_entities.materials = std.ArrayList(Material).init(allocator);
|
||||||
|
s_entities.matrices = std.ArrayList(Mat4f).init(allocator);
|
||||||
|
s_entities.inv_matrices = std.ArrayList(Mat3f).init(allocator);
|
||||||
|
s_entities.translations = std.ArrayList(Vec4f).init(allocator);
|
||||||
|
s_entities.rotations = std.ArrayList(Quat).init(allocator);
|
||||||
|
s_entities.scales = std.ArrayList(Vec4f).init(allocator);
|
||||||
|
s_entities.mod_time = std.time.Instant.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update() void {}
|
||||||
|
|
||||||
|
pub fn get() *const Entities {
|
||||||
|
return &s_entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit() void {
|
||||||
|
delete(get());
|
||||||
|
s_entities.names.deinit();
|
||||||
|
s_entities.meshes.deinit();
|
||||||
|
s_entities.bounds.deinit();
|
||||||
|
s_entities.materials.deinit();
|
||||||
|
s_entities.matrices.deinit();
|
||||||
|
s_entities.inv_matrices.deinit();
|
||||||
|
s_entities.translations.deinit();
|
||||||
|
s_entities.rotations.deinit();
|
||||||
|
s_entities.scales.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(self: *const Entities, name: UUID) !i32 {
|
||||||
|
self.names.append(name);
|
||||||
|
self.translations.append(Vec4f.zero);
|
||||||
|
self.scales.append(Vec4f.one);
|
||||||
|
self.rotations.append(Quat.id);
|
||||||
|
self.matrices.append(Mat4f.id);
|
||||||
|
self.inv_matrices.append(Mat3f.id);
|
||||||
|
self.mod_time = std.time.Instant.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroyAtIndex(ents: *const Entities, i: i32) void {
|
||||||
|
assert(i >= 0);
|
||||||
|
assert(i < ents.names.len);
|
||||||
|
ents.meshes[i].release();
|
||||||
|
ents.materials[i].albedo.release();
|
||||||
|
ents.materials[i].rome.release();
|
||||||
|
ents.materials[i].normal.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn removeAtIndex(ents: *const Entities, i: i32) void {
|
||||||
|
ents.destroyAtIndex(i);
|
||||||
|
|
||||||
|
ents.names.swapRemove(i);
|
||||||
|
ents.meshes.swapRemove(i);
|
||||||
|
ents.bounds.swapRemove(i);
|
||||||
|
ents.materials.swapRemove(i);
|
||||||
|
ents.matrices.swapRemove(i);
|
||||||
|
ents.inv_matrices.swapRemove(i);
|
||||||
|
ents.translations.swapRemove(i);
|
||||||
|
ents.rotations.swapRemove(i);
|
||||||
|
ents.scales.swapRemove(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rm(ents: *const Entities, name: UUID) bool {
|
||||||
|
if (ents.find(name)) |i| {
|
||||||
|
ents.removeAtIndex(i);
|
||||||
|
ents.mod_time = std.time.Instant.now();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find(ents: *const Entities, name: UUID) ?i32 {
|
||||||
|
return ents.names.find(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(ents: *const Entities) void {
|
||||||
|
for (ents.names) |_, i| {
|
||||||
|
ents.destroyAtIndex(i);
|
||||||
|
}
|
||||||
|
ents.mod_time = std.time.Instant.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(ents: *const Entities) void {
|
||||||
|
ents.clear();
|
||||||
|
ents.names.clearAndFree();
|
||||||
|
ents.meshes.clearAndFree();
|
||||||
|
ents.bounds.clearAndFree();
|
||||||
|
ents.materials.clearAndFree();
|
||||||
|
ents.matrices.clearAndFree();
|
||||||
|
ents.inv_matrices.clearAndFree();
|
||||||
|
ents.translations.clearAndFree();
|
||||||
|
ents.rotations.clearAndFree();
|
||||||
|
ents.scales.clearAndFree();
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
const vec = @import("../math/vec.zig");
|
||||||
|
const Vec4f = vec.Vec4f;
|
||||||
|
|
||||||
|
const Texture = @import("textures.zig").Texture;
|
||||||
|
const DiskTexture = @import("textures.zig").DiskTexture;
|
||||||
|
|
||||||
|
pub const MatFlags = packed struct {
|
||||||
|
emissive: bool = false, // enable emissive term
|
||||||
|
sky: bool = false, // lookup emission from sky cubemap
|
||||||
|
water: bool = false,
|
||||||
|
slime: bool = false,
|
||||||
|
lava: bool = false,
|
||||||
|
refractive: bool = false, // enable refraction term
|
||||||
|
warped: bool = false, // uv animated
|
||||||
|
animated: bool = false, // keyframe animated
|
||||||
|
underwater: bool = false, // SURF_UNDERWATER
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Material = packed struct {
|
||||||
|
albedo: Texture.Id, // rgba8 srgb (albedo, alpha)
|
||||||
|
rome: Texture.Id, // rgba8 srgb (roughness, occlusion, metallic, emission)
|
||||||
|
normal: Texture.Id, // rg16 (tangent space xy)
|
||||||
|
flags: MatFlags,
|
||||||
|
mean_free_path: Vec4f, // .w = scatter dir 'g'
|
||||||
|
ior: f32, // index of refraction
|
||||||
|
bumpiness: f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DiskMaterial = packed struct {
|
||||||
|
albedo: DiskTexture.Id,
|
||||||
|
rome: DiskTexture.Id,
|
||||||
|
normal: DiskTexture.Id,
|
||||||
|
flags: MatFlags,
|
||||||
|
ior: f32,
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
const UUID = @import("uuid").UUID;
|
||||||
|
|
||||||
|
const vec = @import("../math/vec.zig");
|
||||||
|
const Vec4f = vec.Vec4f;
|
||||||
|
const Vec4i = vec.Vec4i;
|
||||||
|
|
||||||
|
pub const Mesh = packed struct {
|
||||||
|
const version = 5;
|
||||||
|
|
||||||
|
positions: [*]Vec4f,
|
||||||
|
normals: [*]Vec4f,
|
||||||
|
uvs: [*]Vec4f,
|
||||||
|
tex_indices: [*]Vec4i,
|
||||||
|
length: i32,
|
||||||
|
id: Id,
|
||||||
|
|
||||||
|
pub const Id = packed struct {
|
||||||
|
version: u8,
|
||||||
|
index: u24,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DiskMesh = packed struct {
|
||||||
|
version: i32,
|
||||||
|
length: i32,
|
||||||
|
name: [64]u8,
|
||||||
|
|
||||||
|
pub const Id = packed struct {
|
||||||
|
id: UUID,
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,74 @@
|
||||||
|
const vk = @import("vulkan");
|
||||||
|
const UUID = @import("../common/uuid.zig").UUID;
|
||||||
|
|
||||||
|
const Table = @import("../containers/Table.zig");
|
||||||
|
const Vec2i = @import("../math/vec.zig").Vec2i;
|
||||||
|
|
||||||
|
const TTable = Table(Texture.Id);
|
||||||
|
var s_table: TTable = undefined;
|
||||||
|
|
||||||
|
pub fn init() void {
|
||||||
|
s_table = TTable.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update() void {}
|
||||||
|
|
||||||
|
pub fn deinit() void {}
|
||||||
|
|
||||||
|
pub fn getTable() *const TTable {
|
||||||
|
return &s_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Texture = packed struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
const PalRow = enum {
|
||||||
|
white,
|
||||||
|
brown,
|
||||||
|
light_blue,
|
||||||
|
green,
|
||||||
|
red,
|
||||||
|
orange,
|
||||||
|
gold,
|
||||||
|
peach,
|
||||||
|
purple,
|
||||||
|
magenta,
|
||||||
|
tan,
|
||||||
|
light_green,
|
||||||
|
yellow,
|
||||||
|
blue,
|
||||||
|
fire,
|
||||||
|
brights,
|
||||||
|
|
||||||
|
pub const count = @enumToInt(PalRow.brights);
|
||||||
|
};
|
||||||
|
|
||||||
|
size: Vec2i,
|
||||||
|
texels: [*]u8,
|
||||||
|
format: vk.Format,
|
||||||
|
slot: Id,
|
||||||
|
|
||||||
|
pub fn get(id: Id) *const Self {
|
||||||
|
return s_table.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn isCurrent(id: Id) bool {
|
||||||
|
return s_table.exists(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Id = packed struct {
|
||||||
|
version: u8,
|
||||||
|
index: u24,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DiskTexture = packed struct {
|
||||||
|
version: i32,
|
||||||
|
format: vk.Format,
|
||||||
|
name: []u8,
|
||||||
|
size: Vec2i,
|
||||||
|
|
||||||
|
pub const Id = packed struct {
|
||||||
|
id: UUID,
|
||||||
|
};
|
||||||
|
};
|
|
@ -17,14 +17,17 @@ const framebuffer = @import("framebuffer.zig");
|
||||||
const Targets = @import("Targets.zig");
|
const Targets = @import("Targets.zig");
|
||||||
const RenderPass = @import("RenderPass.zig");
|
const RenderPass = @import("RenderPass.zig");
|
||||||
const Bindings = @import("Bindings.zig");
|
const Bindings = @import("Bindings.zig");
|
||||||
|
const Entities = @import("../Entities.zig");
|
||||||
|
const Texture = @import("../textures.zig").Texture;
|
||||||
|
|
||||||
const vec = @import("../../math/vec.zig");
|
const vec = @import("../../math/vec.zig");
|
||||||
|
const mat = @import("../../math/mat.zig");
|
||||||
const Vec2f = vec.Vec2f;
|
const Vec2f = vec.Vec2f;
|
||||||
const Vec4f = vec.Vec4f;
|
const Vec4f = vec.Vec4f;
|
||||||
const Vec4i = vec.Vec4i;
|
const Vec4i = vec.Vec4i;
|
||||||
const Vec2u = vec.Vec2u;
|
const Vec2u = vec.Vec2u;
|
||||||
const Vec4u = vec.Vec4u;
|
const Vec4u = vec.Vec4u;
|
||||||
const Float4x4 = vec.Float4x4;
|
const Mat4f = mat.Mat4f;
|
||||||
|
|
||||||
pub fn init(device: *const Device, swapchain: *Swapchain) !void {
|
pub fn init(device: *const Device, swapchain: *Swapchain) !void {
|
||||||
errdefer {
|
errdefer {
|
||||||
|
@ -73,7 +76,7 @@ pub fn execute(device: *const Device, swapchain: *Swapchain) !void {
|
||||||
|
|
||||||
const DepthPass = struct {
|
const DepthPass = struct {
|
||||||
const PushConstants = packed struct {
|
const PushConstants = packed struct {
|
||||||
local_to_clip: Float4x4,
|
local_to_clip: Mat4f,
|
||||||
};
|
};
|
||||||
|
|
||||||
var s_render_pass: vk.RenderPass = undefined;
|
var s_render_pass: vk.RenderPass = undefined;
|
||||||
|
@ -91,12 +94,6 @@ const DepthPass = struct {
|
||||||
.dst_access_mask = .{ .color_attachment_write_bit = true },
|
.dst_access_mask = .{ .color_attachment_write_bit = true },
|
||||||
};
|
};
|
||||||
|
|
||||||
//var info = RenderPass.Description{
|
|
||||||
// .src_stage_mask = .{ .early_fragment_tests_bit = true },
|
|
||||||
// .src_access_mask = .{ .depth_stencil_attachment_read_bit = true },
|
|
||||||
// .dst_stage_mask = .{ .late_fragment_tests_bit = true },
|
|
||||||
// .dst_access_mask = .{ .depth_stencil_attachment_write_bit = true },
|
|
||||||
//};
|
|
||||||
info.attachments[0] = .{
|
info.attachments[0] = .{
|
||||||
.format = depth_buffer.format,
|
.format = depth_buffer.format,
|
||||||
.layout = .depth_stencil_attachment_optimal,
|
.layout = .depth_stencil_attachment_optimal,
|
||||||
|
@ -166,7 +163,6 @@ const DepthPass = struct {
|
||||||
defer pm_depth_execute.end();
|
defer pm_depth_execute.end();
|
||||||
|
|
||||||
const camera = Camera.get();
|
const camera = Camera.get();
|
||||||
|
|
||||||
const world_to_clip = camera.getWorldToClip(swapchain.getAspect());
|
const world_to_clip = camera.getWorldToClip(swapchain.getAspect());
|
||||||
|
|
||||||
const attachments = &[_]*Image{Targets.getDepthBuffer(swapchain)};
|
const attachments = &[_]*Image{Targets.getDepthBuffer(swapchain)};
|
||||||
|
@ -202,7 +198,7 @@ const DepthPass = struct {
|
||||||
|
|
||||||
const OpaquePass = struct {
|
const OpaquePass = struct {
|
||||||
const Globals = packed struct {
|
const Globals = packed struct {
|
||||||
g_WorldToClip: Float4x4,
|
g_WorldToClip: Mat4f,
|
||||||
g_Eye: Vec4f,
|
g_Eye: Vec4f,
|
||||||
|
|
||||||
g_HdrEnabled: f32,
|
g_HdrEnabled: f32,
|
||||||
|
@ -215,8 +211,8 @@ const OpaquePass = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
const PushConstants = packed struct {
|
const PushConstants = packed struct {
|
||||||
kLocalToWorld: Float4x4,
|
kLocalToWorld: Mat4f,
|
||||||
kIMc0: Vec4f,
|
kIMc0: Vec4f, // components of inverse matrix
|
||||||
kIMc1: Vec4f,
|
kIMc1: Vec4f,
|
||||||
kIMc2: Vec4f,
|
kIMc2: Vec4f,
|
||||||
kTexInds: Vec4u,
|
kTexInds: Vec4u,
|
||||||
|
@ -239,13 +235,6 @@ const OpaquePass = struct {
|
||||||
.dst_access_mask = .{ .color_attachment_write_bit = true },
|
.dst_access_mask = .{ .color_attachment_write_bit = true },
|
||||||
};
|
};
|
||||||
|
|
||||||
//var info = RenderPass.Description{
|
|
||||||
// .src_stage_mask = .{ .late_fragment_tests_bit = true },
|
|
||||||
// .dst_stage_mask = .{ .early_fragment_tests_bit = true, .color_attachment_output_bit = true },
|
|
||||||
// .src_access_mask = .{ .depth_stencil_attachment_write_bit = true },
|
|
||||||
// .dst_access_mask = .{ .depth_stencil_attachment_read_bit = true, .color_attachment_write_bit = true },
|
|
||||||
//};
|
|
||||||
|
|
||||||
info.attachments[0] = .{
|
info.attachments[0] = .{
|
||||||
.format = depth_buffer.format,
|
.format = depth_buffer.format,
|
||||||
.layout = .depth_stencil_attachment_optimal,
|
.layout = .depth_stencil_attachment_optimal,
|
||||||
|
@ -436,10 +425,31 @@ const OpaquePass = struct {
|
||||||
cmdbuf.beginRenderPass(device, s_render_pass, fbuf, rect, &clear_values);
|
cmdbuf.beginRenderPass(device, s_render_pass, fbuf, rect, &clear_values);
|
||||||
defer cmdbuf.endRenderPass(device);
|
defer cmdbuf.endRenderPass(device);
|
||||||
|
|
||||||
// ITERATE THROUGH ENTITIES AND DRAW THEM FINALLY OMG
|
const ents = Entities.get();
|
||||||
|
for (ents.meshes.items) |mesh, i| {
|
||||||
|
const albedo = Texture.get(ents.materials.items[i].albedo);
|
||||||
|
const rome = Texture.get(ents.materials.items[i].rome);
|
||||||
|
const normal = Texture.get(ents.materials.items[i].normal);
|
||||||
|
|
||||||
|
const pc = PushConstants{
|
||||||
|
.kLocalToWorld = ents.matrices[i],
|
||||||
|
.kIMc0 = ents.invMatrices[i].c0,
|
||||||
|
.kIMc1 = ents.invMatrices[i].c1,
|
||||||
|
.kIMc2 = ents.invMatrices[i].c2,
|
||||||
|
.kTexInds = .{
|
||||||
|
.x = if (albedo) albedo.slot.index else 0,
|
||||||
|
.y = if (rome) rome.slot.index else 0,
|
||||||
|
.z = if (normal) normal.slot.index else 0,
|
||||||
|
.w = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
cmdbuf.pushConstants(device, &s_pass, &pc);
|
||||||
|
cmdbuf.drawMesh(mesh.id);
|
||||||
|
}
|
||||||
|
|
||||||
const pc = PushConstants{
|
const pc = PushConstants{
|
||||||
.kLocalToWorld = Float4x4.id,
|
.kLocalToWorld = Mat4f.id,
|
||||||
.kIMc0 = Vec4f{ .x = 1, .y = 0, .z = 0, .w = 0 },
|
.kIMc0 = Vec4f{ .x = 1, .y = 0, .z = 0, .w = 0 },
|
||||||
.kIMc1 = Vec4f{ .x = 0, .y = 1, .z = 0, .w = 0 },
|
.kIMc1 = Vec4f{ .x = 0, .y = 1, .z = 0, .w = 0 },
|
||||||
.kIMc2 = Vec4f{ .x = 0, .y = 0, .z = 1, .w = 0 },
|
.kIMc2 = Vec4f{ .x = 0, .y = 0, .z = 1, .w = 0 },
|
||||||
|
|
Loading…
Reference in New Issue