aboutsummaryrefslogtreecommitdiff
path: root/lib/camera.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/camera.rb')
-rw-r--r--lib/camera.rb31
1 files changed, 21 insertions, 10 deletions
diff --git a/lib/camera.rb b/lib/camera.rb
index 6a3b190..365ebcd 100644
--- a/lib/camera.rb
+++ b/lib/camera.rb
@@ -1,23 +1,34 @@
class Camera
- def initialize(width = 100, aspect = 1.0, aliasing = 10, depth = 10)
+ def initialize(width = 100, aspect = 1.0,
+ aliasing: 10, depth: 10, vfov: 90.0,
+ lookfrom: Point.new(0, 0, 0),
+ lookat: Point.new(0, 0, -1),
+ vup: Vec3.new(0, 1, 0))
@width = width
- @aspect = aspect
@aliasing = aliasing
@depth = depth
# Height
- @height = (@width / @aspect).to_i
+ @height = (@width / aspect).to_i
@height = @height < 1 ? 1 : @height
# Camera
- c_focallength = 1.0
- @c_centre = Point.new(0,0,0)
+ @c_centre = lookfrom
+ c_focallength = (lookfrom - lookat).mag
# Viewport
- @v_height = 2.0
- @v_width = @v_height * @width.to_f / @height
- v_u = Vec3.new(@v_width, 0, 0)
- v_v = Vec3.new(0, -@v_height, 0)
+ theta = vfov * Maths::PI / 180
+ h = Maths.tan(theta / 2)
+ v_height = 2.0 * h * c_focallength
+ v_width = v_height * @width.to_f / @height
+
+ # Camera basis vectors
+ w = (lookfrom - lookat).unit
+ u = vup.cross(w).unit
+ v = w.cross(u)
+
+ v_u = u * v_width
+ v_v = -v * v_height
# Pixel deltas
@pd_u = v_u / @width
@@ -25,7 +36,7 @@ class Camera
# Upper left pixel
v_upperleft = @c_centre - v_u / 2 - v_v / 2 -
- Vec3.new(0, 0, c_focallength)
+ w * c_focallength
@p00_loc = v_upperleft + (@pd_u + @pd_v) / 2
end