Files
i-mic-fps/lib/camera_controller.rb
2020-12-02 17:37:48 -06:00

113 lines
3.3 KiB
Ruby

# frozen_string_literal: true
class IMICFPS
class CameraController
include CommonMethods
attr_accessor :mode, :camera, :entity, :distance, :origin_distance,
:constant_pitch, :mouse_sensitivity, :mouse_captured
def initialize(camera:, entity:, mode: :fpv)
# :fpv - First Person View
# :tpv - Third Person View
@mode = mode
@camera = camera
@entity = entity
@distance = 4
@origin_distance = @distance
@constant_pitch = 20.0
window.mouse_x = window.width / 2
window.mouse_y = window.height / 2
@true_mouse = Point.new(window.width / 2, window.height / 2)
@mouse_sensitivity = 20.0 # Less is faster, more is slower
@mouse_captured = true
@mouse_checked = 0
end
def first_person_view?
@mode == :fpv
end
def distance_from_object
@distance
end
def horizontal_distance_from_object
distance_from_object * Math.cos(@constant_pitch)
end
def vertical_distance_from_object
distance_from_object * Math.sin(@constant_pitch)
end
def position_camera
@distance = if first_person_view?
0
else
@origin_distance
end
x_offset = horizontal_distance_from_object * Math.sin(@entity.orientation.y.degrees_to_radians)
z_offset = horizontal_distance_from_object * Math.cos(@entity.orientation.y.degrees_to_radians)
eye_height = @entity.normalize_bounding_box.max.y
@camera.position.x = @entity.position.x - x_offset
@camera.position.y = @entity.position.y + eye_height
@camera.position.z = @entity.position.z - z_offset
@camera.orientation.y = 180 - @entity.orientation.y
end
def update
position_camera
if @mouse_captured
delta = Float(@true_mouse.x - mouse_x) / (@mouse_sensitivity * @camera.field_of_view) * 70
@camera.orientation.y -= delta
@camera.orientation.y %= 360.0
@camera.orientation.x -= Float(@true_mouse.y - window.mouse_y) / (@mouse_sensitivity * @camera.field_of_view) * 70
@camera.orientation.x = @camera.orientation.x.clamp(-90.0, 90.0)
@entity.orientation.y += delta
@entity.orientation.y %= 360.0
window.mouse_x = window.width / 2 if window.mouse_x <= 1 || window.mouse_x >= window.width - 1
window.mouse_y = window.height / 2 if window.mouse_y <= 1 || window.mouse_y >= window.height - 1
@true_mouse.x = window.mouse_x
@true_mouse.y = window.mouse_y
end
end
def button_down(id)
actions = InputMapper.actions(id)
if actions.include?(:release_mouse)
@mouse_captured = false
window.needs_cursor = true
elsif actions.include?(:capture_mouse)
@mouse_captured = true
window.needs_cursor = false
elsif actions.include?(:decrease_view_distance)
@camera.max_view_distance -= 0.5
elsif actions.include?(:increase_view_distance)
@camera.max_view_distance += 0.5
elsif actions.include?(:toggle_first_person_view)
@mode = first_person_view? ? :tpv : :fpv
@entity.visible = !first_person_view?
elsif actions.include?(:turn_180)
@entity.orientation.y += 180
@entity.orientation.y %= 360.0
end
end
def button_up(id)
end
end
end