From 016e8109de9a83fa849ee09a92a0cc278f4aff84 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Tue, 13 Aug 2019 09:47:23 -0500 Subject: [PATCH] Gravity constant moved into constants.rb, camera can now report what it is looking at, entity has knowledge of camera now, AABB tree search can now use either BoundingBox or Ray colliders --- lib/constants.rb | 5 ++++ lib/managers/collision_manager.rb | 9 ++++--- lib/objects/camera.rb | 41 +++++++++++++++++-------------- lib/objects/entities/player.rb | 3 +++ lib/objects/entity.rb | 12 ++++++++- lib/states/game_states/game.rb | 4 ++- lib/trees/aabb_node.rb | 8 +++--- lib/trees/aabb_tree.rb | 6 ++--- lib/window.rb | 2 -- 9 files changed, 57 insertions(+), 33 deletions(-) diff --git a/lib/constants.rb b/lib/constants.rb index d1b5835..5930462 100644 --- a/lib/constants.rb +++ b/lib/constants.rb @@ -8,4 +8,9 @@ class IMICFPS # Objects exported from blender using the default or meter object scale will be close to 1 GL unit MODEL_METER_SCALE = 1.0 + + # Earth + GRAVITY = 9.8 # m/s + # Moon + # GRAVITY = 1.625 # m/s end \ No newline at end of file diff --git a/lib/managers/collision_manager.rb b/lib/managers/collision_manager.rb index 3d8388b..7dfa518 100644 --- a/lib/managers/collision_manager.rb +++ b/lib/managers/collision_manager.rb @@ -19,17 +19,18 @@ class IMICFPS next unless node = @aabb_tree.objects[entity] unless entity.bounding_box == node.bounding_box - @aabb_tree.update(entity, entity.bounding_box) + puts "Updating #{entity.class}" + @aabb_tree.update(entity, entity.bounding_box.clone) end end check_broadphase @physics_manager.update + end - collisions.each do |ent, list| - # puts "#{ent.class} -> [#{list.map { |e| e.class }.join(', ')}] (#{Gosu.milliseconds})" - end + def search(collider) + @aabb_tree.search(collider) end def remove(entity) diff --git a/lib/objects/camera.rb b/lib/objects/camera.rb index 3272001..0774178 100644 --- a/lib/objects/camera.rb +++ b/lib/objects/camera.rb @@ -2,13 +2,11 @@ class IMICFPS class Camera include CommonMethods - attr_accessor :field_of_view, :pitch, :yaw, :roll, :mouse_sensitivity - attr_reader :entity, :position + attr_accessor :field_of_view, :mouse_sensitivity + attr_reader :entity, :position, :orientation, :mouse_captured def initialize(x: 0, y: 0, z: 0, fov: 70.0, view_distance: 155.0) @position = Vector.new(x,y,z) - @pitch = 0.0 - @yaw = 0.0 - @roll = 0.0 + @orientation = Vector.new(0, 0, 0) @field_of_view = fov @view_distance = view_distance @constant_pitch = 20.0 @@ -17,8 +15,8 @@ class IMICFPS @distance = 4 @origin_distance = @distance - self.mouse_x, self.mouse_y = window.width/2, window.height/2 - @true_mouse = Point.new(window.width/2, window.height/2) + self.mouse_x, self.mouse_y = window.width / 2, 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 @@ -27,9 +25,11 @@ class IMICFPS def attach_to(entity) raise "Not an Entity!" unless entity.is_a?(Entity) @entity = entity + @entity.attach_camera(self) end def detach + @entity.detach_camera @entity = nil end @@ -61,7 +61,7 @@ class IMICFPS @position.y = @entity.position.y + 2 @position.z = @entity.position.z - z_offset - @yaw = 180 - @entity.rotation.y + @orientation.y = 180 - @entity.rotation.y end def draw @@ -71,8 +71,8 @@ class IMICFPS # 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, @view_distance) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) - glRotatef(@pitch,1,0,0) - glRotatef(@yaw,0,1,0) + glRotatef(@orientation.z, 1, 0, 0) + glRotatef(@orientation.y, 0, 1, 0) glTranslatef(-@position.x, -@position.y, -@position.z) glMatrixMode(GL_MODELVIEW) # The modelview matrix is where object information is stored. glLoadIdentity @@ -82,25 +82,30 @@ class IMICFPS def update if @mouse_captured - delta = Float(@true_mouse.x-self.mouse_x)/(@mouse_sensitivity*@field_of_view)*70 - @yaw -= delta - @yaw %= 360.0 + delta = Float(@true_mouse.x - self.mouse_x) / (@mouse_sensitivity * @field_of_view) * 70 + @orientation.y -= delta + @orientation.y %= 360.0 - @pitch -= Float(@true_mouse.y-self.mouse_y)/(@mouse_sensitivity*@field_of_view)*70 - @pitch = @pitch.clamp(-90.0, 90.0) + @orientation.z -= Float(@true_mouse.y - self.mouse_y) / (@mouse_sensitivity * @field_of_view) * 70 + @orientation.z = @orientation.z.clamp(-90.0, 90.0) @entity.rotation.y += delta if @entity free_move unless @entity position_camera if @entity - self.mouse_x = window.width/2 if self.mouse_x <= 1 || window.mouse_x >= window.width-1 - self.mouse_y = window.height/2 if self.mouse_y <= 1 || window.mouse_y >= window.height-1 + self.mouse_x = window.width / 2 if self.mouse_x <= 1 || window.mouse_x >= window.width-1 + self.mouse_y = window.height / 2 if self.mouse_y <= 1 || window.mouse_y >= window.height-1 @true_mouse.x, @true_mouse.y = self.mouse_x, self.mouse_y end end + def looking_at + ray = Ray.new(@position, @orientation.direction * -1) + window.current_state.collision_manager.search(ray) + end + def free_move - relative_y_rotation = (@yaw + 180) + relative_y_rotation = (@orientation.y + 180) relative_speed = 0.25 if InputMapper.down?( :forward) diff --git a/lib/objects/entities/player.rb b/lib/objects/entities/player.rb index b8bdbe5..82d5eb5 100644 --- a/lib/objects/entities/player.rb +++ b/lib/objects/entities/player.rb @@ -90,6 +90,9 @@ class IMICFPS end def update + # Do not handle movement if mouse is not captured + return if @camera && !@camera.mouse_captured + relative_speed = @speed if InputMapper.down?(:sprint) relative_speed = @running_speed diff --git a/lib/objects/entity.rb b/lib/objects/entity.rb index 386e619..ae37f99 100644 --- a/lib/objects/entity.rb +++ b/lib/objects/entity.rb @@ -7,7 +7,7 @@ class IMICFPS attr_accessor :scale, :visible, :renderable, :backface_culling attr_accessor :position, :rotation, :velocity - attr_reader :name, :debug_color, :bounding_box, :collision, :physics, :mass, :drag + attr_reader :name, :debug_color, :bounding_box, :collision, :physics, :mass, :drag, :camera def initialize(x: 0, y: 0, z: 0, bound_model: nil, scale: MODEL_METER_SCALE, backface_culling: true, auto_manage: true, manifest_file: nil) @position = Vector.new(x, y, z) @@ -43,6 +43,8 @@ class IMICFPS normalize_bounding_box end + @camera = nil + return self end @@ -70,6 +72,14 @@ class IMICFPS @bound_model = nil end + def attach_camera(camera) + @camera = camera + end + + def detach_camera + @camera = nil + end + def setup end diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index 738c186..52cd023 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -1,5 +1,7 @@ class IMICFPS class Game < GameState + + attr_reader :collision_manager def setup @collision_manager = CollisionManager.new(game_state: self) @renderer = Renderer.new(game_state: self) @@ -154,7 +156,7 @@ OpenGL Renderer: #{glGetString(GL_RENDERER)} OpenGL Version: #{glGetString(GL_VERSION)} OpenGL Shader Language Version: #{glGetString(GL_SHADING_LANGUAGE_VERSION)} -Camera pitch: #{@camera.pitch.round(2)} Yaw: #{@camera.yaw.round(2)} Roll #{@camera.roll.round(2)} +Camera pitch: #{@camera.orientation.z.round(2)} Yaw: #{@camera.orientation.y.round(2)} Roll #{@camera.orientation.x.round(2)} Camera X:#{@camera.position.x.round(2)} Y:#{@camera.position.y.round(2)} Z:#{@camera.position.z.round(2)} #{if @camera.entity then "Actor X:#{@camera.entity.position.x.round(2)} Y:#{@camera.entity.position.y.round(2)} Z:#{@camera.entity.position.z.round(2)}";end} Field Of View: #{@camera.field_of_view} diff --git a/lib/trees/aabb_node.rb b/lib/trees/aabb_node.rb index 9101455..183e0bb 100644 --- a/lib/trees/aabb_node.rb +++ b/lib/trees/aabb_node.rb @@ -55,13 +55,13 @@ class IMICFPS end end - def search_subtree(bounding_box, items = []) - if @bounding_box.intersect?(bounding_box) + def search_subtree(collider, items = []) + if @bounding_box.intersect?(collider) if leaf? items << self else - @a.search_subtree(bounding_box, items) - @b.search_subtree(bounding_box, items) + @a.search_subtree(collider, items) + @b.search_subtree(collider, items) end end diff --git a/lib/trees/aabb_tree.rb b/lib/trees/aabb_tree.rb index 49b6e95..415bcb7 100644 --- a/lib/trees/aabb_tree.rb +++ b/lib/trees/aabb_tree.rb @@ -35,11 +35,11 @@ class IMICFPS insert_leaf(leaf) end - # Returns a list of all collided objects inside Bounding Box - def search(bounding_box, return_nodes = false) + # Returns a list of all objects that collided with collider + def search(collider, return_nodes = false) items = [] if @root - items = @root.search_subtree(bounding_box) + items = @root.search_subtree(collider) items.map! {|e| e.object} unless return_nodes end diff --git a/lib/window.rb b/lib/window.rb index ea369f6..bac554c 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -1,6 +1,4 @@ class IMICFPS - GRAVITY = 9.8 # m/s - class Window < CyberarmEngine::Engine attr_accessor :number_of_vertices, :needs_cursor attr_reader :camera