From 97818c8a336e8edb99647f6090d5b2f2cc824e16 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Mon, 25 Feb 2019 11:33:18 -0600 Subject: [PATCH] Collision stuff --- lib/managers/collision_manager.rb | 8 +++++++- lib/managers/entity_manager.rb | 2 +- lib/math/bounding_box.rb | 8 +++++++- lib/objects/entities/player.rb | 1 + lib/objects/entities/skydome.rb | 1 + lib/objects/entity.rb | 6 +++--- lib/trees/aabb_node.rb | 2 +- lib/trees/aabb_tree.rb | 13 +++++++++++-- 8 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/managers/collision_manager.rb b/lib/managers/collision_manager.rb index 1a4669f..7e4be3c 100644 --- a/lib/managers/collision_manager.rb +++ b/lib/managers/collision_manager.rb @@ -29,6 +29,9 @@ class IMICFPS # binding.irb p @aabb_tree + collisions.each do |ent, list| + puts "#{ent.class} -> [#{list.map{|e| e.class}.join(', ')}]" + end end def remove(entity) @@ -40,9 +43,12 @@ class IMICFPS broadphase = {} @game_state.entities.each do |entity| + next unless entity.collidable? + next if entity.collision == :static # Only dynamic entities can be resolved + search = @aabb_tree.search(entity.bounding_box) if search.size > 0 - search.reject! {|ent| ent == entity} + search.reject! {|ent| ent == entity || !ent.collidable?} broadphase[entity] = search end end diff --git a/lib/managers/entity_manager.rb b/lib/managers/entity_manager.rb index 7c28bf7..84dbe79 100644 --- a/lib/managers/entity_manager.rb +++ b/lib/managers/entity_manager.rb @@ -5,7 +5,7 @@ class IMICFPS module EntityManager # Get included into GameState context def add_entity(entity) - @collision_manager.add(entity) if entity.collidable? + @collision_manager.add(entity)# Add every entity to collision manager @entities << entity end diff --git a/lib/math/bounding_box.rb b/lib/math/bounding_box.rb index e8d6822..979d8f5 100644 --- a/lib/math/bounding_box.rb +++ b/lib/math/bounding_box.rb @@ -42,8 +42,14 @@ class IMICFPS return temp end + # does this bounding box envelop other bounding box? (inclusive of border) + def contains?(other) + other.min.x >= min.x && other.min.y >= min.y && other.min.z >= min.z && + other.max.x <= max.x && other.max.y <= max.y && other.max.z <= max.z + end + # returns whether the vector is inside of the bounding box - def contains(vector) + def point?(vector) vector.x.between?(@min.x, @max.x) && vector.y.between?(@min.y, @max.y) && vector.z.between?(@min.z, @max.z) diff --git a/lib/objects/entities/player.rb b/lib/objects/entities/player.rb index 522ff29..b580eff 100644 --- a/lib/objects/entities/player.rb +++ b/lib/objects/entities/player.rb @@ -8,6 +8,7 @@ class IMICFPS def setup bind_model("base", "biped") + @collision = :dynamic @speed = 2.5 # meter's per second @running_speed = 6.8 # meter's per second diff --git a/lib/objects/entities/skydome.rb b/lib/objects/entities/skydome.rb index 372b09e..97e249d 100644 --- a/lib/objects/entities/skydome.rb +++ b/lib/objects/entities/skydome.rb @@ -2,6 +2,7 @@ class IMICFPS class Skydome < Entity def setup bind_model("base", "skydome") + @collision = :none end def draw diff --git a/lib/objects/entity.rb b/lib/objects/entity.rb index 8ffafd7..177c036 100644 --- a/lib/objects/entity.rb +++ b/lib/objects/entity.rb @@ -7,7 +7,7 @@ class IMICFPS include GLU include CommonMethods attr_accessor :scale, :visible, :renderable, :backface_culling - attr_reader :position, :rotation, :velocity + attr_reader :position, :rotation, :velocity, :collision attr_reader :model, :name, :debug_color, :bounding_box 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) @@ -22,8 +22,8 @@ class IMICFPS @debug_color = Color.new(0.0, 1.0, 0.0) @collidable = [:static, :dynamic] - @collision = :static # :dynamic, moves in response, :static, does not move ever, :none, entities can pass through - @physics = false + @collision = :static # :dynamic => moves in response, :static => does not move ever, :none => no collision check, entities can pass through + @physics = false # Entity affected by gravity and what not @mass = 100 # kg @delta_time = Gosu.milliseconds diff --git a/lib/trees/aabb_node.rb b/lib/trees/aabb_node.rb index dcf1392..f20fb74 100644 --- a/lib/trees/aabb_node.rb +++ b/lib/trees/aabb_node.rb @@ -66,7 +66,7 @@ class IMICFPS other_child.parent = @parent return other_child else - leaf.disown_child(leaf) + leaf.parent.disown_child(leaf) return self end end diff --git a/lib/trees/aabb_tree.rb b/lib/trees/aabb_tree.rb index 3443440..5d8b24a 100644 --- a/lib/trees/aabb_tree.rb +++ b/lib/trees/aabb_tree.rb @@ -18,6 +18,10 @@ class IMICFPS leaf = AABBNode.new(parent: nil, object: object, bounding_box: bounding_box.dup) @objects[object] = leaf + insert_leaf(leaf) + end + + def insert_leaf(leaf) if @root @root = @root.insert_subtree(leaf) else @@ -26,8 +30,10 @@ class IMICFPS end def update(object, bounding_box) - remove(object) - insert(object, bounding_box) + leaf = remove(object) + leaf.bounding_box = bounding_box + @objects[object] = leaf + insert_leaf(leaf) end # Returns a list of all collided objects inside Bounding Box @@ -44,6 +50,9 @@ class IMICFPS def remove(object) leaf = @objects.delete(object) @root = @root.remove_subtree(leaf) if leaf + @root.parent = nil + + return leaf end end end \ No newline at end of file