Skip to content
151 changes: 111 additions & 40 deletions src/foundations/object/object_sphere/ObjectSphere.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ instance_data_stride: usize,

const Sphere = @This();
const angle_delta: f32 = std.math.pi * 0.02;
const x_angle_delta = angle_delta / 2.0;
const x_grid_rows: f32 = std.math.pi * 2.0 - angle_delta * 1.5;
const grid_dimension: usize = @intFromFloat((2.0 * std.math.pi) / angle_delta);
const num_vertices: usize = grid_dimension * grid_dimension;
const quad_dimensions = grid_dimension - 1;
const num_quads = quad_dimensions * quad_dimensions;
const num_indices: usize = num_quads * 6;
const num_triangles = quad_dimensions;
const num_triangles_in_end = quad_dimensions * 2;
const num_quads_in_grid = ((x_grid_rows - x_angle_delta * 2) / x_angle_delta) * grid_dimension;
const num_vertices: usize = (num_triangles_in_end * 2 + 1) + (3 * grid_dimension) * (3 * grid_dimension) + (num_triangles_in_end * 2 + 1);
const num_indices: usize = (grid_dimension * 3) + 6 * num_quads_in_grid + (grid_dimension * 3);
const sphere_scale: f32 = 0.75;

pub fn init(
Expand All @@ -26,9 +31,6 @@ pub fn init(
.vao = vao_buf.vao,
.buffer = vao_buf.buffer,
.wire_mesh = wireframe,
// TODO: this code has a degenerate triangle, cull face bug at when i % grid_dimension == 0
// I have to do the math on paper to figure this out.
.cull = false,
.instance_type = .{
.instanced = .{
.index_count = num_indices,
Expand All @@ -51,51 +53,120 @@ pub fn updateInstanceAt(self: Sphere, index: usize, instance_data: rhi.instanceD
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;
var x_axis_angle: f32 = 0;

const x_angle_delta: f32 = angle_delta;
const y_angle_delta = angle_delta;
var x_axis_angle: f32 = x_angle_delta;
var y_axis_angle: f32 = y_angle_delta;

var positions: [num_vertices]math.vector.vec3 = undefined;
{
var pi: usize = 0;
while (x_axis_angle < 2 * std.math.pi) : (x_axis_angle += x_angle_delta) {
const y_angle_delta: f32 = x_angle_delta;
var y_axis_angle: f32 = 0;
while (y_axis_angle < 2 * std.math.pi) : (y_axis_angle += y_angle_delta) {
positions[pi] = math.rotation.sphericalCoordinatesToCartesian3D(math.vector.vec3, .{
1.0,
y_axis_angle,
x_axis_angle,
});
pi += 1;
}
}
const r: f32 = 1.0;

const start: math.vector.vec3 = .{ 1, 0, 0 };
const end: math.vector.vec3 = .{ -1, 0, 0 };
positions[0] = start;
positions[1] = end;
var pi: usize = 2;
while (y_axis_angle <= std.math.pi * 2 + y_angle_delta) : (y_axis_angle += y_angle_delta) {
positions[pi] = .{
r * @cos(x_axis_angle),
r * @sin(x_axis_angle) * @sin(y_axis_angle),
r * @sin(x_axis_angle) * @cos(y_axis_angle),
};
pi += 1;
}
y_axis_angle += y_angle_delta;
x_axis_angle += x_angle_delta;

var ii: usize = 0;
var i: u32 = 0;
var pii: u32 = 1;
while (i < num_triangles) : (i += 1) {
indices[ii] = 0;
indices[ii + 1] = pii + 1;
indices[ii + 2] = pii + 2;
ii += 3;
pii += 1;
}
indices[ii] = 0;
indices[ii + 1] = pii + 1;
indices[ii + 2] = 2;
ii += 3;
pii += 2;

var iii: usize = 2;
while (x_axis_angle < x_grid_rows) : (x_axis_angle += x_angle_delta) {
const start_iii = iii;
y_axis_angle = y_angle_delta;
for (0..grid_dimension) |ri| {
positions[pi] = .{
r * @cos(x_axis_angle),
r * @sin(x_axis_angle) * @sin(y_axis_angle),
r * @sin(x_axis_angle) * @cos(y_axis_angle),
};
pi += 1;
y_axis_angle += y_angle_delta;
positions[pi] = .{
r * @cos(x_axis_angle),
r * @sin(x_axis_angle) * @sin(y_axis_angle),
r * @sin(x_axis_angle) * @cos(y_axis_angle),
};
pi += 1;
{
var tr = iii + 1;
if (ri == grid_dimension - 1) {
tr = start_iii;
}
const br = iii + grid_dimension + 1;
const tl = iii;
const bl = iii + grid_dimension;

{
var ii: usize = 0;
var last: usize = 0;
var fl: usize = 0;
var sl: usize = 0;
for (0..quad_dimensions) |_| {
for (0..quad_dimensions) |_| {
const i = fl + sl;
const tr = i + 1;
const br = i + grid_dimension + 1;
const tl = i;
var bl = i + grid_dimension;
bl += 0;

addVertexData(positions, indices[0..], attribute_data[0..], tr, br, tl, bl, ii);
// Triangle 1
indices[ii] = @intCast(tl);
indices[ii + 1] = @intCast(bl);
indices[ii + 2] = @intCast(br);

// Triangle 2
indices[ii + 3] = @intCast(tl);
indices[ii + 4] = @intCast(br);
indices[ii + 5] = @intCast(tr);

ii += 6;
last = br;
fl += 1;
iii += 1;
}
sl += 1;
y_axis_angle += y_angle_delta;
pii += 2;
}
}

y_axis_angle = y_angle_delta;
x_axis_angle = std.math.pi + x_angle_delta;
while (y_axis_angle <= std.math.pi * 2 + y_angle_delta) : (y_axis_angle += y_angle_delta) {
positions[pi] = .{
r * @cos(x_axis_angle),
r * @sin(x_axis_angle) * @sin(y_axis_angle),
r * @sin(x_axis_angle) * @cos(y_axis_angle),
};
pi += 1;
}

i = 0;
const closer = pii;
while (i < num_triangles) : (i += 1) {
indices[ii + 2] = 1;
indices[ii + 1] = pii + 0;
indices[ii] = pii + 1;
ii += 3;
pii += 1;
}
indices[ii + 2] = 1;
indices[ii + 1] = pii;
indices[ii] = closer;
var adi: usize = 0;

while (adi < pi) : (adi += 1) {
attribute_data[adi].position = positions[adi];
attribute_data[adi].normals = math.vector.normalize(positions[adi]);
}

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

Expand Down