Cleanup int collision math, which is still wrong
This commit is contained in:
121
src/Player.zig
121
src/Player.zig
@@ -181,24 +181,24 @@ movement_state: MovementState,
|
||||
|
||||
pub const camera_height_vx = 1.62;
|
||||
|
||||
pub const horizontal_speed_sv = c.sv(11.0);
|
||||
pub const vertical_speed_sv = c.sv(7.49);
|
||||
pub const horizontal_speed_sv = sv(11.0);
|
||||
pub const vertical_speed_sv = sv(7.49);
|
||||
|
||||
pub const min_pitch_rad = -0.5 * std.math.pi;
|
||||
pub const max_pitch_rad = 0.5 * std.math.pi;
|
||||
|
||||
pub const collision_half_width_sv = c.sv(0.4);
|
||||
pub const collision_height_sv = c.sv(1.8);
|
||||
pub const collision_half_width_sv = sv(0.4);
|
||||
pub const collision_height_sv = sv(1.8);
|
||||
|
||||
pub const speed_sv = c.sv(5.612);
|
||||
pub const step_up_sv = c.sv(0.53125);
|
||||
pub const step_down_sv = c.sv(0.53125);
|
||||
pub const jump_velocity_sv = c.sv(6.1237245);
|
||||
pub const gravity_sv = c.sv(15);
|
||||
pub const vertical_velocity_cap_sv = c.sv(30);
|
||||
pub const ground_acceleration_sv = c.sv(56.12);
|
||||
pub const air_acceleration_sv = c.sv(56.12);
|
||||
pub const air_speed_limit_sv = c.sv(0.5612);
|
||||
pub const speed_sv = sv(5.612);
|
||||
pub const step_up_sv = sv(0.53125);
|
||||
pub const step_down_sv = sv(0.53125);
|
||||
pub const jump_velocity_sv = sv(6.1237245);
|
||||
pub const gravity_sv = sv(15);
|
||||
pub const vertical_velocity_cap_sv = sv(30);
|
||||
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 fn init(position_sv: Vector3Int, pitch_rad: f32, yaw_rad: f32) Player {
|
||||
return .{
|
||||
@@ -286,9 +286,10 @@ pub fn update(self: *Player, dt: f32, chunks: *const std.AutoHashMapUnmanaged([3
|
||||
const adjustment = hit.normal_frac
|
||||
.asVector2Int()
|
||||
.mulScalarFrac(hit.projected_distance_sv);
|
||||
std.debug.print("i={} | n={} | d={} | adj={} | disp={}->", .{
|
||||
std.debug.print("i={} | pos={X} | n={} | d={X} | adj={X} | disp={X}->", .{
|
||||
i,
|
||||
hit.normal_frac.vector,
|
||||
position_sv.vector,
|
||||
hit.normal_frac.asVector3Frac().vector,
|
||||
hit.projected_distance_sv,
|
||||
adjustment.vector,
|
||||
horizontal_displacement_sv.vector,
|
||||
@@ -297,7 +298,7 @@ pub fn update(self: *Player, dt: f32, chunks: *const std.AutoHashMapUnmanaged([3
|
||||
horizontal_displacement_sv,
|
||||
adjustment,
|
||||
);
|
||||
std.debug.print("{}\n", .{horizontal_displacement_sv.vector});
|
||||
std.debug.print("{X}\n", .{horizontal_displacement_sv.vector});
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -325,17 +326,17 @@ fn sweepCastDown(origin_sv: Vector3Int, distance_sv: i32, chunks: *const std.Aut
|
||||
const min_origin_sv = origin_sv.add(.init(-collision_half_width_sv, -collision_half_width_sv, 0));
|
||||
const max_origin_sv = origin_sv.add(.init(collision_half_width_sv, collision_half_width_sv, collision_height_sv));
|
||||
|
||||
const min_x_vx = voxelFromSubvoxel(.border_up, min_origin_sv.getX());
|
||||
const min_y_vx = voxelFromSubvoxel(.border_up, min_origin_sv.getY());
|
||||
const max_x_vx = voxelFromSubvoxel(.border_down, max_origin_sv.getX());
|
||||
const max_y_vx = voxelFromSubvoxel(.border_down, max_origin_sv.getY());
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, min_origin_sv.getX());
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, min_origin_sv.getY());
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, max_origin_sv.getX());
|
||||
const max_y_vx = c.subvoxelsToVoxels(.border_down, max_origin_sv.getY());
|
||||
|
||||
const start_z_vx = voxelFromSubvoxel(.next_down, min_origin_sv.getZ());
|
||||
const end_z_vx = voxelFromSubvoxel(.border_up, min_origin_sv.getZ() - distance_sv);
|
||||
const start_z_vx = c.subvoxelsToVoxels(.border_up, min_origin_sv.getZ()) - 1;
|
||||
const end_z_vx = c.subvoxelsToVoxels(.border_up, min_origin_sv.getZ() - distance_sv);
|
||||
|
||||
var z_vx: i32 = start_z_vx;
|
||||
while (z_vx >= end_z_vx) : (z_vx -= 1) {
|
||||
const z_sv = (z_vx + 1) * c.sv_per_vx;
|
||||
const z_sv = c.voxelsToSubvoxels(z_vx + 1);
|
||||
var it = Iterator2(i32).init(.{
|
||||
.min = .{ min_x_vx, min_y_vx },
|
||||
.max = .{ max_x_vx, max_y_vx },
|
||||
@@ -358,17 +359,17 @@ fn sweepCastUp(origin_sv: Vector3Int, distance_sv: i32, chunks: *const std.AutoH
|
||||
const min_origin_sv = origin_sv.add(.init(-collision_half_width_sv, -collision_half_width_sv, 0));
|
||||
const max_origin_sv = origin_sv.add(.init(collision_half_width_sv, collision_half_width_sv, collision_height_sv));
|
||||
|
||||
const min_x_vx = voxelFromSubvoxel(.border_up, min_origin_sv.getX());
|
||||
const min_y_vx = voxelFromSubvoxel(.border_up, min_origin_sv.getY());
|
||||
const max_x_vx = voxelFromSubvoxel(.border_down, max_origin_sv.getX());
|
||||
const max_y_vx = voxelFromSubvoxel(.border_down, max_origin_sv.getY());
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, min_origin_sv.getX());
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, min_origin_sv.getY());
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, max_origin_sv.getX());
|
||||
const max_y_vx = c.subvoxelsToVoxels(.border_down, max_origin_sv.getY());
|
||||
|
||||
const start_z_vx = voxelFromSubvoxel(.next_up, max_origin_sv.getZ());
|
||||
const end_z_vx = voxelFromSubvoxel(.border_up, max_origin_sv.getZ() + distance_sv);
|
||||
const start_z_vx = c.subvoxelsToVoxels(.border_down, max_origin_sv.getZ()) + 1;
|
||||
const end_z_vx = c.subvoxelsToVoxels(.border_down, max_origin_sv.getZ() + distance_sv);
|
||||
|
||||
var z_vx: i32 = start_z_vx;
|
||||
while (z_vx <= end_z_vx) : (z_vx += 1) {
|
||||
const z_sv = z_vx * c.sv_per_vx;
|
||||
const z_sv = c.voxelsToSubvoxels(z_vx);
|
||||
var it = Iterator2(i32).init(.{
|
||||
.min = .{ min_x_vx, min_y_vx },
|
||||
.max = .{ max_x_vx, max_y_vx },
|
||||
@@ -391,8 +392,8 @@ fn sweepCastHorizontal(origin_sv: Vector3Int, ray_sv: Vector2Int, chunks: *const
|
||||
const min_origin_sv = origin_sv.add(.init(-collision_half_width_sv, -collision_half_width_sv, 0));
|
||||
const max_origin_sv = origin_sv.add(.init(collision_half_width_sv, collision_half_width_sv, collision_height_sv));
|
||||
|
||||
const min_z_vx = voxelFromSubvoxel(.border_up, min_origin_sv.getZ());
|
||||
const max_z_vx = voxelFromSubvoxel(.border_down, max_origin_sv.getZ());
|
||||
const min_z_vx = c.subvoxelsToVoxels(.border_up, min_origin_sv.getZ());
|
||||
const max_z_vx = c.subvoxelsToVoxels(.border_down, max_origin_sv.getZ());
|
||||
|
||||
var hit: ?SweepHit = null;
|
||||
var hit_distance_squared = std.math.inf(f32);
|
||||
@@ -406,14 +407,14 @@ fn sweepCastHorizontal(origin_sv: Vector3Int, ray_sv: Vector2Int, chunks: *const
|
||||
const y0_sv = min_origin_sv.getY();
|
||||
const y1_sv = max_origin_sv.getY();
|
||||
|
||||
const start_x_vx = voxelFromSubvoxel(.next_up, x0_sv);
|
||||
const end_x_vx = voxelFromSubvoxel(.border_down, x0_sv + ray_sv.getX());
|
||||
const start_x_vx = c.subvoxelsToVoxels(.border_down, x0_sv) + 1;
|
||||
const end_x_vx = c.subvoxelsToVoxels(.border_down, x0_sv + ray_sv.getX());
|
||||
|
||||
var x_vx: i32 = start_x_vx;
|
||||
px: while (x_vx <= end_x_vx) : (x_vx += 1) {
|
||||
const x_sv = x_vx * c.sv_per_vx;
|
||||
const min_y_vx = voxelFromSubvoxel(.border_up, wideMulDivFloor(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y0_sv);
|
||||
const max_y_vx = voxelFromSubvoxel(.border_down, wideMulDivCeil(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y1_sv);
|
||||
const x_sv = c.voxelsToSubvoxels(x_vx);
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, wideMulDivFloor(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y0_sv);
|
||||
const max_y_vx = c.subvoxelsToVoxels(.border_down, wideMulDivCeil(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y1_sv);
|
||||
var it = Iterator2(i32).init(.{
|
||||
.min = .{ min_y_vx, min_z_vx },
|
||||
.max = .{ max_y_vx, max_z_vx },
|
||||
@@ -444,14 +445,14 @@ fn sweepCastHorizontal(origin_sv: Vector3Int, ray_sv: Vector2Int, chunks: *const
|
||||
const y0_sv = min_origin_sv.getY();
|
||||
const y1_sv = max_origin_sv.getY();
|
||||
|
||||
const start_x_vx = voxelFromSubvoxel(.next_down, x0_sv);
|
||||
const end_x_vx = voxelFromSubvoxel(.border_up, x0_sv + ray_sv.getX());
|
||||
const start_x_vx = c.subvoxelsToVoxels(.border_up, x0_sv) - 1;
|
||||
const end_x_vx = c.subvoxelsToVoxels(.border_up, x0_sv + ray_sv.getX());
|
||||
|
||||
var x_vx: i32 = start_x_vx;
|
||||
nx: while (x_vx >= end_x_vx) : (x_vx -= 1) {
|
||||
const x_sv = (x_vx + 1) * c.sv_per_vx;
|
||||
const min_y_vx = voxelFromSubvoxel(.border_up, wideMulDivFloor(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y0_sv);
|
||||
const max_y_vx = voxelFromSubvoxel(.border_down, wideMulDivCeil(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y1_sv);
|
||||
const x_sv = c.voxelsToSubvoxels(x_vx + 1);
|
||||
const min_y_vx = c.subvoxelsToVoxels(.border_up, wideMulDivFloor(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y0_sv);
|
||||
const max_y_vx = c.subvoxelsToVoxels(.border_down, wideMulDivCeil(x_sv - x0_sv, ray_sv.getY(), ray_sv.getX()) + y1_sv);
|
||||
var it = Iterator2(i32).init(.{
|
||||
.min = .{ min_y_vx, min_z_vx },
|
||||
.max = .{ max_y_vx, max_z_vx },
|
||||
@@ -482,14 +483,14 @@ fn sweepCastHorizontal(origin_sv: Vector3Int, ray_sv: Vector2Int, chunks: *const
|
||||
const x0_sv = min_origin_sv.getX();
|
||||
const x1_sv = max_origin_sv.getX();
|
||||
|
||||
const start_y_vx = voxelFromSubvoxel(.next_up, y0_sv);
|
||||
const end_y_vx = voxelFromSubvoxel(.border_down, y0_sv + ray_sv.getY());
|
||||
const start_y_vx = c.subvoxelsToVoxels(.border_down, y0_sv) + 1;
|
||||
const end_y_vx = c.subvoxelsToVoxels(.border_down, y0_sv + ray_sv.getY());
|
||||
|
||||
var y_vx = start_y_vx;
|
||||
py: while (y_vx <= end_y_vx) : (y_vx += 1) {
|
||||
const y_sv = y_vx * c.sv_per_vx;
|
||||
const min_x_vx = voxelFromSubvoxel(.border_up, wideMulDivFloor(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x0_sv);
|
||||
const max_x_vx = voxelFromSubvoxel(.border_down, wideMulDivCeil(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x1_sv);
|
||||
const y_sv = c.voxelsToSubvoxels(y_vx);
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, wideMulDivFloor(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x0_sv);
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, wideMulDivCeil(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x1_sv);
|
||||
var it = Iterator2(i32).init(.{
|
||||
.min = .{ min_x_vx, min_z_vx },
|
||||
.max = .{ max_x_vx, max_z_vx },
|
||||
@@ -523,14 +524,14 @@ fn sweepCastHorizontal(origin_sv: Vector3Int, ray_sv: Vector2Int, chunks: *const
|
||||
const x0_sv = min_origin_sv.getX();
|
||||
const x1_sv = max_origin_sv.getX();
|
||||
|
||||
const start_y_vx = voxelFromSubvoxel(.next_down, y0_sv);
|
||||
const end_y_vx = voxelFromSubvoxel(.border_up, y0_sv + ray_sv.getY());
|
||||
const start_y_vx = c.subvoxelsToVoxels(.border_up, y0_sv) - 1;
|
||||
const end_y_vx = c.subvoxelsToVoxels(.border_up, y0_sv + ray_sv.getY());
|
||||
|
||||
var y_vx = start_y_vx;
|
||||
ny: while (y_vx >= end_y_vx) : (y_vx -= 1) {
|
||||
const y_sv = (y_vx + 1) * c.sv_per_vx;
|
||||
const min_x_vx = voxelFromSubvoxel(.border_up, wideMulDivFloor(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x0_sv);
|
||||
const max_x_vx = voxelFromSubvoxel(.border_down, wideMulDivCeil(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x1_sv);
|
||||
const y_sv = c.voxelsToSubvoxels(y_vx + 1);
|
||||
const min_x_vx = c.subvoxelsToVoxels(.border_up, wideMulDivFloor(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x0_sv);
|
||||
const max_x_vx = c.subvoxelsToVoxels(.border_down, wideMulDivCeil(y_sv - y0_sv, ray_sv.getX(), ray_sv.getY()) + x1_sv);
|
||||
var it = Iterator2(i32).init(.{
|
||||
.min = .{ min_x_vx, min_z_vx },
|
||||
.max = .{ max_x_vx, max_z_vx },
|
||||
@@ -595,13 +596,6 @@ fn isSolid(chunks: *const std.AutoHashMapUnmanaged([3]i16, Chunk), vx: Vector3In
|
||||
return maybe_id != .air;
|
||||
}
|
||||
|
||||
const RoundingMode = enum {
|
||||
border_down,
|
||||
border_up,
|
||||
next_down,
|
||||
next_up,
|
||||
};
|
||||
|
||||
inline fn wideMulDivFloor(a: i32, mul: i32, div: i32) i32 {
|
||||
return @intCast(@divFloor(@as(i64, a) * @as(i64, mul), div));
|
||||
}
|
||||
@@ -610,11 +604,6 @@ inline fn wideMulDivCeil(a: i32, mul: i32, div: i32) i32 {
|
||||
return @intCast(@divFloor(@as(i64, a) * @as(i64, mul) + @as(i64, div) - 1, div));
|
||||
}
|
||||
|
||||
inline fn voxelFromSubvoxel(comptime rounding_mode: RoundingMode, subvoxel: i32) i32 {
|
||||
return switch (rounding_mode) {
|
||||
.border_down => @divFloor(subvoxel - 1, c.sv_per_vx),
|
||||
.border_up => @divFloor(subvoxel, c.sv_per_vx),
|
||||
.next_down => @divFloor(subvoxel - c.sv_per_vx, c.sv_per_vx),
|
||||
.next_up => @divFloor(subvoxel + (c.sv_per_vx - 1), c.sv_per_vx),
|
||||
};
|
||||
inline fn sv(comptime vx: comptime_float) comptime_int {
|
||||
return @intFromFloat(@round(vx * c.sv_per_vx));
|
||||
}
|
||||
|
||||
@@ -38,6 +38,61 @@ pub const sv_per_vx = 4096;
|
||||
pub const vx_per_ck = 16;
|
||||
pub const sv_per_ck = sv_per_vx * vx_per_ck;
|
||||
|
||||
pub inline fn sv(comptime vx: comptime_float) comptime_int {
|
||||
return @intFromFloat(@round(vx * sv_per_vx));
|
||||
pub const RoundingMode = enum {
|
||||
border_down,
|
||||
border_up,
|
||||
};
|
||||
|
||||
/// SV to VX
|
||||
pub inline fn subvoxelsToVoxels(comptime rounding_mode: RoundingMode, sv: i32) i32 {
|
||||
return switch (rounding_mode) {
|
||||
.border_down => @divFloor(sv, sv_per_vx - 1),
|
||||
.border_up => @divFloor(sv, sv_per_vx),
|
||||
};
|
||||
}
|
||||
|
||||
/// SV to CK
|
||||
pub inline fn subvoxelsToChunks(comptime rounding_mode: RoundingMode, sv: i32) i32 {
|
||||
return switch (rounding_mode) {
|
||||
.border_down => @divFloor(sv, sv_per_ck - 1),
|
||||
.border_up => @divFloor(sv, sv_per_ck),
|
||||
};
|
||||
}
|
||||
|
||||
/// SV to CKSV
|
||||
pub inline fn subvoxelsToChunkSubvoxels(sv: i32) std.math.IntFittingRange(0, sv_per_ck - 1) {
|
||||
return @intCast(@mod(sv, sv_per_ck));
|
||||
}
|
||||
|
||||
/// SV to VXSV
|
||||
pub inline fn subvoxelsToVoxelSubvoxels(sv: i32) std.math.IntFittingRange(0, sv_per_vx - 1) {
|
||||
return @intCast(@mod(sv, sv_per_vx));
|
||||
}
|
||||
|
||||
/// VX to SV
|
||||
pub inline fn voxelsToSubvoxels(vx: i32) i32 {
|
||||
return vx * sv_per_vx;
|
||||
}
|
||||
|
||||
/// VX to CK
|
||||
pub inline fn voxelsToChunks(comptime rounding_mode: RoundingMode, vx: i32) i32 {
|
||||
return switch (rounding_mode) {
|
||||
.border_down => @divFloor(vx, vx_per_ck - 1),
|
||||
.border_up => @divFloor(vx, vx_per_ck),
|
||||
};
|
||||
}
|
||||
|
||||
/// VX to CKVX
|
||||
pub inline fn voxelsToChunkVoxels(vx: i32) std.math.IntFittingRange(0, vx_per_ck) {
|
||||
return @intCast(@mod(vx, vx_per_ck));
|
||||
}
|
||||
|
||||
/// CK to SV
|
||||
pub inline fn chunksToSubvoxels(ck: i32) i32 {
|
||||
return ck * sv_per_ck;
|
||||
}
|
||||
|
||||
/// CK to VX
|
||||
pub inline fn chunksToVoxels(ck: i32) i32 {
|
||||
return ck * vx_per_ck;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user