Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/foundations/math/geometry/Plane.zig
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,15 @@ pub fn distanceToPoint(self: Plane, q: vector.vec3) f32 {
return vector.dotProduct(q, self.normal) - self.offset;
}

pub fn debug(self: Plane) void {
std.debug.print("plane: ({d}, {d}, {d}| {d})\n", .{
self.parameterized[0],
self.parameterized[1],
self.parameterized[2],
self.parameterized[3],
});
}

const std = @import("std");
const vector = @import("../vector.zig");
const float = @import("../float.zig");
56 changes: 28 additions & 28 deletions src/foundations/math/geometry/Triangle.zig
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
v0: vector.vec3,
v1: vector.vec3,
v2: vector.vec3,
p0: vector.vec3,
p1: vector.vec3,
p2: vector.vec3,
e0: vector.vec3,
e1: vector.vec3,
e2: vector.vec3,
normal: vector.vec3,

const Triangle = @This();

pub fn init(v0: vector.vec3, v1: vector.vec3, v2: vector.vec3) Triangle {
const e0 = vector.sub(v2, v1);
const e1 = vector.sub(v0, v2);
const e2 = vector.sub(v1, v0);
pub fn init(p0: vector.vec3, p1: vector.vec3, p2: vector.vec3) Triangle {
const e0 = vector.sub(p2, p1);
const e1 = vector.sub(p0, p2);
const e2 = vector.sub(p1, p0);
const ortho_v = vector.crossProduct(e0, e1);
const n = vector.normalize(ortho_v);
return .{
.v0 = v0,
.v1 = v1,
.v2 = v2,
.p0 = p0,
.p1 = p1,
.p2 = p2,
.e0 = e0,
.e1 = e1,
.e2 = e2,
Expand All @@ -30,9 +30,9 @@ pub fn area(self: Triangle) f32 {
}

pub fn barycentricCooordinate(self: Triangle, point: vector.vec3) vector.vec3 {
const d0 = vector.sub(point, self.v0);
const d1 = vector.sub(point, self.v1);
const d2 = vector.sub(point, self.v2);
const d0 = vector.sub(point, self.p0);
const d1 = vector.sub(point, self.p1);
const d2 = vector.sub(point, self.p2);
const area_t = vector.dotProduct(vector.crossProduct(self.e0, self.e1), self.normal);
return .{
vector.dotProduct(vector.crossProduct(self.e0, d2), self.normal) / area_t,
Expand All @@ -42,9 +42,9 @@ pub fn barycentricCooordinate(self: Triangle, point: vector.vec3) vector.vec3 {
}

pub fn centerOfGravity(self: Triangle) vector.vec3 {
var rv: vector.vec3 = self.v0;
rv = vector.add(rv, self.v1);
rv = vector.add(rv, self.v2);
var rv: vector.vec3 = self.p0;
rv = vector.add(rv, self.p1);
rv = vector.add(rv, self.p2);
return vector.mul(1.0 / 3.0, rv);
}

Expand All @@ -59,9 +59,9 @@ pub fn incenter(self: Triangle) vector.vec3 {
const l0 = vector.magnitude(self.e0);
const l1 = vector.magnitude(self.e1);
const l2 = vector.magnitude(self.e2);
var rv: vector.vec3 = vector.mul(l0, self.v0);
rv = vector.add(rv, vector.mul(l1, self.v1));
rv = vector.add(rv, vector.mul(l2, self.v2));
var rv: vector.vec3 = vector.mul(l0, self.p0);
rv = vector.add(rv, vector.mul(l1, self.p1));
rv = vector.add(rv, vector.mul(l2, self.p2));
return vector.mul(1.0 / (l0 + l1 + l2), rv);
}

Expand All @@ -83,9 +83,9 @@ pub fn circumCenter(self: Triangle) f32 {
const c1: f32 = d2 * d0;
const c2: f32 = d0 * d1;
const c: f32 = c0 + c1 + c2;
var cc_n = vector.mul(vector.add(c1, c2), self.v0);
cc_n = vector.add(cc_n, vector.mul(vector.add(c2, c0), self.v1));
cc_n = vector.add(cc_n, vector.mul(vector.add(c0, c1), self.v2));
var cc_n = vector.mul(vector.add(c1, c2), self.p0);
cc_n = vector.add(cc_n, vector.mul(vector.add(c2, c0), self.p1));
cc_n = vector.add(cc_n, vector.mul(vector.add(c0, c1), self.p2));
return vector.mul(1 / 2 * c, cc_n);
}

Expand All @@ -97,9 +97,9 @@ pub fn circumscribedCircle(self: Triangle) Circle {
const c1: f32 = d2 * d0;
const c2: f32 = d0 * d1;
const c: f32 = c0 + c1 + c2;
var cc_n = vector.mul(c1 + c2, self.v0);
cc_n = vector.add(cc_n, vector.mul(c2 + c0, self.v1));
cc_n = vector.add(cc_n, vector.mul(c0 + c1, self.v2));
var cc_n = vector.mul(c1 + c2, self.p0);
cc_n = vector.add(cc_n, vector.mul(c2 + c0, self.p1));
cc_n = vector.add(cc_n, vector.mul(c0 + c1, self.p2));
const cc = vector.mul(1 / (2 * c), cc_n);
const r = @sqrt((d0 + d1) * (d1 + d2) * (d2 + d0) / c) / 2;
const center = geometry.xUpLeftHandedTo2D(cc);
Expand All @@ -111,9 +111,9 @@ pub fn circumscribedCircle(self: Triangle) Circle {

pub fn vectorAt(self: Triangle, i: usize) vector.vec3 {
return switch (i) {
0 => self.v0,
1 => self.v1,
2 => self.v2,
0 => self.p0,
1 => self.p1,
2 => self.p2,
else => undefined,
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/foundations/math/vector.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub fn vec4ToVec3(v: vec4) vec3 {
return .{ v[0], v[1], v[2] };
}

pub fn vec3ToVec4(v: vec3) vec4 {
pub fn vec3ToVec4Point(v: vec3) vec4 {
return .{ v[0], v[1], v[2], 1.0 };
}

Expand Down
30 changes: 18 additions & 12 deletions src/foundations/object/object.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,28 @@ pub const object_type = enum {
sphere,
strip,
parallelepiped,
cylinder,
cone,
};

pub const object = union(object_type) {
triangle: triangle,
quad: quad,
cube: cube,
circle: circle,
sphere: sphere,
strip: strip,
triangle: Triangle,
quad: Quad,
cube: Cube,
circle: Circle,
sphere: Sphere,
strip: Strip,
parallelepiped: Parallelepiped,
cylinder: Cylinder,
cone: Cone,
};

pub const triangle = @import("object_triangle/object_triangle.zig");
pub const quad = @import("object_quad/object_quad.zig");
pub const cube = @import("object_cube/object_cube.zig");
pub const circle = @import("object_circle/object_circle.zig");
pub const sphere = @import("object_sphere/object_sphere.zig");
pub const strip = @import("object_strip/object_strip.zig");
pub const Triangle = @import("object_triangle/ObjectTriangle.zig");
pub const Quad = @import("object_quad/ObjectQuad.zig");
pub const Cube = @import("object_cube/ObjectCube.zig");
pub const Circle = @import("object_circle/ObjectCircle.zig");
pub const Sphere = @import("object_sphere/ObjectSphere.zig");
pub const Strip = @import("object_strip/ObjectStrip.zig");
pub const Parallelepiped = @import("object_parallelepiped/ObjectParallelepiped.zig");
pub const Cylinder = @import("object_cylinder/ObjectCylinder.zig");
pub const Cone = @import("object_cone/ObjectCone.zig");
75 changes: 75 additions & 0 deletions src/foundations/object/object_cone/ObjectCone.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
mesh: rhi.mesh,

const Cone = @This();
const num_triangles: usize = 256;
const change: f32 = std.math.pi / 128.0;
const num_vertices: usize = 4 * num_triangles;
const num_indices: usize = 3 * num_triangles;

pub fn init(
program: u32,
instance_data: []rhi.instanceData,
) Cone {
var d = data();

const vao_buf = rhi.attachInstancedBuffer(d.attribute_data[0..], instance_data);
const ebo = rhi.initEBO(@ptrCast(d.indices[0..]), vao_buf.vao);
return .{
.mesh = .{
.program = program,
.vao = vao_buf.vao,
.buffer = vao_buf.buffer,
.wire_mesh = false,
.instance_type = .{
.instanced = .{
.index_count = num_indices,
.instances_count = instance_data.len,
.ebo = ebo,
.primitive = c.GL_TRIANGLES,
.format = c.GL_UNSIGNED_INT,
},
},
.cull = false,
},
};
}

fn data() struct { attribute_data: [num_vertices]rhi.attributeData, indices: [num_indices]u32 } {
var attribute_data: [num_vertices]rhi.attributeData = undefined;
var indices: [num_indices]u32 = undefined;

const start: math.vector.vec3 = .{ 1, 0, 0 };
var offset: usize = 0;
var rad: f32 = 0;
for (0..num_triangles) |_| {
const uoffset: u32 = @intCast(offset);
const p0: math.vector.vec3 = .{ 0, @cos(rad), -@sin(rad) };
rad += change;
const p1: math.vector.vec3 = .{ 0, @cos(rad), -@sin(rad) };
const p2 = start;
const tri = math.geometry.Triangle.init(p0, p1, p2);
attribute_data[offset + 0] = .{
.position = tri.p0,
.normals = tri.normal,
};
indices[offset + 0] = uoffset + 0;
attribute_data[uoffset + 1] = .{
.position = tri.p1,
.normals = tri.normal,
};
indices[offset + 1] = uoffset + 1;
attribute_data[uoffset + 2] = .{
.position = tri.p2,
.normals = tri.normal,
};
indices[offset + 2] = uoffset + 2;
offset += 3;
}

return .{ .attribute_data = attribute_data, .indices = indices };
}

const std = @import("std");
const c = @import("../../c.zig").c;
const rhi = @import("../../rhi/rhi.zig");
const math = @import("../../math/math.zig");
141 changes: 141 additions & 0 deletions src/foundations/object/object_cylinder/ObjectCylinder.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
mesh: rhi.mesh,
vertex_data_size: usize,
instance_data_stride: usize,

const Cylinder = @This();

const num_sides = 160;
const num_vertices: usize = 4 * num_sides;
const num_indices: usize = 6 * num_sides; // because normals

pub fn init(
program: u32,
instance_data: []rhi.instanceData,
cull: bool,
) Cylinder {
var d = data();

const vao_buf = rhi.attachInstancedBuffer(d.data[0..], instance_data);
const ebo = rhi.initEBO(@ptrCast(d.indices[0..]), vao_buf.vao);
return .{
.mesh = .{
.program = program,
.vao = vao_buf.vao,
.buffer = vao_buf.buffer,
.instance_type = .{
.instanced = .{
.index_count = num_indices,
.instances_count = instance_data.len,
.ebo = ebo,
.primitive = c.GL_TRIANGLES,
.format = c.GL_UNSIGNED_INT,
},
},
.cull = cull,
},
.vertex_data_size = vao_buf.vertex_data_size,
.instance_data_stride = vao_buf.instance_data_stride,
};
}
pub fn updateInstanceAt(self: Cylinder, index: usize, instance_data: rhi.instanceData) void {
rhi.updateInstanceData(self.mesh.buffer, self.vertex_data_size, self.instance_data_stride, index, instance_data);
}

fn data() struct { data: [num_vertices]rhi.attributeData, indices: [num_indices]u32 } {
var rv_data: [num_vertices]rhi.attributeData = undefined;
var indices: [num_indices]u32 = undefined;
const origin: [3]f32 = .{ 0, 0, 0 };
const pp: math.geometry.Parallelepiped = .{
.v0 = .{ 1, 0, 0 },
.v1 = .{ 0, 1, 0 },
.v2 = .{ 0, 0, 1 },
};
var p0: math.vector.vec3 = origin;
var p1: math.vector.vec3 = pp.v0;
var p2: math.vector.vec3 = pp.v2;
var p3: math.vector.vec3 = math.vector.add(p1, p2);
var s_os: usize = 0;
var i_os: usize = 0;
{
var m = math.matrix.identity();
m = math.matrix.transformMatrix(m, math.matrix.scale(1, 1, 0.0125));
p0 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p0)));
p1 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p1)));
p2 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p2)));
p3 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p3)));
}

var offset: u32 = 0;
for (0..num_sides) |_| {
var m = math.matrix.identity();
m = math.matrix.transformMatrix(m, math.matrix.translate(0, 0, 0.0125));
m = math.matrix.transformMatrix(m, math.matrix.rotationX(0.0125 * std.math.pi));
p0 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p0)));
p1 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p1)));
p2 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p2)));
p3 = math.vector.vec4ToVec3(math.matrix.transformVector(m, math.vector.vec3ToVec4Point(p3)));
s_os = addSurface(&rv_data, p0, p1, p2, p3, s_os);
i_os = addIndicesPerSurface(&indices, offset, offset + 1, offset + 2, offset + 3, i_os);
offset += 4;
}
return .{ .data = rv_data, .indices = indices };
}

fn addIndicesPerSurface(
indices: *[num_indices]u32,
far_corner0: u32,
shared_0: u32,
shared_1: u32,
far_corner1: u32,
offset: usize,
) usize {
// first surface triangle
indices[offset] = far_corner0;
indices[offset + 1] = shared_1;
indices[offset + 2] = shared_0;
// second surface triangle
indices[offset + 3] = far_corner1;
indices[offset + 4] = shared_0;
indices[offset + 5] = shared_1;
return offset + 6;
}

fn addSurface(
s_data: *[num_vertices]rhi.attributeData,
sp0: math.vector.vec3,
sp1: math.vector.vec3,
sp2: math.vector.vec3,
sp3: math.vector.vec3,
offset: usize,
) usize {
const e1 = math.vector.sub(sp0, sp1);
const e2 = math.vector.sub(sp0, sp2);
const n = math.vector.normalize(math.vector.crossProduct(e1, e2));
s_data[offset] = .{
.position = sp0,
.color = color.debug_color,
.normals = n,
};
s_data[offset + 1] = .{
.position = sp1,
.color = color.debug_color,
.normals = n,
};
s_data[offset + 2] = .{
.position = sp2,
.color = color.debug_color,
.normals = n,
};
s_data[offset + 3] = .{
.position = sp3,
.color = color.debug_color,
.normals = n,
};
return offset + 4;
}

const std = @import("std");
const c = @import("../../c.zig").c;
const rhi = @import("../../rhi/rhi.zig");
const math = @import("../../math/math.zig");
const color = @import("../../color/color.zig");
Loading