From 8ccd1506f3c7af6fe0b83e9e255f909f45b10be1 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Mon, 25 Feb 2019 17:59:09 -0600 Subject: [PATCH] Refactored Model to make faces first class objects for use in AABBTree, renamed BoundingBox.intersect to intersect? --- lib/managers/collision_manager.rb | 2 +- lib/managers/entity_manager.rb | 1 + lib/math/bounding_box.rb | 14 ++++++------ lib/trees/aabb_node.rb | 2 +- lib/wavefront/model.rb | 17 +++++++++++++++ lib/wavefront/object.rb | 36 +++++++++++++++---------------- lib/wavefront/parser.rb | 20 +++++++++++++---- 7 files changed, 60 insertions(+), 32 deletions(-) diff --git a/lib/managers/collision_manager.rb b/lib/managers/collision_manager.rb index 6b33c22..e878c06 100644 --- a/lib/managers/collision_manager.rb +++ b/lib/managers/collision_manager.rb @@ -54,7 +54,7 @@ class IMICFPS end broadphase.each do |entity, _collisions| - _collisions.reject! {|ent| !entity.bounding_box.intersect(ent.bounding_box)} + _collisions.reject! {|ent| !entity.bounding_box.intersect?(ent.bounding_box)} # TODO: mesh aabb tree vs other mesh aabb tree check # TODO: triangle vs other triangle check _collisions.each do |ent| diff --git a/lib/managers/entity_manager.rb b/lib/managers/entity_manager.rb index 84dbe79..75e54bc 100644 --- a/lib/managers/entity_manager.rb +++ b/lib/managers/entity_manager.rb @@ -2,6 +2,7 @@ class IMICFPS TextureCoordinate = Struct.new(:u, :v, :weight) Point = Struct.new(:x, :y) Color = Struct.new(:red, :green, :blue, :alpha) + Face = Struct.new(:vertices, :uvs, :normals, :material, :smoothing) module EntityManager # Get included into GameState context def add_entity(entity) diff --git a/lib/math/bounding_box.rb b/lib/math/bounding_box.rb index 979d8f5..ba099cb 100644 --- a/lib/math/bounding_box.rb +++ b/lib/math/bounding_box.rb @@ -26,13 +26,6 @@ class IMICFPS return temp end - # returns whether both bounding boxes intersect - def intersect(other) - (@min.x <= other.max.x && @max.x >= other.min.x) && - (@min.y <= other.max.y && @max.y >= other.min.y) && - (@min.z <= other.max.z && @max.z >= other.min.z) - end - # returns the difference between both bounding boxes def difference(other) temp = BoundingBox.new @@ -42,6 +35,13 @@ class IMICFPS return temp end + # returns whether both bounding boxes intersect + def intersect?(other) + (@min.x <= other.max.x && @max.x >= other.min.x) && + (@min.y <= other.max.y && @max.y >= other.min.y) && + (@min.z <= other.max.z && @max.z >= other.min.z) + 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 && diff --git a/lib/trees/aabb_node.rb b/lib/trees/aabb_node.rb index 9ef552e..9101455 100644 --- a/lib/trees/aabb_node.rb +++ b/lib/trees/aabb_node.rb @@ -56,7 +56,7 @@ class IMICFPS end def search_subtree(bounding_box, items = []) - if @bounding_box.intersect(bounding_box) + if @bounding_box.intersect?(bounding_box) if leaf? items << self else diff --git a/lib/wavefront/model.rb b/lib/wavefront/model.rb index 668a880..f75dffa 100644 --- a/lib/wavefront/model.rb +++ b/lib/wavefront/model.rb @@ -58,6 +58,23 @@ class IMICFPS @textured_material = key end end + + @aabb_tree = AABBTree.new + @faces.each do |face| + box = BoundingBox.new + box.min = face.vertices.first.dup + box.max = face.vertices.first.dup + + face.vertices.each do |vertex| + if vertex.sum < box.min.sum + box.min = vertex.dup + elsif vertex.sum > box.max.sum + box.max = vertex.dup + end + end + + @aabb_tree.insert(face, box) + end end def allocate_gl_objects diff --git a/lib/wavefront/object.rb b/lib/wavefront/object.rb index 4d922e9..cf60fd4 100644 --- a/lib/wavefront/object.rb +++ b/lib/wavefront/object.rb @@ -34,11 +34,11 @@ class IMICFPS def flattened_vertices unless @vertices_list - @debug_color = @faces.first[3].diffuse + @debug_color = @faces.first.material.diffuse list = [] @faces.each do |face| - [face[0]].each do |v| + face.vertices.each do |v| next unless v list << v.x*@scale list << v.y*@scale @@ -61,8 +61,8 @@ class IMICFPS def flattened_textures unless @textures_list list = [] - @faces.each_with_index do |face, i| - [face[1]].each do |v| + @faces.each do |face| + face.uvs.each do |v| next unless v list << v.x list << v.y @@ -81,12 +81,11 @@ class IMICFPS unless @normals_list list = [] @faces.each do |face| - [face[2]].each do |v| - next unless v - list << v.x - list << v.y - list << v.z - # list << v.weight + face.normals.each do |n| + next unless n + list << n.x + list << n.y + list << n.z end end @@ -101,15 +100,14 @@ class IMICFPS unless @materials_list list = [] @faces.each do |face| - # p face - [face[3]].each do |v| - next unless v - # p v - # exit - list << v.diffuse.red - list << v.diffuse.green - list << v.diffuse.blue - # list << v.alpha + material = face.material + next unless material + face.vertices.each do # Add material to each vertex + + list << material.diffuse.red + list << material.diffuse.green + list << material.diffuse.blue + # list << material.alpha end end diff --git a/lib/wavefront/parser.rb b/lib/wavefront/parser.rb index dbf0811..1224361 100644 --- a/lib/wavefront/parser.rb +++ b/lib/wavefront/parser.rb @@ -38,15 +38,27 @@ class IMICFPS norms << f.split("/")[2] end + face = Face.new + face.vertices = [] + face.uvs = [] + face.normals = [] + face.material = material + face.smoothing= @smoothing + verts.each_with_index do |v, index| if uvs.first != "" - face = [@vertices[Integer(v)-1], @uvs[Integer(uvs[index])-1], @normals[Integer(norms[index])-1], material, @smoothing] + face.vertices << @vertices[Integer(v)-1] + face.uvs << @uvs[Integer(uvs[index])-1] + face.normals << @normals[Integer(norms[index])-1] else - face = [@vertices[Integer(v)-1], nil, @normals[Integer(norms[index])-1], material, @smoothing] + face.vertices << @vertices[Integer(v)-1] + face.uvs << nil + face.normals << @normals[Integer(norms[index])-1] end - @current_object.faces << face - @faces << face end + + @current_object.faces << face + @faces << face end end