Attempts at raycast
This commit is contained in:
@@ -8,6 +8,45 @@ layout(set = 0, binding = 2, rgba16f) uniform writeonly restrict imageCube _Cube
|
||||
const float INV_PI = 0.31830987;
|
||||
const float HALF_INV_PI = 0.15915494;
|
||||
|
||||
const mat3x3 MATRIX_2D_TO_CUBE[6] = mat3x3[](
|
||||
// Positive X
|
||||
mat3x3(
|
||||
0, 0, -1,
|
||||
0, -1, 0,
|
||||
1, 0, 0
|
||||
),
|
||||
// Negative X
|
||||
mat3x3(
|
||||
0, 0, 1,
|
||||
0, -1, 0,
|
||||
-1, 0, 0
|
||||
),
|
||||
// Positive Y
|
||||
mat3x3(
|
||||
1, 0, 0,
|
||||
0, 0, 1,
|
||||
0, 1, 0
|
||||
),
|
||||
// Negative Y
|
||||
mat3x3(
|
||||
1, 0, 0,
|
||||
0, 0, -1,
|
||||
0, -1, 0
|
||||
),
|
||||
// Positive Z
|
||||
mat3x3(
|
||||
1, 0, 0,
|
||||
0, -1, 0,
|
||||
0, 0, 1
|
||||
),
|
||||
// Negative Z
|
||||
mat3x3(
|
||||
-1, 0, 0,
|
||||
0, -1, 0,
|
||||
0, 0, -1
|
||||
)
|
||||
);
|
||||
|
||||
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
void main() {
|
||||
vec2 size = vec2(imageSize(_CubemapImage).xy);
|
||||
@@ -16,27 +55,7 @@ void main() {
|
||||
|
||||
texCoord = texCoord * vec2(2.0) - vec2(1.0); // Map to range [-1, 1]
|
||||
|
||||
vec3 cubeCoord;
|
||||
if (layerIndex == 0) {
|
||||
// Positive X
|
||||
cubeCoord = vec3(1, -texCoord.y, -texCoord.x);
|
||||
} else if (layerIndex == 1) {
|
||||
// Negative X
|
||||
cubeCoord = vec3(-1, -texCoord.y, texCoord.x);
|
||||
} else if (layerIndex == 2) {
|
||||
// Positive Y
|
||||
cubeCoord = vec3(texCoord.x, 1, texCoord.y);
|
||||
} else if (layerIndex == 3) {
|
||||
// Negative Y
|
||||
cubeCoord = vec3(texCoord.x, -1, -texCoord.y);
|
||||
} else if (layerIndex == 4) {
|
||||
// Positive Z
|
||||
cubeCoord = vec3(texCoord.x, -texCoord.y, 1);
|
||||
} else if (layerIndex == 5) {
|
||||
// Negative Z
|
||||
cubeCoord = vec3(-texCoord.x, -texCoord.y, -1);
|
||||
}
|
||||
|
||||
vec3 cubeCoord = MATRIX_2D_TO_CUBE[layerIndex] * vec3(texCoord, 1.0);
|
||||
vec3 cubeDir = normalize(cubeCoord);
|
||||
|
||||
float theta = atan(cubeDir.y, cubeDir.x);
|
||||
@@ -45,5 +64,5 @@ void main() {
|
||||
vec2 equirectCoord = vec2(theta * HALF_INV_PI, phi * INV_PI) + vec2(0.5);
|
||||
|
||||
vec4 irradiance = texture(sampler2D(_EquirectangularTexture, _EquirectangularSampler), equirectCoord);
|
||||
imageStore(_CubemapImage, ivec3(ivec2(gl_GlobalInvocationID.xy), layerIndex), irradiance);
|
||||
imageStore(_CubemapImage, ivec3(gl_GlobalInvocationID.xyz), irradiance);
|
||||
}
|
||||
|
||||
195
src/Chunks.zig
195
src/Chunks.zig
@@ -14,7 +14,7 @@ const Vector3Int = math.Vector3Int;
|
||||
|
||||
chunks: std.AutoHashMapUnmanaged([3]i16, Chunk),
|
||||
|
||||
const SweepHit = struct {
|
||||
const RaycastHit = struct {
|
||||
normal_frac: Vector3Int,
|
||||
projected_distance_sv: i32,
|
||||
};
|
||||
@@ -54,7 +54,7 @@ pub fn isSolid(self: *const Chunks, vx: Vector3Int) bool {
|
||||
return maybe_id != .air;
|
||||
}
|
||||
|
||||
pub fn sweepCastDown(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int, distance_sv: i32) ?SweepHit {
|
||||
pub fn sweepCastDown(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int, distance_sv: i32) ?RaycastHit {
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, min_sv.getX());
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, min_sv.getY());
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, max_sv.getX());
|
||||
@@ -84,7 +84,7 @@ pub fn sweepCastDown(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn sweepCastUp(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int, distance_sv: i32) ?SweepHit {
|
||||
pub fn sweepCastUp(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int, distance_sv: i32) ?RaycastHit {
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, min_sv.getX());
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, min_sv.getY());
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, max_sv.getX());
|
||||
@@ -114,11 +114,11 @@ pub fn sweepCastUp(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int,
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn sweepCastHorizontal(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int, ray_sv: Vector2Int) ?SweepHit {
|
||||
pub fn sweepCastHorizontal(self: *const Chunks, min_sv: Vector3Int, max_sv: Vector3Int, ray_sv: Vector2Int) ?RaycastHit {
|
||||
const min_z_vx = c.subvoxelsToVoxels(.border_up, min_sv.getZ());
|
||||
const max_z_vx = c.subvoxelsToVoxels(.border_down, max_sv.getZ());
|
||||
|
||||
var hit: ?SweepHit = null;
|
||||
var hit: ?RaycastHit = null;
|
||||
var hit_distance_squared = std.math.inf(f32);
|
||||
|
||||
const fdydx: f32 = @as(f32, @floatFromInt(ray_sv.getY())) / @as(f32, @floatFromInt(ray_sv.getX()));
|
||||
@@ -284,3 +284,188 @@ pub fn sweepCastHorizontal(self: *const Chunks, min_sv: Vector3Int, max_sv: Vect
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
pub fn raycast(self: *const Chunks, origin_sv: Vector3Int, ray_sv: 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.getX()),
|
||||
c.subvoxelsToVoxelSubvoxels(origin_sv.getX()),
|
||||
c.subvoxelsToVoxels(.border_up, origin_sv.getY()),
|
||||
c.subvoxelsToVoxelSubvoxels(origin_sv.getY()),
|
||||
c.subvoxelsToVoxels(.border_up, origin_sv.getZ()),
|
||||
c.subvoxelsToVoxelSubvoxels(origin_sv.getZ()),
|
||||
c.subvoxelsToVoxels(.border_up, end_sv.getX()),
|
||||
c.subvoxelsToVoxelSubvoxels(end_sv.getX()),
|
||||
c.subvoxelsToVoxels(.border_up, end_sv.getY()),
|
||||
c.subvoxelsToVoxelSubvoxels(end_sv.getY()),
|
||||
c.subvoxelsToVoxels(.border_up, end_sv.getZ()),
|
||||
c.subvoxelsToVoxelSubvoxels(end_sv.getZ()),
|
||||
});
|
||||
|
||||
const zero = Vector3Int.zero.vector;
|
||||
const one = Vector3Int.one.vector;
|
||||
|
||||
const ray_positive: Vector3Int = .{ .vector = @select(i32, ray_sv.vector > zero, one, zero) };
|
||||
const ray_negative: Vector3Int = .{ .vector = @select(i32, ray_sv.vector < zero, one, zero) };
|
||||
const ray_sign: Vector3Int = .sub(ray_positive, ray_negative);
|
||||
|
||||
const start_vx = origin_sv.sub(ray_positive).divScalar(c.sv_per_vx).add(ray_sign);
|
||||
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.getX(),
|
||||
start_vx.getY(),
|
||||
start_vx.getZ(),
|
||||
end_vx.getX(),
|
||||
end_vx.getY(),
|
||||
end_vx.getZ(),
|
||||
});
|
||||
|
||||
var i_index: usize = undefined;
|
||||
var j_index: usize = undefined;
|
||||
var k_index: usize = undefined;
|
||||
|
||||
if (abs_ray_sv.getX() > abs_ray_sv.getY() and abs_ray_sv.getX() > abs_ray_sv.getZ()) {
|
||||
// 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.getY() > abs_ray_sv.getZ()) {
|
||||
// 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.getZ() > 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.getX() == 0);
|
||||
std.debug.assert(abs_ray_sv.getY() == 0);
|
||||
std.debug.assert(abs_ray_sv.getZ() == 0);
|
||||
return null;
|
||||
}
|
||||
|
||||
const oi = origin_sv.vector[i_index];
|
||||
const oj = origin_sv.vector[j_index];
|
||||
const ok = origin_sv.vector[k_index];
|
||||
|
||||
const di = ray_sv.vector[i_index];
|
||||
const dj = ray_sv.vector[j_index];
|
||||
const dk = ray_sv.vector[k_index];
|
||||
|
||||
var i_vx = start_vx.vector[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_i_vx = @divFloor(enter_i_sv - ray_positive.vector[i_index], c.sv_per_vx);
|
||||
var enter_j_vx = @divFloor(enter_jdi_sv - ray_positive.vector[j_index], c.sv_per_vx * di);
|
||||
var enter_k_vx = @divFloor(enter_kdi_sv - ray_positive.vector[k_index], c.sv_per_vx * di);
|
||||
|
||||
var exit_i_sv = c.voxelsToSubvoxels(i_vx + ray_negative.vector[i_index]);
|
||||
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_i_vx = @divFloor(exit_i_sv - ray_positive.vector[i_index], c.sv_per_vx);
|
||||
var exit_j_vx = @divFloor(exit_jdi_sv - ray_positive.vector[j_index], c.sv_per_vx * di);
|
||||
var exit_k_vx = @divFloor(exit_kdi_sv - ray_positive.vector[k_index], c.sv_per_vx * 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,
|
||||
});
|
||||
|
||||
while (i_vx != end_vx.vector[i_index]) : (i_vx += ray_sign.vector[i_index]) {
|
||||
enter_i_sv = exit_i_sv;
|
||||
enter_di_sv = exit_di_sv;
|
||||
enter_jdi_sv = exit_jdi_sv;
|
||||
enter_kdi_sv = exit_kdi_sv;
|
||||
|
||||
enter_i_vx = exit_i_vx;
|
||||
enter_j_vx = exit_j_vx;
|
||||
enter_k_vx = exit_k_vx;
|
||||
|
||||
exit_i_sv = c.voxelsToSubvoxels(i_vx + ray_positive.vector[i_index]);
|
||||
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_i_vx = @divFloor(exit_i_sv - ray_positive.vector[i_index], c.sv_per_vx);
|
||||
exit_j_vx = @divFloor(exit_jdi_sv - ray_positive.vector[j_index], c.sv_per_vx * di);
|
||||
exit_k_vx = @divFloor(exit_kdi_sv - ray_positive.vector[k_index], c.sv_per_vx * 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,
|
||||
});
|
||||
}
|
||||
|
||||
enter_i_sv = exit_i_sv;
|
||||
enter_di_sv = exit_di_sv;
|
||||
enter_jdi_sv = exit_jdi_sv;
|
||||
enter_kdi_sv = exit_kdi_sv;
|
||||
|
||||
enter_i_vx = exit_i_vx;
|
||||
enter_j_vx = exit_j_vx;
|
||||
enter_k_vx = exit_k_vx;
|
||||
|
||||
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_i_vx = @divFloor(exit_i_sv - ray_positive.vector[i_index], c.sv_per_vx);
|
||||
exit_j_vx = @divFloor(exit_jdi_sv - ray_positive.vector[j_index], c.sv_per_vx * di);
|
||||
exit_k_vx = @divFloor(exit_kdi_sv - ray_positive.vector[k_index], c.sv_per_vx * 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,
|
||||
});
|
||||
|
||||
// XXX
|
||||
std.debug.print("\n", .{});
|
||||
|
||||
_ = self;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ const math = @import("math.zig");
|
||||
const Blocks = @import("assets/Blocks.zig");
|
||||
const Chunks = @import("Chunks.zig");
|
||||
const Iterator2 = math.Iterator2;
|
||||
const Quaternion = math.Quaternion;
|
||||
const Vector2 = math.Vector2;
|
||||
const Vector3 = math.Vector3;
|
||||
const Vector2Int = math.Vector2Int;
|
||||
@@ -200,6 +201,8 @@ pub const ground_acceleration_sv = sv(56.12);
|
||||
pub const air_acceleration_sv = sv(56.12);
|
||||
pub const air_speed_limit_sv = sv(0.5612);
|
||||
|
||||
pub const raycast_length_sv = sv(5.0);
|
||||
|
||||
pub fn init(position_sv: Vector3Int, pitch_rad: f32, yaw_rad: f32) Player {
|
||||
return .{
|
||||
.position_sv = position_sv,
|
||||
@@ -229,6 +232,17 @@ pub fn onMouseMove(self: *Player, dx: f32, dy: f32) void {
|
||||
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 = Vector3
|
||||
// .init(0, raycast_length_sv, 0)
|
||||
// .rotate(.mulQuaternion(
|
||||
// .initRotationXY(self.yaw_rad),
|
||||
// .initRotationYZ(self.pitch_rad),
|
||||
// ))
|
||||
// .asVector3Int();
|
||||
//const raycast_hit = chunks.raycast(raycast_origin_sv, raycast_ray_sv);
|
||||
|
||||
// --- GATHER INPUTS -------------------------------------------------------
|
||||
|
||||
const horizontal_input_vector_frac = blk: {
|
||||
|
||||
Reference in New Issue
Block a user