From 57c52cd725f6f8b9aaad33f2b59c8834ed8109f7 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Tue, 20 Mar 2018 19:25:06 -0500 Subject: [PATCH] Moved camera into its own class, added CommonMethods for gosu methods outside of window. --- i-mic-fps.rb | 2 + lib/common_methods.rb | 12 +++++ lib/objects/camera.rb | 110 ++++++++++++++++++++++++++++++++++++++++++ lib/objects/model.rb | 4 +- lib/window.rb | 102 +++++---------------------------------- 5 files changed, 137 insertions(+), 93 deletions(-) create mode 100644 lib/common_methods.rb create mode 100644 lib/objects/camera.rb diff --git a/i-mic-fps.rb b/i-mic-fps.rb index 8de9caf..51a7f02 100644 --- a/i-mic-fps.rb +++ b/i-mic-fps.rb @@ -20,10 +20,12 @@ BoundingBox = Struct.new(:min_x, :min_y, :min_z, :max_x, :max_y, :max_z) $debug = ARGV.join.include?("--debug") ? true : false +require_relative "lib/common_methods" require_relative "lib/managers/object_manager" require_relative "lib/managers/light_manager" require_relative "lib/objects/light" +require_relative "lib/objects/camera" require_relative "lib/objects/model" require_relative "lib/wavefront/model" diff --git a/lib/common_methods.rb b/lib/common_methods.rb new file mode 100644 index 0000000..4278dfc --- /dev/null +++ b/lib/common_methods.rb @@ -0,0 +1,12 @@ +class IMICFPS + module CommonMethods + + def delta_time; $window.delta_time; end + def button_down?(id); $window.button_down?(id); end + + def mouse_x; $window.mouse_x; end + def mouse_y; $window.mouse_y; end + def mouse_x=int; $window.mouse_x=int; end + def mouse_y=int; $window.mouse_y=int; end + end +end diff --git a/lib/objects/camera.rb b/lib/objects/camera.rb new file mode 100644 index 0000000..3afb73c --- /dev/null +++ b/lib/objects/camera.rb @@ -0,0 +1,110 @@ +class IMICFPS + class Camera + include CommonMethods + include OpenGL + include GLU + + attr_accessor :x,:y,:z, :field_of_view, :vertical_angle, :horizontal_angle, :mouse_sensitivity + def initialize(x: 0, y: 0, z: 0, fov: 70.0) + @x,@y,@z = x,y,z + @vertical_angle = 0.0 + @horizontal_angle = 0.0 + @field_of_view = fov + + @speed = 0.05 + @old_speed = @speed + self.mouse_x, self.mouse_y = Gosu.screen_width/2, Gosu.screen_height/2 + @true_mouse = Point.new(Gosu.screen_width/2, Gosu.screen_height/2) + @true_mouse_checked = 0 + @mouse_sensitivity = 20.0 + end + + def draw + #glMatrixMode(matrix) indicates that following [matrix] is going to get used + glMatrixMode(GL_PROJECTION) # The projection matrix is responsible for adding perspective to our scene. + glLoadIdentity # Resets current modelview matrix + # Calculates aspect ratio of the window. Gets perspective view. 45 is degree viewing angle, (0.1, 100) are ranges how deep can we draw into the screen + gluPerspective(@field_of_view, $window.width / $window.height, 0.1, 1000.0) + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) + + glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored. + glLoadIdentity + + glEnable(GL_DEPTH_TEST) + + glRotatef(@vertical_angle,1,0,0) + glRotatef(@horizontal_angle,0,1,0) + glTranslatef(@x, @y, @z) + end + + def update + if @true_mouse_checked > 2 + @horizontal_angle-=Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70 + @vertical_angle-=Float(@true_mouse.y-self.mouse_y)/(@mouse_sensitivity*@field_of_view)*70 + @horizontal_angle %= 360.0 + @vertical_angle = @vertical_angle.clamp(-90.0, 90.0) + else + @true_mouse_checked+=1 + @true_mouse.x = self.mouse_x + @true_mouse.y = self.mouse_y + end + + self.mouse_x, self.mouse_y = Gosu.screen_width/2.0, Gosu.screen_height/2.0 + @true_mouse_checked = 0 if (button_down?(Gosu::KbLeftAlt) && (button_down?(Gosu::KbEnter) || button_down?(Gosu::KbReturn))) + @true_mouse_checked = 0 if (button_down?(Gosu::KbRightAlt) && (button_down?(Gosu::KbEnter) || button_down?(Gosu::KbReturn))) + + relative_speed = @speed + if button_down?(Gosu::KbLeftControl) + relative_speed = (@speed*10.0)*(delta_time/60.0) + else + relative_speed = @speed*(delta_time/60.0) + end + + if button_down?(Gosu::KbUp) || button_down?(Gosu::KbW) + @z+=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed + @x-=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed + end + if button_down?(Gosu::KbDown) || button_down?(Gosu::KbS) + @z-=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed + @x+=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed + end + if button_down?(Gosu::KbA) + @z+=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed + @x+=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed + end + if button_down?(Gosu::KbD) + @z-=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed + @x-=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed + end + + if button_down?(Gosu::KbLeft) + @horizontal_angle-=relative_speed*100 + end + if button_down?(Gosu::KbRight) + @horizontal_angle+=relative_speed*100 + end + + @y+=relative_speed if button_down?(Gosu::KbC) || button_down?(Gosu::KbLeftShift) + @y-=relative_speed if button_down?(Gosu::KbSpace) + end + + def button_up(id) + case id + when Gosu::KB_NUMPAD_PLUS + @mouse_sensitivity+=1 + @mouse_sensitivity = @mouse_sensitivity.clamp(1.0, 100.0) + when Gosu::KbMinus, Gosu::KB_NUMPAD_MINUS + @mouse_sensitivity-=1 + @mouse_sensitivity = @mouse_sensitivity.clamp(1.0, 100.0) + when Gosu::KB_NUMPAD_MULTIPLY + @mouse_sensitivity = 20.0 + when Gosu::MsWheelUp + @field_of_view += 1 + @field_of_view = @field_of_view.clamp(1, 179) + when Gosu::MsWheelDown + @field_of_view -= 1 + @field_of_view = @field_of_view.clamp(1, 179) + end + end + end +end diff --git a/lib/objects/model.rb b/lib/objects/model.rb index 5ab3c78..091239f 100644 --- a/lib/objects/model.rb +++ b/lib/objects/model.rb @@ -80,7 +80,7 @@ class IMICFPS next if a == b if a.intersect(a.model.bounding_box, b.model.bounding_box) if a.name == "tree" - a.y_rotation+=0.1 + a.y_rotation+=0.01 end end end @@ -132,8 +132,6 @@ class IMICFPS def render_bounding_box(bounding_box, color = @debug_color) # TODO: Minimize number of calls in here bounding_box = normalize_bounding_box(bounding_box) - puts bounding_box - puts glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glBegin(GL_TRIANGLES) diff --git a/lib/window.rb b/lib/window.rb index fc46780..cc68ce0 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -26,17 +26,7 @@ class IMICFPS # Model.new(type: :obj, file_path: "objects/tree.obj", x: -2, z: -6) # Model.new(type: :obj, file_path: "objects/sponza.obj", scale: 1, y: -0.2) - @camera = Vertex.new(0,-1,0) - @camera_target = Vertex.new(0,-1,0) - @speed = 0.05 - @old_speed = @speed - @vertical_angle = 0.0 # | - @horizontal_angle = 0.0 # _ - self.mouse_x, self.mouse_y = Gosu.screen_width/2, Gosu.screen_height/2 - @true_mouse = Point.new(Gosu.screen_width/2, Gosu.screen_height/2) - @true_mouse_checked = 0 - @mouse_sesitivity = 20.0 - @initial_fov = 70.0 + @camera = Camera.new @crosshair_size = 10 @crosshair_thickness = 3 @@ -68,22 +58,9 @@ class IMICFPS glClearColor(0,0.2,0.5,1) # skyish blue glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer - #glMatrixMode(matrix) indicates that following [matrix] is going to get used - glMatrixMode(GL_PROJECTION) # The projection matrix is responsible for adding perspective to our scene. - glLoadIdentity # Resets current modelview matrix - # Calculates aspect ratio of the window. Gets perspective view. 45 is degree viewing angle, (0.1, 100) are ranges how deep can we draw into the screen - gluPerspective(@initial_fov, width / height, 0.1, 1000.0) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) - - glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored. - glLoadIdentity - - glEnable(GL_DEPTH_TEST) + @camera.draw @camera_light.draw - glRotatef(@vertical_angle,1,0,0) - glRotatef(@horizontal_angle,0,1,0) - glTranslatef(@camera.x, @camera.y, @camera.z) # gluLookAt(@camera.x,@camera.y,@camera.z, @horizontal_angle,@vertical_angle,0, 0,1,0) ObjectManager.objects.each do |object| @@ -107,10 +84,10 @@ class IMICFPS OpenGL Version: #{glGetString(GL_VERSION)}~ OpenGL Shader Language Version: #{glGetString(GL_SHADING_LANGUAGE_VERSION)}~ ~ - Vertical Angle: #{@vertical_angle.round(2)} Horizontal Angle: #{@horizontal_angle.round(2)} ~ + Vertical Angle: #{@camera.vertical_angle.round(2)} Horizontal Angle: #{@camera.horizontal_angle.round(2)} ~ X:#{@camera.x.round(2)} Y:#{@camera.y.round(2)} Z:#{@camera.z.round(2)} ~ - FOV: #{@initial_fov} ~ - Mouse Sesitivity: #{@mouse_sesitivity} ~ + FOV: #{@camera.field_of_view} ~ + Mouse Sesitivity: #{@camera.mouse_sensitivity} ~ Faces: #{@number_of_faces} ~ Last Frame: #{delta_time}ms (#{Gosu.fps} fps)~ ~ @@ -121,54 +98,7 @@ class IMICFPS object.update end - if @true_mouse_checked > 2 - @horizontal_angle-=Float(@true_mouse.x-self.mouse_x)/(@mouse_sesitivity*@initial_fov)*70 - @vertical_angle-=Float(@true_mouse.y-self.mouse_y)/(@mouse_sesitivity*@initial_fov)*70 - @horizontal_angle %= 360.0 - @vertical_angle = @vertical_angle.clamp(-90.0, 90.0) - else - @true_mouse_checked+=1 - @true_mouse.x = self.mouse_x - @true_mouse.y = self.mouse_y - end - - self.mouse_x, self.mouse_y = Gosu.screen_width/2.0, Gosu.screen_height/2.0 - @true_mouse_checked = 0 if (button_down?(Gosu::KbLeftAlt) && (button_down?(Gosu::KbEnter) || button_down?(Gosu::KbReturn))) - @true_mouse_checked = 0 if (button_down?(Gosu::KbRightAlt) && (button_down?(Gosu::KbEnter) || button_down?(Gosu::KbReturn))) - - relative_speed = @speed - if button_down?(Gosu::KbLeftControl) - relative_speed = (@speed*10.0)*(delta_time/60.0) - else - relative_speed = @speed*(delta_time/60.0) - end - - if button_down?(Gosu::KbUp) || button_down?(Gosu::KbW) - @camera.z+=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed - @camera.x-=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed - end - if button_down?(Gosu::KbDown) || button_down?(Gosu::KbS) - @camera.z-=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed - @camera.x+=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed - end - if button_down?(Gosu::KbA) - @camera.z+=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed - @camera.x+=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed - end - if button_down?(Gosu::KbD) - @camera.z-=Math.sin(@horizontal_angle * Math::PI / 180)*relative_speed - @camera.x-=Math.cos(@horizontal_angle * Math::PI / 180)*relative_speed - end - - if button_down?(Gosu::KbLeft) - @horizontal_angle-=relative_speed*100 - end - if button_down?(Gosu::KbRight) - @horizontal_angle+=relative_speed*100 - end - - @camera.y+=relative_speed if $window.button_down?(Gosu::KbC) || $window.button_down?(Gosu::KbLeftShift) - @camera.y-=relative_speed if $window.button_down?(Gosu::KbSpace) + @camera.update $window.close if $window.button_down?(Gosu::KbEscape) @number_of_faces = 0 @@ -176,26 +106,18 @@ class IMICFPS end def button_up(id) + ObjectManager.objects.each do |object| + object.button_up(id) if defined?(object.button_up) + end + + @camera.button_up(id) + case id when Gosu::KbZ @draw_skydome = !@draw_skydome @skydome.renderable = @draw_skydome - when Gosu::KB_NUMPAD_PLUS - @mouse_sesitivity+=1 - @mouse_sesitivity = @mouse_sesitivity.clamp(1.0, 100.0) - when Gosu::KbMinus, Gosu::KB_NUMPAD_MINUS - @mouse_sesitivity-=1 - @mouse_sesitivity = @mouse_sesitivity.clamp(1.0, 100.0) - when Gosu::KB_NUMPAD_MULTIPLY - @mouse_sesitivity = 20.0 when Gosu::KbBacktick $debug = !$debug - when Gosu::MsWheelUp - @initial_fov += 1 - @initial_fov = @initial_fov.clamp(1, 179) - when Gosu::MsWheelDown - @initial_fov -= 1 - @initial_fov = @initial_fov.clamp(1, 179) end end