BLOK DISTROJ
This commit is contained in:
2
castle
2
castle
Submodule castle updated: 6c9a786926...31651dc96a
502
src/Chunks.zig
502
src/Chunks.zig
@@ -13,11 +13,15 @@ const Iterator2 = math.Iterator2;
|
||||
|
||||
chunks: std.AutoHashMapUnmanaged([3]i16, Chunk),
|
||||
|
||||
const RaycastHit = struct {
|
||||
pub const SweepHit = struct {
|
||||
normal_frac: vm.Vector3Int,
|
||||
projected_distance_sv: i32,
|
||||
};
|
||||
|
||||
pub const RaycastHit = struct {
|
||||
voxel: vm.Vector3Int,
|
||||
};
|
||||
|
||||
pub fn deinit(self: *Chunks, engine: *Engine, descriptor_pool: vk.DescriptorPool, allocator: std.mem.Allocator) void {
|
||||
var it = self.chunks.valueIterator();
|
||||
while (it.next()) |chunk| {
|
||||
@@ -48,13 +52,116 @@ pub fn getVoxelAt(self: *const Chunks, vx: vm.Vector3Int) ?Blocks.Id {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroyVoxelAt(self: *const Chunks, vx: vm.Vector3Int, engine: *Engine, blocks: *const Blocks, allocator: std.mem.Allocator) !void {
|
||||
const min_ck = vm.Vector3Int.initScalar(std.math.minInt(i16));
|
||||
const max_ck = vm.Vector3Int.initScalar(std.math.maxInt(i16));
|
||||
const ck = vx.divScalar(c.vx_per_ck);
|
||||
if ((ck.x < min_ck.x) | (ck.y < min_ck.y) | (ck.z < min_ck.z) | (ck.x > max_ck.x) | (ck.y > max_ck.y) | (ck.z > max_ck.z)) {
|
||||
@branchHint(.unlikely);
|
||||
return;
|
||||
}
|
||||
|
||||
const x: i16 = @intCast(ck.x);
|
||||
const y: i16 = @intCast(ck.y);
|
||||
const z: i16 = @intCast(ck.z);
|
||||
|
||||
if (self.chunks.getPtr(.{ x, y, z })) |chunk| {
|
||||
const ckvx = vx.modScalar(c.vx_per_ck);
|
||||
const block = &chunk.blocks[@intCast(ckvx.z)][@intCast(ckvx.y)][@intCast(ckvx.x)];
|
||||
if (block.* != .air) {
|
||||
block.* = .air;
|
||||
|
||||
try chunk.refresh(engine, blocks, .{
|
||||
.positive_x = self.chunks.getPtr(.{ x + 1, y, z }),
|
||||
.negative_x = self.chunks.getPtr(.{ x - 1, y, z }),
|
||||
.positive_y = self.chunks.getPtr(.{ x, y + 1, z }),
|
||||
.negative_y = self.chunks.getPtr(.{ x, y - 1, z }),
|
||||
.positive_z = self.chunks.getPtr(.{ x, y, z + 1 }),
|
||||
.negative_z = self.chunks.getPtr(.{ x, y, z - 1 }),
|
||||
}, allocator);
|
||||
|
||||
if (ckvx.x == 0) {
|
||||
if (self.chunks.getPtr(.{ x - 1, y, z })) |neighbor| {
|
||||
try neighbor.refresh(engine, blocks, .{
|
||||
.positive_x = self.chunks.getPtr(.{ x, y, z }),
|
||||
.negative_x = self.chunks.getPtr(.{ x - 2, y, z }),
|
||||
.positive_y = self.chunks.getPtr(.{ x - 1, y + 1, z }),
|
||||
.negative_y = self.chunks.getPtr(.{ x - 1, y - 1, z }),
|
||||
.positive_z = self.chunks.getPtr(.{ x - 1, y, z + 1 }),
|
||||
.negative_z = self.chunks.getPtr(.{ x - 1, y, z - 1 }),
|
||||
}, allocator);
|
||||
}
|
||||
} else if (ckvx.x == c.vx_per_ck - 1) {
|
||||
if (self.chunks.getPtr(.{ x + 1, y, z })) |neighbor| {
|
||||
try neighbor.refresh(engine, blocks, .{
|
||||
.positive_x = self.chunks.getPtr(.{ x + 2, y, z }),
|
||||
.negative_x = self.chunks.getPtr(.{ x, y, z }),
|
||||
.positive_y = self.chunks.getPtr(.{ x + 1, y + 1, z }),
|
||||
.negative_y = self.chunks.getPtr(.{ x + 1, y - 1, z }),
|
||||
.positive_z = self.chunks.getPtr(.{ x + 1, y, z + 1 }),
|
||||
.negative_z = self.chunks.getPtr(.{ x + 1, y, z - 1 }),
|
||||
}, allocator);
|
||||
}
|
||||
}
|
||||
|
||||
if (ckvx.y == 0) {
|
||||
if (self.chunks.getPtr(.{ x, y - 1, z })) |neighbor| {
|
||||
try neighbor.refresh(engine, blocks, .{
|
||||
.positive_x = self.chunks.getPtr(.{ x + 1, y - 1, z }),
|
||||
.negative_x = self.chunks.getPtr(.{ x - 1, y - 1, z }),
|
||||
.positive_y = self.chunks.getPtr(.{ x, y, z }),
|
||||
.negative_y = self.chunks.getPtr(.{ x, y - 2, z }),
|
||||
.positive_z = self.chunks.getPtr(.{ x, y - 1, z + 1 }),
|
||||
.negative_z = self.chunks.getPtr(.{ x, y - 1, z - 1 }),
|
||||
}, allocator);
|
||||
}
|
||||
} else if (ckvx.y == c.vx_per_ck - 1) {
|
||||
if (self.chunks.getPtr(.{ x, y + 1, z })) |neighbor| {
|
||||
try neighbor.refresh(engine, blocks, .{
|
||||
.positive_x = self.chunks.getPtr(.{ x + 1, y + 1, z }),
|
||||
.negative_x = self.chunks.getPtr(.{ x - 1, y + 1, z }),
|
||||
.positive_y = self.chunks.getPtr(.{ x, y + 2, z }),
|
||||
.negative_y = self.chunks.getPtr(.{ x, y, z }),
|
||||
.positive_z = self.chunks.getPtr(.{ x, y + 1, z + 1 }),
|
||||
.negative_z = self.chunks.getPtr(.{ x, y + 1, z - 1 }),
|
||||
}, allocator);
|
||||
}
|
||||
}
|
||||
|
||||
if (ckvx.z == 0) {
|
||||
if (self.chunks.getPtr(.{ x, y, z - 1 })) |neighbor| {
|
||||
try neighbor.refresh(engine, blocks, .{
|
||||
.positive_x = self.chunks.getPtr(.{ x + 1, y, z - 1 }),
|
||||
.negative_x = self.chunks.getPtr(.{ x - 1, y, z - 1 }),
|
||||
.positive_y = self.chunks.getPtr(.{ x, y + 1, z - 1 }),
|
||||
.negative_y = self.chunks.getPtr(.{ x, y - 1, z - 1 }),
|
||||
.positive_z = self.chunks.getPtr(.{ x, y, z }),
|
||||
.negative_z = self.chunks.getPtr(.{ x, y, z - 2 }),
|
||||
}, allocator);
|
||||
}
|
||||
} else if (ckvx.z == c.vx_per_ck - 1) {
|
||||
if (self.chunks.getPtr(.{ x, y, z + 1 })) |neighbor| {
|
||||
try neighbor.refresh(engine, blocks, .{
|
||||
.positive_x = self.chunks.getPtr(.{ x + 1, y, z + 1 }),
|
||||
.negative_x = self.chunks.getPtr(.{ x - 1, y, z + 1 }),
|
||||
.positive_y = self.chunks.getPtr(.{ x, y + 1, z + 1 }),
|
||||
.negative_y = self.chunks.getPtr(.{ x, y - 1, z + 1 }),
|
||||
.positive_z = self.chunks.getPtr(.{ x, y, z + 2 }),
|
||||
.negative_z = self.chunks.getPtr(.{ x, y, z }),
|
||||
}, allocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isSolid(self: *const Chunks, vx: vm.Vector3Int) bool {
|
||||
const maybe_id = getVoxelAt(self, vx);
|
||||
// NOTE `null` is considered solid, as it's out of bounds.
|
||||
return maybe_id != .air;
|
||||
}
|
||||
|
||||
pub fn sweepCastDown(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vector3Int, distance_sv: i32) ?RaycastHit {
|
||||
pub fn sweepCastDown(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vector3Int, distance_sv: i32) ?SweepHit {
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, min_sv.x);
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, min_sv.y);
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, max_sv.x);
|
||||
@@ -84,7 +191,7 @@ pub fn sweepCastDown(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vect
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn sweepCastUp(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vector3Int, distance_sv: i32) ?RaycastHit {
|
||||
pub fn sweepCastUp(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vector3Int, distance_sv: i32) ?SweepHit {
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, min_sv.x);
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, min_sv.y);
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, max_sv.x);
|
||||
@@ -114,11 +221,11 @@ pub fn sweepCastUp(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vector
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn sweepCastHorizontal(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vector3Int, ray_sv: vm.Vector2Int) ?RaycastHit {
|
||||
pub fn sweepCastHorizontal(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: vm.Vector3Int, ray_sv: vm.Vector2Int) ?SweepHit {
|
||||
const min_z_vx = c.subvoxelsToVoxels(.border_up, min_sv.z);
|
||||
const max_z_vx = c.subvoxelsToVoxels(.border_down, max_sv.z);
|
||||
|
||||
var hit: ?RaycastHit = null;
|
||||
var hit: ?SweepHit = null;
|
||||
var hit_distance_squared = std.math.inf(f32);
|
||||
|
||||
const fdydx: f32 = @as(f32, @floatFromInt(ray_sv.y)) / @as(f32, @floatFromInt(ray_sv.x));
|
||||
@@ -288,20 +395,20 @@ pub fn sweepCastHorizontal(self: *const Chunks, min_sv: vm.Vector3Int, max_sv: v
|
||||
pub fn raycast(self: *const Chunks, origin_sv: vm.Vector3Int, ray_sv: vm.Vector3Int) ?RaycastHit {
|
||||
const end_sv = origin_sv.add(ray_sv);
|
||||
|
||||
std.debug.print("Raycast from ({d}:{X}, {d}:{X}, {d}:{X}) to ({d}:{X}, {d}:{X}, {d}:{X})\n", .{
|
||||
c.subvoxelsToVoxels(.border_up, origin_sv.x),
|
||||
c.subvoxelsToVoxelSubvoxels(origin_sv.x),
|
||||
c.subvoxelsToVoxels(.border_up, origin_sv.y),
|
||||
c.subvoxelsToVoxelSubvoxels(origin_sv.y),
|
||||
c.subvoxelsToVoxels(.border_up, origin_sv.z),
|
||||
c.subvoxelsToVoxelSubvoxels(origin_sv.z),
|
||||
c.subvoxelsToVoxels(.border_up, end_sv.x),
|
||||
c.subvoxelsToVoxelSubvoxels(end_sv.x),
|
||||
c.subvoxelsToVoxels(.border_up, end_sv.y),
|
||||
c.subvoxelsToVoxelSubvoxels(end_sv.y),
|
||||
c.subvoxelsToVoxels(.border_up, end_sv.z),
|
||||
c.subvoxelsToVoxelSubvoxels(end_sv.z),
|
||||
});
|
||||
//std.debug.print("Raycast from ({d}:{X}, {d}:{X}, {d}:{X}) to ({d}:{X}, {d}:{X}, {d}:{X})\n", .{
|
||||
// c.subvoxelsToVoxels(.border_up, origin_sv.x),
|
||||
// c.subvoxelsToVoxelSubvoxels(origin_sv.x),
|
||||
// c.subvoxelsToVoxels(.border_up, origin_sv.y),
|
||||
// c.subvoxelsToVoxelSubvoxels(origin_sv.y),
|
||||
// c.subvoxelsToVoxels(.border_up, origin_sv.z),
|
||||
// c.subvoxelsToVoxelSubvoxels(origin_sv.z),
|
||||
// c.subvoxelsToVoxels(.border_up, end_sv.x),
|
||||
// c.subvoxelsToVoxelSubvoxels(end_sv.x),
|
||||
// c.subvoxelsToVoxels(.border_up, end_sv.y),
|
||||
// c.subvoxelsToVoxelSubvoxels(end_sv.y),
|
||||
// c.subvoxelsToVoxels(.border_up, end_sv.z),
|
||||
// c.subvoxelsToVoxelSubvoxels(end_sv.z),
|
||||
//});
|
||||
|
||||
const ray_positive = vm.Vector3Int.init(
|
||||
@intFromBool(ray_sv.x > 0),
|
||||
@@ -319,37 +426,38 @@ pub fn raycast(self: *const Chunks, origin_sv: vm.Vector3Int, ray_sv: vm.Vector3
|
||||
const end_vx = end_sv.sub(ray_positive).divScalar(c.sv_per_vx);
|
||||
const abs_ray_sv = ray_sv.abs();
|
||||
|
||||
std.debug.print("Start [VX]: ({d}, {d}, {d}) | End [VX]: ({d}, {d}, {d})\n", .{
|
||||
start_vx.x,
|
||||
start_vx.y,
|
||||
start_vx.z,
|
||||
end_vx.x,
|
||||
end_vx.y,
|
||||
end_vx.z,
|
||||
});
|
||||
//std.debug.print("Start [VX]: ({d}, {d}, {d}) | End [VX]: ({d}, {d}, {d})\n", .{
|
||||
// start_vx.x,
|
||||
// start_vx.y,
|
||||
// start_vx.z,
|
||||
// end_vx.x,
|
||||
// end_vx.y,
|
||||
// end_vx.z,
|
||||
//});
|
||||
|
||||
var i_index: usize = undefined;
|
||||
var j_index: usize = undefined;
|
||||
var k_index: usize = undefined;
|
||||
const i_index: usize, const j_index: usize, const k_index: usize = blk: {
|
||||
if (abs_ray_sv.x > abs_ray_sv.y and abs_ray_sv.x > abs_ray_sv.z) {
|
||||
// Main axis: ±X
|
||||
//std.debug.print("Order is (X, Y, Z)\n", .{});
|
||||
break :blk .{ 0, 1, 2 };
|
||||
} else if (abs_ray_sv.y > abs_ray_sv.z) {
|
||||
// Main axis: ±Y
|
||||
//std.debug.print("Order is (Y, Z, X)\n", .{});
|
||||
break :blk .{ 1, 2, 0 };
|
||||
} else if (abs_ray_sv.z > 0) {
|
||||
// Main axis: ±Z
|
||||
//std.debug.print("Order is (Z, X, Y)\n", .{});
|
||||
break :blk .{ 2, 0, 1 };
|
||||
} else {
|
||||
std.debug.assert(abs_ray_sv.x == 0);
|
||||
std.debug.assert(abs_ray_sv.y == 0);
|
||||
std.debug.assert(abs_ray_sv.z == 0);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
if (abs_ray_sv.x > abs_ray_sv.y and abs_ray_sv.x > abs_ray_sv.z) {
|
||||
// Main axis: ±X
|
||||
i_index, j_index, k_index = .{ 0, 1, 2 };
|
||||
std.debug.print("Order is (X, Y, Z)\n", .{});
|
||||
} else if (abs_ray_sv.y > abs_ray_sv.z) {
|
||||
// Main axis: ±Y
|
||||
i_index, j_index, k_index = .{ 1, 2, 0 };
|
||||
std.debug.print("Order is (Y, Z, X)\n", .{});
|
||||
} else if (abs_ray_sv.z > 0) {
|
||||
// Main axis: ±Z
|
||||
i_index, j_index, k_index = .{ 2, 0, 1 };
|
||||
std.debug.print("Order is (Z, X, Y)\n", .{});
|
||||
} else {
|
||||
std.debug.assert(abs_ray_sv.x == 0);
|
||||
std.debug.assert(abs_ray_sv.y == 0);
|
||||
std.debug.assert(abs_ray_sv.z == 0);
|
||||
return null;
|
||||
}
|
||||
var ind_buf: [3]usize = undefined;
|
||||
var current_vx: [3]i32 = undefined;
|
||||
|
||||
const oi = origin_sv.asArray()[i_index];
|
||||
const oj = origin_sv.asArray()[j_index];
|
||||
@@ -359,42 +467,70 @@ pub fn raycast(self: *const Chunks, origin_sv: vm.Vector3Int, ray_sv: vm.Vector3
|
||||
const dj = ray_sv.asArray()[j_index];
|
||||
const dk = ray_sv.asArray()[k_index];
|
||||
|
||||
const rpi = ray_positive.asArray()[i_index];
|
||||
const rpj = ray_positive.asArray()[j_index];
|
||||
const rpk = ray_positive.asArray()[k_index];
|
||||
|
||||
const rni = ray_negative.asArray()[i_index];
|
||||
const rnj = ray_negative.asArray()[j_index];
|
||||
const rnk = ray_negative.asArray()[k_index];
|
||||
|
||||
var i_vx = start_vx.asArray()[i_index];
|
||||
|
||||
var enter_i_sv = oi;
|
||||
var enter_di_sv = enter_i_sv - oi;
|
||||
var enter_jdi_sv = oj * di + enter_di_sv * dj;
|
||||
var enter_kdi_sv = ok * di + enter_di_sv * dk;
|
||||
var enter_jdi_sv = @as(i64, oj) * @as(i64, di) + @as(i64, enter_di_sv) * @as(i64, dj);
|
||||
var enter_kdi_sv = @as(i64, ok) * @as(i64, di) + @as(i64, enter_di_sv) * @as(i64, dk);
|
||||
|
||||
var enter_i_vx = @divFloor(enter_i_sv - ray_positive.asArray()[i_index], c.sv_per_vx);
|
||||
var enter_j_vx = @divFloor(enter_jdi_sv - ray_positive.asArray()[j_index], c.sv_per_vx * di);
|
||||
var enter_k_vx = @divFloor(enter_kdi_sv - ray_positive.asArray()[k_index], c.sv_per_vx * di);
|
||||
var enter_i_vx: i32 = @divFloor(enter_i_sv - rpi, c.sv_per_vx);
|
||||
var enter_j_vx: i32 = @intCast(@divFloor(enter_jdi_sv - rpj, c.sv_per_vx * @as(i64, di)));
|
||||
var enter_k_vx: i32 = @intCast(@divFloor(enter_kdi_sv - rpk, c.sv_per_vx * @as(i64, di)));
|
||||
|
||||
var exit_i_sv = c.voxelsToSubvoxels(i_vx + ray_negative.asArray()[i_index]);
|
||||
current_vx[i_index] = enter_i_vx;
|
||||
current_vx[j_index] = enter_j_vx;
|
||||
current_vx[k_index] = enter_k_vx;
|
||||
|
||||
var exit_i_sv = c.voxelsToSubvoxels(i_vx + rni);
|
||||
var exit_di_sv = exit_i_sv - oi;
|
||||
var exit_jdi_sv = oj * di + exit_di_sv * dj;
|
||||
var exit_kdi_sv = ok * di + exit_di_sv * dk;
|
||||
var exit_jdi_sv = @as(i64, oj) * @as(i64, di) + @as(i64, exit_di_sv) * @as(i64, dj);
|
||||
var exit_kdi_sv = @as(i64, ok) * @as(i64, di) + @as(i64, exit_di_sv) * @as(i64, dk);
|
||||
|
||||
var exit_i_vx = @divFloor(exit_i_sv - ray_positive.asArray()[i_index], c.sv_per_vx);
|
||||
var exit_j_vx = @divFloor(exit_jdi_sv - ray_positive.asArray()[j_index], c.sv_per_vx * di);
|
||||
var exit_k_vx = @divFloor(exit_kdi_sv - ray_positive.asArray()[k_index], c.sv_per_vx * di);
|
||||
var exit_i_vx: i32 = @divFloor(exit_i_sv - rpi, c.sv_per_vx);
|
||||
var exit_j_vx: i32 = @intCast(@divFloor(exit_jdi_sv - rpj, c.sv_per_vx * @as(i64, di)));
|
||||
var exit_k_vx: i32 = @intCast(@divFloor(exit_kdi_sv - rpk, c.sv_per_vx * @as(i64, di)));
|
||||
|
||||
std.debug.print("({d}:{X}, {d:.3}, {d:.3}) → ({d}:{X}, {d:.3}, {d:.3}) | ({d}, {d}, {d}) → ({d}, {d}, {d})\n", .{
|
||||
c.subvoxelsToVoxels(.border_up, enter_i_sv),
|
||||
c.subvoxelsToVoxelSubvoxels(enter_i_sv),
|
||||
@as(f64, @floatFromInt(enter_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
@as(f64, @floatFromInt(enter_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
c.subvoxelsToVoxels(.border_up, exit_i_sv),
|
||||
c.subvoxelsToVoxelSubvoxels(exit_i_sv),
|
||||
@as(f64, @floatFromInt(exit_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
@as(f64, @floatFromInt(exit_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
enter_i_vx,
|
||||
enter_j_vx,
|
||||
enter_k_vx,
|
||||
exit_i_vx,
|
||||
exit_j_vx,
|
||||
exit_k_vx,
|
||||
});
|
||||
var cross_i = vm.unlerpInt(enter_i_sv, exit_i_sv, c.voxelsToSubvoxels(exit_i_vx + rni));
|
||||
var cross_j = vm.unlerpInt64(enter_jdi_sv, exit_jdi_sv, c.voxelsToSubvoxels(exit_j_vx + rnj) * @as(i64, di));
|
||||
var cross_k = vm.unlerpInt64(enter_kdi_sv, exit_kdi_sv, c.voxelsToSubvoxels(exit_k_vx + rnk) * @as(i64, di));
|
||||
|
||||
//std.debug.print("({d}:{X:0>3}, {d:.3}, {d:.3}) → ({d}:{X:0>3}, {d:.3}, {d:.3}) | ({d}, {d}, {d}) → ({d}, {d}, {d}) | × ({d:.3}, {d:.3}, {d:.3})\n", .{
|
||||
// c.subvoxelsToVoxels(.border_up, enter_i_sv),
|
||||
// c.subvoxelsToVoxelSubvoxels(enter_i_sv),
|
||||
// @as(f64, @floatFromInt(enter_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// @as(f64, @floatFromInt(enter_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// c.subvoxelsToVoxels(.border_up, exit_i_sv),
|
||||
// c.subvoxelsToVoxelSubvoxels(exit_i_sv),
|
||||
// @as(f64, @floatFromInt(exit_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// @as(f64, @floatFromInt(exit_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// enter_i_vx,
|
||||
// enter_j_vx,
|
||||
// enter_k_vx,
|
||||
// exit_i_vx,
|
||||
// exit_j_vx,
|
||||
// exit_k_vx,
|
||||
// cross_i,
|
||||
// cross_j,
|
||||
// cross_k,
|
||||
//});
|
||||
|
||||
var cross_indices = order3(i_index, j_index, k_index, cross_i, cross_j, cross_k, &ind_buf);
|
||||
for (cross_indices) |cross_index| {
|
||||
current_vx[cross_index] += ray_sign.asArray()[cross_index];
|
||||
const voxel = vm.Vector3Int.initArray(current_vx);
|
||||
if (self.isSolid(voxel)) {
|
||||
return .{ .voxel = voxel };
|
||||
}
|
||||
}
|
||||
|
||||
while (i_vx != end_vx.asArray()[i_index]) : (i_vx += ray_sign.asArray()[i_index]) {
|
||||
enter_i_sv = exit_i_sv;
|
||||
@@ -406,31 +542,47 @@ pub fn raycast(self: *const Chunks, origin_sv: vm.Vector3Int, ray_sv: vm.Vector3
|
||||
enter_j_vx = exit_j_vx;
|
||||
enter_k_vx = exit_k_vx;
|
||||
|
||||
exit_i_sv = c.voxelsToSubvoxels(i_vx + ray_positive.asArray()[i_index]);
|
||||
exit_i_sv = c.voxelsToSubvoxels(i_vx + rpi);
|
||||
exit_di_sv = exit_i_sv - oi;
|
||||
exit_jdi_sv = oj * di + exit_di_sv * dj;
|
||||
exit_kdi_sv = ok * di + exit_di_sv * dk;
|
||||
exit_jdi_sv = @as(i64, oj) * @as(i64, di) + @as(i64, exit_di_sv) * @as(i64, dj);
|
||||
exit_kdi_sv = @as(i64, ok) * @as(i64, di) + @as(i64, exit_di_sv) * @as(i64, dk);
|
||||
|
||||
exit_i_vx = @divFloor(exit_i_sv - ray_positive.asArray()[i_index], c.sv_per_vx);
|
||||
exit_j_vx = @divFloor(exit_jdi_sv - ray_positive.asArray()[j_index], c.sv_per_vx * di);
|
||||
exit_k_vx = @divFloor(exit_kdi_sv - ray_positive.asArray()[k_index], c.sv_per_vx * di);
|
||||
exit_i_vx = @divFloor(exit_i_sv - rpi, c.sv_per_vx);
|
||||
exit_j_vx = @intCast(@divFloor(exit_jdi_sv - rpj, c.sv_per_vx * @as(i64, di)));
|
||||
exit_k_vx = @intCast(@divFloor(exit_kdi_sv - rpk, c.sv_per_vx * @as(i64, di)));
|
||||
|
||||
std.debug.print("({d}:{X}, {d:.3}, {d:.3}) → ({d}:{X}, {d:.3}, {d:.3}) | ({d}, {d}, {d}) → ({d}, {d}, {d})\n", .{
|
||||
c.subvoxelsToVoxels(.border_up, enter_i_sv),
|
||||
c.subvoxelsToVoxelSubvoxels(enter_i_sv),
|
||||
@as(f64, @floatFromInt(enter_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
@as(f64, @floatFromInt(enter_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
c.subvoxelsToVoxels(.border_up, exit_i_sv),
|
||||
c.subvoxelsToVoxelSubvoxels(exit_i_sv),
|
||||
@as(f64, @floatFromInt(exit_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
@as(f64, @floatFromInt(exit_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
enter_i_vx,
|
||||
enter_j_vx,
|
||||
enter_k_vx,
|
||||
exit_i_vx,
|
||||
exit_j_vx,
|
||||
exit_k_vx,
|
||||
});
|
||||
cross_i = vm.unlerpInt(enter_i_sv, exit_i_sv, c.voxelsToSubvoxels(exit_i_vx + rni));
|
||||
cross_j = vm.unlerpInt64(enter_jdi_sv, exit_jdi_sv, c.voxelsToSubvoxels(exit_j_vx + rnj) * @as(i64, di));
|
||||
cross_k = vm.unlerpInt64(enter_kdi_sv, exit_kdi_sv, c.voxelsToSubvoxels(exit_k_vx + rnk) * @as(i64, di));
|
||||
|
||||
//std.debug.print("({d}:{X:0>3}, {d:.3}, {d:.3}) → ({d}:{X:0>3}, {d:.3}, {d:.3}) | ({d}, {d}, {d}) → ({d}, {d}, {d}) | × ({d:.3}, {d:.3}, {d:.3})\n", .{
|
||||
// c.subvoxelsToVoxels(.border_up, enter_i_sv),
|
||||
// c.subvoxelsToVoxelSubvoxels(enter_i_sv),
|
||||
// @as(f64, @floatFromInt(enter_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// @as(f64, @floatFromInt(enter_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// c.subvoxelsToVoxels(.border_up, exit_i_sv),
|
||||
// c.subvoxelsToVoxelSubvoxels(exit_i_sv),
|
||||
// @as(f64, @floatFromInt(exit_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// @as(f64, @floatFromInt(exit_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// enter_i_vx,
|
||||
// enter_j_vx,
|
||||
// enter_k_vx,
|
||||
// exit_i_vx,
|
||||
// exit_j_vx,
|
||||
// exit_k_vx,
|
||||
// cross_i,
|
||||
// cross_j,
|
||||
// cross_k,
|
||||
//});
|
||||
|
||||
cross_indices = order3(i_index, j_index, k_index, cross_i, cross_j, cross_k, &ind_buf);
|
||||
for (cross_indices) |cross_index| {
|
||||
current_vx[cross_index] += ray_sign.asArray()[cross_index];
|
||||
const voxel = vm.Vector3Int.initArray(current_vx);
|
||||
if (self.isSolid(voxel)) {
|
||||
return .{ .voxel = voxel };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enter_i_sv = exit_i_sv;
|
||||
@@ -444,33 +596,141 @@ pub fn raycast(self: *const Chunks, origin_sv: vm.Vector3Int, ray_sv: vm.Vector3
|
||||
|
||||
exit_i_sv = oi + di;
|
||||
exit_di_sv = exit_i_sv - oi;
|
||||
exit_jdi_sv = oj * di + exit_di_sv * dj;
|
||||
exit_kdi_sv = ok * di + exit_di_sv * dk;
|
||||
exit_jdi_sv = @as(i64, oj) * @as(i64, di) + @as(i64, exit_di_sv) * @as(i64, dj);
|
||||
exit_kdi_sv = @as(i64, ok) * @as(i64, di) + @as(i64, exit_di_sv) * @as(i64, dk);
|
||||
|
||||
exit_i_vx = @divFloor(exit_i_sv - ray_positive.asArray()[i_index], c.sv_per_vx);
|
||||
exit_j_vx = @divFloor(exit_jdi_sv - ray_positive.asArray()[j_index], c.sv_per_vx * di);
|
||||
exit_k_vx = @divFloor(exit_kdi_sv - ray_positive.asArray()[k_index], c.sv_per_vx * di);
|
||||
exit_i_vx = @divFloor(exit_i_sv - rpi, c.sv_per_vx);
|
||||
exit_j_vx = @intCast(@divFloor(exit_jdi_sv - rpj, c.sv_per_vx * @as(i64, di)));
|
||||
exit_k_vx = @intCast(@divFloor(exit_kdi_sv - rpk, c.sv_per_vx * @as(i64, di)));
|
||||
|
||||
std.debug.print("({d}:{X}, {d:.3}, {d:.3}) → ({d}:{X}, {d:.3}, {d:.3}) | ({d}, {d}, {d}) → ({d}, {d}, {d})\n", .{
|
||||
c.subvoxelsToVoxels(.border_up, enter_i_sv),
|
||||
c.subvoxelsToVoxelSubvoxels(enter_i_sv),
|
||||
@as(f64, @floatFromInt(enter_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
@as(f64, @floatFromInt(enter_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
c.subvoxelsToVoxels(.border_up, exit_i_sv),
|
||||
c.subvoxelsToVoxelSubvoxels(exit_i_sv),
|
||||
@as(f64, @floatFromInt(exit_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
@as(f64, @floatFromInt(exit_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
enter_i_vx,
|
||||
enter_j_vx,
|
||||
enter_k_vx,
|
||||
exit_i_vx,
|
||||
exit_j_vx,
|
||||
exit_k_vx,
|
||||
});
|
||||
cross_i = vm.unlerpInt(enter_i_sv, exit_i_sv, c.voxelsToSubvoxels(exit_i_vx + rni));
|
||||
cross_j = vm.unlerpInt64(enter_jdi_sv, exit_jdi_sv, c.voxelsToSubvoxels(exit_j_vx + rnj) * @as(i64, di));
|
||||
cross_k = vm.unlerpInt64(enter_kdi_sv, exit_kdi_sv, c.voxelsToSubvoxels(exit_k_vx + rnk) * @as(i64, di));
|
||||
|
||||
// XXX
|
||||
std.debug.print("\n", .{});
|
||||
//std.debug.print("({d}:{X:0>3}, {d:.3}, {d:.3}) → ({d}:{X:0>3}, {d:.3}, {d:.3}) | ({d}, {d}, {d}) → ({d}, {d}, {d}) | × ({d:.3}, {d:.3}, {d:.3})\n", .{
|
||||
// c.subvoxelsToVoxels(.border_up, enter_i_sv),
|
||||
// c.subvoxelsToVoxelSubvoxels(enter_i_sv),
|
||||
// @as(f64, @floatFromInt(enter_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// @as(f64, @floatFromInt(enter_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// c.subvoxelsToVoxels(.border_up, exit_i_sv),
|
||||
// c.subvoxelsToVoxelSubvoxels(exit_i_sv),
|
||||
// @as(f64, @floatFromInt(exit_jdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// @as(f64, @floatFromInt(exit_kdi_sv)) / @as(f64, @floatFromInt(di * c.sv_per_vx)),
|
||||
// enter_i_vx,
|
||||
// enter_j_vx,
|
||||
// enter_k_vx,
|
||||
// exit_i_vx,
|
||||
// exit_j_vx,
|
||||
// exit_k_vx,
|
||||
// cross_i,
|
||||
// cross_j,
|
||||
// cross_k,
|
||||
//});
|
||||
|
||||
cross_indices = order3(i_index, j_index, k_index, cross_i, cross_j, cross_k, &ind_buf);
|
||||
for (cross_indices) |cross_index| {
|
||||
current_vx[cross_index] += ray_sign.asArray()[cross_index];
|
||||
const voxel = vm.Vector3Int.initArray(current_vx);
|
||||
if (self.isSolid(voxel)) {
|
||||
return .{ .voxel = voxel };
|
||||
}
|
||||
}
|
||||
|
||||
//std.debug.print("\n", .{});
|
||||
|
||||
_ = self;
|
||||
return null;
|
||||
}
|
||||
|
||||
fn order3(i: usize, j: usize, k: usize, cross_i: f32, cross_j: f32, cross_k: f32, buf: *[3]usize) []usize {
|
||||
if (cross_i >= 0 and cross_i < 1) {
|
||||
if (cross_j >= 0 and cross_j < 1) {
|
||||
if (cross_k >= 0 and cross_k < 1) {
|
||||
if (cross_i < cross_j and cross_i < cross_k) {
|
||||
if (cross_j < cross_k) {
|
||||
// Crossed I, J, K
|
||||
buf.* = .{ i, j, k };
|
||||
return buf[0..3];
|
||||
} else {
|
||||
// Crossed I, K, J
|
||||
buf.* = .{ i, k, j };
|
||||
return buf[0..3];
|
||||
}
|
||||
} else if (cross_j < cross_k) {
|
||||
if (cross_i < cross_k) {
|
||||
// Crossed J, I, K
|
||||
buf.* = .{ j, i, k };
|
||||
return buf[0..3];
|
||||
} else {
|
||||
// Crossed J, K, I
|
||||
buf.* = .{ j, k, i };
|
||||
return buf[0..3];
|
||||
}
|
||||
} else {
|
||||
if (cross_i < cross_j) {
|
||||
// Crossed K, I, J
|
||||
buf.* = .{ k, i, j };
|
||||
return buf[0..3];
|
||||
} else {
|
||||
// Crossed K, J, I
|
||||
buf.* = .{ k, j, i };
|
||||
return buf[0..3];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cross_i < cross_j) {
|
||||
// Crossed I, J
|
||||
buf.* = .{ i, j, undefined };
|
||||
return buf[0..2];
|
||||
} else {
|
||||
// Crossed J, I
|
||||
buf.* = .{ j, i, undefined };
|
||||
return buf[0..2];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cross_k >= 0 and cross_k < 1) {
|
||||
if (cross_i < cross_k) {
|
||||
// Crossed I, K
|
||||
buf.* = .{ i, k, undefined };
|
||||
return buf[0..2];
|
||||
} else {
|
||||
// Crossed K, I
|
||||
buf.* = .{ k, i, undefined };
|
||||
return buf[0..2];
|
||||
}
|
||||
} else {
|
||||
// Crossed I
|
||||
buf.* = .{ i, undefined, undefined };
|
||||
return buf[0..1];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cross_j >= 0 and cross_j < 1) {
|
||||
if (cross_k >= 0 and cross_k < 1) {
|
||||
if (cross_j < cross_k) {
|
||||
// Crossed J, K
|
||||
buf.* = .{ j, k, undefined };
|
||||
return buf[0..2];
|
||||
} else {
|
||||
// Crossed K, J
|
||||
buf.* = .{ k, j, undefined };
|
||||
return buf[0..2];
|
||||
}
|
||||
} else {
|
||||
// Crossed J
|
||||
buf.* = .{ j, undefined, undefined };
|
||||
return buf[0..1];
|
||||
}
|
||||
} else {
|
||||
if (cross_k >= 0 and cross_k < 1) {
|
||||
// Crossed K
|
||||
buf.* = .{ k, undefined, undefined };
|
||||
return buf[0..1];
|
||||
} else {
|
||||
// Crossed nothing
|
||||
buf.* = undefined;
|
||||
return buf[0..0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,8 +721,7 @@ pub fn onMouseMove(self: *Game, dx: f32, dy: f32) void {
|
||||
}
|
||||
|
||||
pub fn onMouseDown(self: *Game, button: glfw.MouseButton) void {
|
||||
_ = self;
|
||||
_ = button;
|
||||
self.player.onMouseDown(button, self);
|
||||
}
|
||||
|
||||
pub fn onMouseUp(self: *Game, button: glfw.MouseButton) void {
|
||||
|
||||
@@ -8,6 +8,7 @@ const vm = @import("vecmath");
|
||||
|
||||
const Blocks = @import("assets/Blocks.zig");
|
||||
const Chunks = @import("Chunks.zig");
|
||||
const Game = @import("Game.zig");
|
||||
const Iterator2 = math.Iterator2;
|
||||
|
||||
const AxisState = enum {
|
||||
@@ -175,6 +176,7 @@ mouse_sensitivity: f32 = 0.0003,
|
||||
vertical_fov_deg: f32 = 80,
|
||||
|
||||
movement_state: MovementState,
|
||||
maybe_raycast_hit: ?Chunks.RaycastHit = null,
|
||||
|
||||
pub const camera_height_vx = 1.62;
|
||||
|
||||
@@ -225,19 +227,38 @@ pub fn onMouseMove(self: *Player, dx: f32, dy: f32) void {
|
||||
self.yaw_turns = @mod(self.yaw_turns - dx * self.mouse_sensitivity, 1);
|
||||
}
|
||||
|
||||
pub fn onMouseDown(self: *Player, button: glfw.MouseButton, game: *Game) void {
|
||||
if (self.maybe_raycast_hit) |raycast_hit| {
|
||||
switch (button) {
|
||||
.left => {
|
||||
game.chunks.destroyVoxelAt(
|
||||
raycast_hit.voxel,
|
||||
game.engine,
|
||||
&game.blocks,
|
||||
game.allocator,
|
||||
) catch |err| {
|
||||
std.log.err("Error while destroying voxel {f}: {}", .{ raycast_hit.voxel, err });
|
||||
};
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(self: *Player, dt: f32, chunks: *const Chunks) void {
|
||||
defer self.resetAllButtons();
|
||||
|
||||
//const raycast_origin_sv = self.position_sv
|
||||
// .add(.init(0, 0, @intFromFloat(@round(c.sv_per_vx * camera_height_vx))));
|
||||
//const raycast_ray_sv = vm.Vector3
|
||||
// .init(0, raycast_length_sv, 0)
|
||||
// .rotate(.mulQuaternion(
|
||||
// .initRotation(.XY, self.yaw_turns),
|
||||
// .initRotation(.YZ, self.pitch_turns),
|
||||
// ))
|
||||
// .asVector3Int();
|
||||
//const raycast_hit = chunks.raycast(raycast_origin_sv, raycast_ray_sv);
|
||||
const raycast_origin_sv = self.position_sv
|
||||
.add(.init(0, 0, @intFromFloat(@round(c.sv_per_vx * camera_height_vx))));
|
||||
const raycast_ray_sv = vm.Vector3
|
||||
.init(0, raycast_length_sv, 0)
|
||||
.rotate(.mulQuaternion(
|
||||
.initRotation(.XY, self.yaw_turns),
|
||||
.initRotation(.YZ, self.pitch_turns),
|
||||
))
|
||||
.round()
|
||||
.asInt();
|
||||
self.maybe_raycast_hit = chunks.raycast(raycast_origin_sv, raycast_ray_sv);
|
||||
|
||||
// --- GATHER INPUTS -------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user