diff --git a/in_one_weekend/src/camera.zig b/in_one_weekend/src/camera.zig index a489ceb..a7fb8d4 100644 --- a/in_one_weekend/src/camera.zig +++ b/in_one_weekend/src/camera.zig @@ -1,23 +1,41 @@ +const std = @import("std"); +const math = std.math; + const Point3 = @import("vec3.zig").Point3; const Vec3 = @import("vec3.zig").Vec3; const Ray = @import("ray.zig").Ray; +fn degreesToRadians(degrees: f32) f32 { + return degrees * math.pi / 180.0; +} + pub const Camera = struct { origin: Point3, lowerLeftCorner: Point3, horizontal: Vec3, vertical: Vec3, - pub fn init() Camera { - const aspectRatio = 16.0 / 9.0; - const viewportHeight = 2.0; - const viewportWidth = aspectRatio * viewportHeight; - const focalLength = 1.0; + pub fn init( + lookFrom: Point3, + lookAt: Point3, + vup: Vec3, + vfov: f32, + aspectRatio: f32, + ) Camera { + const theta = degreesToRadians(vfov); + const h = math.tan(theta / 2); - const origin = Vec3{}; - const horizontal = Vec3{ .x = viewportWidth }; - const vertical = Vec3{ .y = viewportHeight }; - const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(Vec3{ .z = focalLength }); + const viewportHeight = 2.0 * h; + const viewportWidth = aspectRatio * viewportHeight; + + const w = lookFrom.sub(lookAt).unit(); + const u = vup.cross(w).unit(); + const v = w.cross(u); + + const origin = lookFrom; + const horizontal = u.mul_s(viewportWidth); + const vertical = v.mul_s(viewportHeight); + const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(w); return Camera { .origin = origin, @@ -27,10 +45,10 @@ pub const Camera = struct { }; } - pub fn getRay(self: Camera, u: f32, v: f32) Ray { + pub fn getRay(self: Camera, s: f32, t: f32) Ray { return Ray{ .origin = self.origin, - .direction = self.lowerLeftCorner.add(self.horizontal.mul_s(u)).add(self.vertical.mul_s(v)).sub(self.origin), + .direction = self.lowerLeftCorner.add(self.horizontal.mul_s(s)).add(self.vertical.mul_s(t)).sub(self.origin), }; } }; \ No newline at end of file diff --git a/in_one_weekend/src/main.zig b/in_one_weekend/src/main.zig index c9378b1..ee265df 100644 --- a/in_one_weekend/src/main.zig +++ b/in_one_weekend/src/main.zig @@ -117,12 +117,19 @@ pub fn main() anyerror!void { Sphere{ .center = Point3{ .x = 0, .y = -100.5, .z = -1 }, .radius = 100, .material = materialGround }, Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter }, Sphere{ .center = Point3{ .x = -1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialLeft }, + Sphere{ .center = Point3{ .x = -1, .y = 0, .z = -1 }, .radius = -0.45, .material = materialLeft }, Sphere{ .center = Point3{ .x = 1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialRight }, }; const world = World{ .spheres = spheres[0..spheres.len] }; // Camera - const camera = Camera.init(); + const camera = Camera.init( + Point3{ .x = -2, .y = 2, .z = 1 }, + Point3{ .x = 0, .y = 0, .z = -1 }, + Vec3{ .x = 0, .y = 1, .z = 0 }, + 20.0, + aspectRatio + ); const window = sdl.c.SDL_CreateWindow( "Raytracing in One Weekend",