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