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.
-
#yaw ⇒ Object
Returns the value of attribute yaw.
Instance Method Summary collapse
- #apply_gl ⇒ Object
- #apply_projection_gl(aspect) ⇒ Object
- #forward ⇒ Object
-
#initialize(position: Math::Vec3::ORIGIN, yaw: 0.0, pitch: 0.0, fov: 90.0, near: 4.0, far: 4096.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: 4096.0) ⇒ Camera
Returns a new instance of Camera.
15 16 17 18 19 20 21 22 23 24 |
# 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: 4096.0) @position = position @yaw = yaw @pitch = pitch @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 |
#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
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/quake/camera.rb', line 78 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(-@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
72 73 74 75 76 |
# File 'lib/quake/camera.rb', line 72 def apply_projection_gl(aspect) GL.MatrixMode(GL::PROJECTION) GL.LoadIdentity GLU.Perspective(@fov, aspect, @near, @far) end |
#forward ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/quake/camera.rb', line 26 def forward # Quake: X = forward, Y = left, Z = up # yaw rotates around Z, pitch rotates around Y ry = deg2rad(@yaw) rp = deg2rad(@pitch) cp = ::Math.cos(rp) Math::Vec3.new( ::Math.cos(ry) * cp, ::Math.sin(ry) * cp, -::Math.sin(rp) ) end |
#move_forward(dt) ⇒ Object
48 49 50 |
# File 'lib/quake/camera.rb', line 48 def move_forward(dt) @position = @position + forward * (SPEED * dt) end |
#move_right(dt) ⇒ Object
52 53 54 |
# File 'lib/quake/camera.rb', line 52 def move_right(dt) @position = @position + right * (SPEED * dt) end |
#move_up(dt) ⇒ Object
56 57 58 |
# File 'lib/quake/camera.rb', line 56 def move_up(dt) @position = @position + up * (SPEED * dt) end |
#right ⇒ Object
39 40 41 42 |
# File 'lib/quake/camera.rb', line 39 def right ry = deg2rad(@yaw - 90.0) Math::Vec3.new(::Math.cos(ry), ::Math.sin(ry), 0.0) end |
#rotate(dx, dy) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/quake/camera.rb', line 60 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 |