From cf1eb8fc551f5f3ee3bc0054fc236ff7d201f44a Mon Sep 17 00:00:00 2001 From: tslil clingman <> Date: Mon, 6 Sep 2021 20:22:58 -0400 Subject: Only attempt to render cells with h > 0 --- src/raycast.zig | 96 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/raycast.zig b/src/raycast.zig index e1bfce0..2a9b0a1 100644 --- a/src/raycast.zig +++ b/src/raycast.zig @@ -38,6 +38,13 @@ pub const RenderSliceFunction: type = fn ( ) void; pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type { + const FOV: f32 = std.math.pi / 3.0; + const PlanePixels = PlaneWidth * PlaneHeight; + // given the desired width of the image, how far away must + // the projection plane be from the camera? + const FOV_SCALE = 2 * std.math.tan(FOV / 2); + const PlaneDist = PlaneWidth / FOV_SCALE; + return struct { pos_x: f32, pos_y: f32, @@ -46,17 +53,9 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type { vel_y: f32 = 0, acc_x: f32 = 0, acc_y: f32 = 0, - fov: f32 = std.math.pi / 3.0, height: f32 = 1.8 / 2.5, // TODO z_buffer: std.BoundedArray(f32, PlanePixels), - const FOV: f32 = std.math.pi / 3.0; - const PlanePixels = PlaneWidth * PlaneHeight; - // given the desired width of the image, how far away must - // the projection plane be from the camera? - const FOV_SCALE = 2 * std.math.tan(FOV / 2); - const PlaneDist = PlaneWidth / FOV_SCALE; - // standing still at the given location, looking in direction ang, pub fn new(pos_x: f32, pos_y: f32, ang: f32) !@This() { const infs = [_]f32{std.math.inf(f32)} ** PlanePixels; @@ -269,46 +268,49 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type { ipos_y += step_y; } }) { - var cell = map.lookup(ipos_x, ipos_y); - - // project the top of the wall - var top = PlaneHeight / 2 + PlaneDist * (cell.height - self.height) / distance; - - // We have a wall to draw if it protrudes above what we have so far drawn - if (top > highest_point) { - - // did we extend beyond the top of the plane? - if (top > PlaneHeight) { - still_drawing = false; - } - - // compute the height of this wall - const total_length = PlaneDist * cell.height / distance; - - // as well as the fraction we'll be drawing - const draw_length = top - highest_point; - const draw_frac = std.math.clamp(draw_length / total_length, 0, 1); - - // we need the raw Euclidean distance to calculate the - // fractional part of the relevant coordinate for texture - // mapping of the walls - const hit_coordinate = if (horizontal_hit) distance * cosra + self.pos_x else distance * sinra + self.pos_y; - var texfrac = std.math.modf(hit_coordinate).fpart; - // we also want to be sure that we're consistently orienting - // textures, in this case clockwise - if ((horizontal_hit and sinra < 0) or (!horizontal_hit and cosra > 0)) texfrac = 1 - texfrac; - - // draw the wall - renderSlice(window, walls_sprite, col, top, total_length, draw_frac, texfrac, cell.wall_texture); - - // record that there's a wall here in the z_buffer - var y = @floatToInt(i32, std.math.min(top, PlaneHeight - 1)); - while (y > @floatToInt(i32, highest_point)) : (y -= 1) { - const index = @intCast(usize, col * @floatToInt(i32, PlaneHeight) + y); - self.z_buffer.set(index, distance); + const cell = map.lookup(ipos_x, ipos_y); + + // Is there a wall? + if (cell.height > 0) { + // project the top of the wall + var top = PlaneHeight / 2 + PlaneDist * (cell.height - self.height) / distance; + // We have a wall to draw if it protrudes above what we have so far drawn + if (top > highest_point) { + + // did we extend beyond the top of the plane? + if (top > PlaneHeight) { + still_drawing = false; + } + + // compute the height of this wall + const total_length = PlaneDist * cell.height / distance; + + // as well as the fraction we'll be drawing + const draw_length = top - highest_point; + const draw_frac = std.math.clamp(draw_length / total_length, 0, 1); + + // we need the distance to calculate the fractional + // part of the relevant coordinate for texture + // mapping of the walls + const hit_coordinate = if (horizontal_hit) distance * cosra + self.pos_x else distance * sinra + self.pos_y; + var texfrac = std.math.modf(hit_coordinate).fpart; + + // we also want to be sure that we're consistently orienting + // textures, in this case clockwise + if ((horizontal_hit and sinra < 0) or (!horizontal_hit and cosra > 0)) texfrac = 1 - texfrac; + + // draw the wall + renderSlice(window, walls_sprite, col, top, total_length, draw_frac, texfrac, cell.wall_texture); + + // record that there's a wall here in the z_buffer + var y = @floatToInt(i32, std.math.min(top, PlaneHeight - 1)); + while (y > @floatToInt(i32, highest_point)) : (y -= 1) { + const index = @intCast(usize, col * @floatToInt(i32, PlaneHeight) + y); + self.z_buffer.set(index, distance); + } + + highest_point = top; } - - highest_point = top; } } } -- cgit v1.3.1