Class: Quake::Camera
- Inherits:
-
Object
- Object
- Quake::Camera
- Defined in:
- lib/quake/camera.rb
Constant Summary collapse
- SPEED =
units per second (Quake run speed)
320.0- SENSITIVITY =
degrees per pixel
0.15- MAX_MOUSE_DELTA =
clamp insane deltas (e.g. first frame warp)
50
Instance Attribute Summary collapse
-
#far ⇒ Object
readonly
Returns the value of attribute far.
-
#fov ⇒ Object
readonly
Returns the value of attribute fov.
-
#near ⇒ Object
readonly
Returns the value of attribute near.
-
#pitch ⇒ Object
Returns the value of attribute pitch.
-
#position ⇒ Object
Returns the value of attribute position.
-
#roll ⇒ Object
Returns the value of attribute roll.
-
#yaw ⇒ Object
Returns the value of attribute yaw.
Instance Method Summary collapse
- #apply_gl ⇒ Object
- #apply_projection_gl(aspect) ⇒ Object
- #forward ⇒ Object
-
#fov_x(aspect) ⇒ Object
Actual horizontal FOV for a given aspect (follows from fov_y).
-
#fov_y(_aspect = nil) ⇒ Object
Quake's fov cvar is the horizontal FOV on a 4:3 screen.
-
#frustum_planes(aspect) ⇒ Object
R_SetFrustum: 4 view-frustum planes as [normal, dist] pairs, where a point is inside when normal.dot(point) - dist >= 0.
-
#initialize(position: Math::Vec3::ORIGIN, yaw: 0.0, pitch: 0.0, fov: 90.0, near: 4.0, far: 6144.0) ⇒ Camera
constructor
A new instance of Camera.
- #move_forward(dt) ⇒ Object
- #move_right(dt) ⇒ Object
- #move_up(dt) ⇒ Object
- #right ⇒ Object
- #rotate(dx, dy) ⇒ Object
- #up ⇒ Object
Constructor Details
#initialize(position: Math::Vec3::ORIGIN, yaw: 0.0, pitch: 0.0, fov: 90.0, near: 4.0, far: 6144.0) ⇒ Camera
Returns a new instance of Camera.
15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/quake/camera.rb', line 15 def initialize(position: Math::Vec3::ORIGIN, yaw: 0.0, pitch: 0.0, fov: 90.0, near: 4.0, far: 6144.0) @position = position @yaw = yaw @pitch = pitch @roll = 0.0 @fov = fov @near = near @far = far @ignore_mouse = 2 # skip first N motion events (SDL warp artifacts) end |
Instance Attribute Details
#far ⇒ Object (readonly)
Returns the value of attribute far.
9 10 11 |
# File 'lib/quake/camera.rb', line 9 def far @far end |
#fov ⇒ Object (readonly)
Returns the value of attribute fov.
9 10 11 |
# File 'lib/quake/camera.rb', line 9 def fov @fov end |
#near ⇒ Object (readonly)
Returns the value of attribute near.
9 10 11 |
# File 'lib/quake/camera.rb', line 9 def near @near end |
#pitch ⇒ Object
Returns the value of attribute pitch.
8 9 10 |
# File 'lib/quake/camera.rb', line 8 def pitch @pitch end |
#position ⇒ Object
Returns the value of attribute position.
8 9 10 |
# File 'lib/quake/camera.rb', line 8 def position @position end |
#roll ⇒ Object
Returns the value of attribute roll.
8 9 10 |
# File 'lib/quake/camera.rb', line 8 def roll @roll end |
#yaw ⇒ Object
Returns the value of attribute yaw.
8 9 10 |
# File 'lib/quake/camera.rb', line 8 def yaw @yaw end |
Instance Method Details
#apply_gl ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/quake/camera.rb', line 101 def apply_gl GL.MatrixMode(GL::MODELVIEW) GL.LoadIdentity # Quake coords (X-forward, Y-left, Z-up) -> GL coords (X-right, Y-up, Z-backward) # Rotate -90 around X to convert Z-up to Y-up # Rotate 90 around Z to convert X-forward to -Z-backward GL.Rotatef(-90.0, 1.0, 0.0, 0.0) # Z-up -> Y-up GL.Rotatef(90.0, 0.0, 0.0, 1.0) # X-forward -> GL GL.Rotatef(-@roll, 1.0, 0.0, 0.0) GL.Rotatef(-@pitch, 0.0, 1.0, 0.0) GL.Rotatef(-@yaw, 0.0, 0.0, 1.0) GL.Translatef(-@position.x, -@position.y, -@position.z) end |
#apply_projection_gl(aspect) ⇒ Object
63 64 65 66 67 |
# File 'lib/quake/camera.rb', line 63 def apply_projection_gl(aspect) GL.MatrixMode(GL::PROJECTION) GL.LoadIdentity GLU.Perspective(fov_y(aspect), aspect, @near, @far) end |
#forward ⇒ Object
27 28 29 |
# File 'lib/quake/camera.rb', line 27 def forward quake_angle_vectors.fetch(:forward) end |
#fov_x(aspect) ⇒ Object
Actual horizontal FOV for a given aspect (follows from fov_y)
78 79 80 |
# File 'lib/quake/camera.rb', line 78 def fov_x(aspect) 2.0 * ::Math.atan(::Math.tan(deg2rad(fov_y) / 2.0) * aspect) * 180.0 / ::Math::PI end |
#fov_y(_aspect = nil) ⇒ Object
Quake's fov cvar is the horizontal FOV on a 4:3 screen. Like Quakespasm's fov_adapt (Hor+), the vertical FOV stays at its 4:3 value on wide screens and the horizontal FOV widens instead -- otherwise widescreen crops the view and the weapon model.
73 74 75 |
# File 'lib/quake/camera.rb', line 73 def fov_y(_aspect = nil) 2.0 * ::Math.atan(::Math.tan(deg2rad(@fov) / 2.0) * 0.75) * 180.0 / ::Math::PI end |
#frustum_planes(aspect) ⇒ Object
R_SetFrustum: 4 view-frustum planes as [normal, dist] pairs, where a point is inside when normal.dot(point) - dist >= 0.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/quake/camera.rb', line 84 def frustum_planes(aspect) vecs = quake_angle_vectors forward = vecs.fetch(:forward) right = vecs.fetch(:right) up = vecs.fetch(:up) fx = fov_x(aspect) fy = fov_y normals = [ rotate_around_axis(forward, up, -(90.0 - fx / 2.0)), rotate_around_axis(forward, up, 90.0 - fx / 2.0), rotate_around_axis(forward, right, 90.0 - fy / 2.0), rotate_around_axis(forward, right, -(90.0 - fy / 2.0)) ] normals.map { |normal| [normal, normal.dot(@position)] } end |
#move_forward(dt) ⇒ Object
39 40 41 |
# File 'lib/quake/camera.rb', line 39 def move_forward(dt) @position = @position + forward * (SPEED * dt) end |
#move_right(dt) ⇒ Object
43 44 45 |
# File 'lib/quake/camera.rb', line 43 def move_right(dt) @position = @position + right * (SPEED * dt) end |
#move_up(dt) ⇒ Object
47 48 49 |
# File 'lib/quake/camera.rb', line 47 def move_up(dt) @position = @position + up * (SPEED * dt) end |
#right ⇒ Object
31 32 33 |
# File 'lib/quake/camera.rb', line 31 def right quake_angle_vectors.fetch(:right) end |
#rotate(dx, dy) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/quake/camera.rb', line 51 def rotate(dx, dy) if @ignore_mouse > 0 @ignore_mouse -= 1 return end dx = dx.clamp(-MAX_MOUSE_DELTA, MAX_MOUSE_DELTA) dy = dy.clamp(-MAX_MOUSE_DELTA, MAX_MOUSE_DELTA) @yaw -= dx * SENSITIVITY @pitch += dy * SENSITIVITY @pitch = @pitch.clamp(-89.0, 89.0) end |
#up ⇒ Object
35 36 37 |
# File 'lib/quake/camera.rb', line 35 def up quake_angle_vectors.fetch(:up) end |