aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortslil clingman <>2021-10-10 21:01:14 -0400
committertslil clingman <>2021-10-10 21:01:14 -0400
commite014c4a063b05f7e417b4fd593a4f7033b0e4a9f (patch)
tree6a30d92aae015b8bee0eb1110df4bbcfbb1aa209 /src
parentcb15709551921e111d2648f7d6545e4d0e3fdcd6 (diff)
Untested first mock up of polygon intersection in square
Diffstat (limited to 'src')
-rw-r--r--src/level.zig25
-rw-r--r--src/render.zig58
2 files changed, 74 insertions, 9 deletions
diff --git a/src/level.zig b/src/level.zig
index a5d7330..dce2a14 100644
--- a/src/level.zig
+++ b/src/level.zig
@@ -18,26 +18,33 @@
const std = @import("std");
pub const Object = struct {
- height : f32,
- width : f32,
- texture : u8,
- pos_x : f32,
- pos_y : f32,
- pos_z : f32 = 0,
+ height: f32,
+ width: f32,
+ texture: u8,
+ pos_x: f32,
+ pos_y: f32,
+ pos_z: f32 = 0,
};
pub const Cell = struct {
floor_height: f32 = 0,
- ceiling_height : f32 = DEFAULT_HEIGHT,
+ ceiling_height: f32 = DEFAULT_HEIGHT,
draw_down: bool = false,
lower_texture: u8 = 0,
upper_texture: u8 = 0,
floor_texture: u8 = 0,
ceiling_texture: u8 = 2,
- pub const floor = Cell{ };
+ vertices: [][2]f32 = [][2]f32{
+ .{ 0, 0 },
+ .{ 1, 0 },
+ .{ 1, 1 },
+ .{ 0, 1 },
+ },
- pub const DEFAULT_HEIGHT : f32 = 4;
+ pub const floor = Cell{};
+
+ pub const DEFAULT_HEIGHT: f32 = 4;
};
pub const Map = struct {
diff --git a/src/render.zig b/src/render.zig
index 12af775..38cd26d 100644
--- a/src/render.zig
+++ b/src/render.zig
@@ -69,6 +69,61 @@ fn fasterColourBlend(onto: Colour, from: Colour) Colour {
};
}
+fn hitDistLocalCoords(
+ ray0: [2]f32,
+ ray1: [2]f32,
+ vertices: [][2]f32,
+) ?f32 {
+ const rdy = ray1[1] - ray0[1];
+ const rdx = ray1[0] - ray0[0];
+
+ var vp = vertices[0];
+ var crossp: f32 = rdy * (vp[0] - ray0[0]) - rdx * (vp[1] - ray0[1]);
+
+ // TODO: there is currently a bug in the logic, if vp->v is parallel to
+ // ray0->ray1, then we'll return the distance ray0->vp (even if v is
+ // closer). This is incorrect.
+
+ if (crossp == 0) {
+ // hit a vertex exactly
+ const dx = vp[0] - ray0[0];
+ const dy = vp[1] - ray0[1];
+ return math.sqrt(dx * dx + dy * dy);
+ }
+
+ var i: usize = 1;
+ var v = vertices[i];
+ var cross: f32 = rdy * (v[0] - ray0[0]) - rdx * (v[1] - ray0[1]);
+ while (i < vertices.len) : ({
+ i += 1;
+ vp = v;
+ v = vertices[i];
+ crossp = cross;
+ cross = rdy * (v[0] - ray0[0]) - rdx * (v[1] - ray0[1]);
+ }) {
+ if (cross == 0) {
+ const dx = v[0] - ray0[0];
+ const dy = v[1] - ray0[1];
+ return math.sqrt(dx * dx + dy * dy);
+ } else {
+ if (crossp * cross < 0) {
+ // If the segment from ray0->ray1 has vp and v on opposite sides
+ // of it then it intersects the line segment vp->v. This is not
+ // true in general, but all coordinates are constrained to be in
+ // the unit square so it is true here. With that we compute the
+ // distance to the intersection from ray0
+ const vdx = v[0] - vp[0];
+ const vdy = v[1] - vp[1];
+
+ const dx = rdx * cross; // this should really be negative, but we square it...
+ const dy = rdy * (vdx * (ray0[1] - v[1]) - vdy * (ray0[0] - v[0]));
+ return math.sqrt(dx * dx + dy * dy) / (rdx * vdy - vdx * rdy);
+ }
+ }
+ }
+ return null;
+}
+
pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
const FOV: f32 = std.math.pi / 3.0;
const PlanePixels = PlaneWidth * PlaneHeight;
@@ -294,6 +349,9 @@ pub fn Renderer(PlaneWidth: f32, PlaneHeight: f32) type {
// Are we drawing vertical surfaces?
if (cell.floor_height > 0 or cell.draw_down) {
+ if (hitDistLocalCoords(ray0, ray1, cell.vertices)) |local_distance| {
+
+ }
// project the top of the bottom and the bottom of the top
top_of_floor = PlaneHeight / 2 + PlaneDist * (cell.floor_height - pheight) / distance;
bottom_of_ceiling = PlaneHeight / 2 + PlaneDist * (cell.ceiling_height - pheight) / distance;