mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-16 08:02:36 +00:00
Various tweaks
This commit is contained in:
@@ -27,10 +27,8 @@ class IMICFPS
|
|||||||
|
|
||||||
@physics_manager.update
|
@physics_manager.update
|
||||||
|
|
||||||
# binding.irb
|
|
||||||
# p @aabb_tree
|
|
||||||
collisions.each do |ent, list|
|
collisions.each do |ent, list|
|
||||||
# puts "#{ent.class} -> [#{list.map{|e| e.class}.join(', ')}]"
|
# puts "#{ent.class} -> [#{list.map{|e| e.class}.join(', ')}] (#{Gosu.milliseconds})"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -39,6 +37,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_broadphase
|
def check_broadphase
|
||||||
|
# FIXME: Cache collisions to speed things up
|
||||||
@collisions.clear
|
@collisions.clear
|
||||||
broadphase = {}
|
broadphase = {}
|
||||||
|
|
||||||
@@ -54,13 +53,33 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
broadphase.each do |entity, _collisions|
|
broadphase.each do |entity, _collisions|
|
||||||
_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|
|
_collisions.each do |ent|
|
||||||
|
# aabb vs aabb
|
||||||
|
next unless entity.bounding_box.intersect?(ent.bounding_box)
|
||||||
|
# entity model aabb tree vs ent model aabb tree
|
||||||
|
# ent_tree_search = ent.model.aabb_tree.search(localize_entity_bounding_box(entity, ent), true)
|
||||||
|
# next if ent_tree_search.size == 0
|
||||||
|
|
||||||
|
# puts "#{ent.class} -> #{ent_tree_search.size} (#{Gosu.milliseconds})"
|
||||||
|
|
||||||
|
# entity.position.y = ent_tree_search.first.object.vertices.first.y if entity.is_a?(Player) && ent.is_a?(Terrain)
|
||||||
|
|
||||||
@collisions[entity] = _collisions
|
@collisions[entity] = _collisions
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# AABBTree on entities is relative to model origin of 0,0,0
|
||||||
|
def localize_entity_bounding_box(entity, target)
|
||||||
|
return entity.bounding_box if target.position == 0 && target.rotation == 0
|
||||||
|
|
||||||
|
# "tranform" entity bounding box into target's space
|
||||||
|
local = (target.position) # needs tweaking, works well enough for now
|
||||||
|
box = entity.bounding_box.clone
|
||||||
|
box.min -= local
|
||||||
|
box.max -= local
|
||||||
|
|
||||||
|
return box
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ class IMICFPS
|
|||||||
class BoundingBox
|
class BoundingBox
|
||||||
attr_accessor :min, :max
|
attr_accessor :min, :max
|
||||||
|
|
||||||
def initialize
|
def initialize(minx = 0, miny = 0, minz = 0, maxx = 0, maxy = 0, maxz = 0)
|
||||||
@min = Vector.new
|
@min = Vector.new(minx, miny, minz)
|
||||||
@max = Vector.new
|
@max = Vector.new(maxx, maxy, maxz)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ==(other)
|
def ==(other)
|
||||||
@@ -116,5 +116,9 @@ class IMICFPS
|
|||||||
def sum
|
def sum
|
||||||
@min.sum + @max.sum
|
@min.sum + @max.sum
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def clone
|
||||||
|
BoundingBox.new(@min.x, @min.y, @min.z, @max.x, @max.y, @max.z)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -22,10 +22,17 @@ class IMICFPS
|
|||||||
# def xyzw=(nx, ny, nz, nw); @x = nx; @y = ny; @z = nz; @weight = nw; end
|
# def xyzw=(nx, ny, nz, nw); @x = nx; @y = ny; @z = nz; @weight = nw; end
|
||||||
|
|
||||||
def ==(other)
|
def ==(other)
|
||||||
@x == other.x &&
|
if other.is_a?(Numeric)
|
||||||
@y == other.y &&
|
@x == other &&
|
||||||
@z == other.z &&
|
@y == other &&
|
||||||
@weight == other.weight
|
@z == other &&
|
||||||
|
@weight == other
|
||||||
|
else
|
||||||
|
@x == other.x &&
|
||||||
|
@y == other.y &&
|
||||||
|
@z == other.z &&
|
||||||
|
@weight == other.weight
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def +(other)
|
def +(other)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ class IMICFPS
|
|||||||
class TestObject < Entity
|
class TestObject < Entity
|
||||||
def setup
|
def setup
|
||||||
bind_model("base", "war_factory")
|
bind_model("base", "war_factory")
|
||||||
|
@backface_culling = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ class IMICFPS
|
|||||||
include GLU
|
include GLU
|
||||||
include CommonMethods
|
include CommonMethods
|
||||||
attr_accessor :scale, :visible, :renderable, :backface_culling
|
attr_accessor :scale, :visible, :renderable, :backface_culling
|
||||||
attr_reader :position, :rotation, :velocity, :collision
|
attr_accessor :position, :rotation, :velocity
|
||||||
attr_reader :model, :name, :debug_color, :bounding_box
|
attr_reader :model, :name, :debug_color, :bounding_box, :collision
|
||||||
def initialize(x: 0, y: 0, z: 0, bound_model: nil, scale: MODEL_METER_SCALE, backface_culling: true, auto_manage: true, manifest_file: nil)
|
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)
|
@position = Vector.new(x, y, z)
|
||||||
@scale = scale
|
@scale = scale
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ class IMICFPS
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@bounding_boxes[mesh_object_id] = {}
|
|
||||||
@bounding_boxes[mesh_object_id] = {object: object, box: box, color: color, objects: []}
|
@bounding_boxes[mesh_object_id] = {object: object, box: box, color: color, objects: []}
|
||||||
|
|
||||||
box = object.normalize_bounding_box
|
box = object.normalize_bounding_box
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class IMICFPS
|
|||||||
glEnableClientState(GL_VERTEX_ARRAY)
|
glEnableClientState(GL_VERTEX_ARRAY)
|
||||||
glEnableClientState(GL_COLOR_ARRAY)
|
glEnableClientState(GL_COLOR_ARRAY)
|
||||||
glEnableClientState(GL_NORMAL_ARRAY)
|
glEnableClientState(GL_NORMAL_ARRAY)
|
||||||
if model.model_has_texture
|
if model.has_texture?
|
||||||
glEnable(GL_TEXTURE_2D)
|
glEnable(GL_TEXTURE_2D)
|
||||||
glBindTexture(GL_TEXTURE_2D, model.materials[model.textured_material].texture_id)
|
glBindTexture(GL_TEXTURE_2D, model.materials[model.textured_material].texture_id)
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||||
@@ -96,7 +96,7 @@ class IMICFPS
|
|||||||
glDisableClientState(GL_VERTEX_ARRAY)
|
glDisableClientState(GL_VERTEX_ARRAY)
|
||||||
glDisableClientState(GL_COLOR_ARRAY)
|
glDisableClientState(GL_COLOR_ARRAY)
|
||||||
glDisableClientState(GL_NORMAL_ARRAY)
|
glDisableClientState(GL_NORMAL_ARRAY)
|
||||||
if model.model_has_texture
|
if model.has_texture?
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||||
# glBindTexture(GL_TEXTURE_2D, 0)
|
# glBindTexture(GL_TEXTURE_2D, 0)
|
||||||
glDisable(GL_TEXTURE_2D)
|
glDisable(GL_TEXTURE_2D)
|
||||||
|
|||||||
@@ -36,11 +36,11 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Returns a list of all collided objects inside Bounding Box
|
# Returns a list of all collided objects inside Bounding Box
|
||||||
def search(bounding_box)
|
def search(bounding_box, return_nodes = false)
|
||||||
items = []
|
items = []
|
||||||
if @root
|
if @root
|
||||||
items = @root.search_subtree(bounding_box)
|
items = @root.search_subtree(bounding_box)
|
||||||
items.map! {|e| e.object}
|
items.map! {|e| e.object} unless return_nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ class IMICFPS
|
|||||||
|
|
||||||
attr_accessor :objects, :materials, :vertices, :texures, :normals, :faces
|
attr_accessor :objects, :materials, :vertices, :texures, :normals, :faces
|
||||||
attr_accessor :scale, :entity
|
attr_accessor :scale, :entity
|
||||||
attr_reader :position, :bounding_box, :model_has_texture, :textured_material
|
attr_reader :position, :bounding_box, :textured_material
|
||||||
|
|
||||||
attr_reader :normals_buffer, :uvs_buffer, :vertices_buffer
|
attr_reader :normals_buffer, :uvs_buffer, :vertices_buffer
|
||||||
attr_reader :vertices_buffer_data, :uvs_buffer_data, :normals_buffer_data
|
attr_reader :vertices_buffer_data, :uvs_buffer_data, :normals_buffer_data
|
||||||
attr_reader :vertex_array_id
|
attr_reader :vertex_array_id
|
||||||
|
attr_reader :aabb_tree
|
||||||
|
|
||||||
def initialize(file_path:, entity: nil)
|
def initialize(file_path:, entity: nil)
|
||||||
@entity = entity
|
@entity = entity
|
||||||
@@ -42,39 +43,24 @@ class IMICFPS
|
|||||||
|
|
||||||
puts "#{@file_path.split('/').last} took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)-start_time)/1000.0).round(2)} seconds to parse" if $debug
|
puts "#{@file_path.split('/').last} took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)-start_time)/1000.0).round(2)} seconds to parse" if $debug
|
||||||
|
|
||||||
allocate_gl_objects
|
# allocate_gl_objects
|
||||||
populate_buffers
|
# populate_buffers
|
||||||
populate_arrays
|
# populate_arrays
|
||||||
|
|
||||||
@objects.each {|o| @vertex_count+=o.vertices.size}
|
@objects.each {|o| @vertex_count+=o.vertices.size}
|
||||||
@objects.each_with_index do |o, i|
|
@objects.each_with_index do |o, i|
|
||||||
puts " Model::Object Name: #{o.name}, Vertices: #{o.vertices.size}" if $debug
|
puts " Model::Object Name: #{o.name}, Vertices: #{o.vertices.size}" if $debug
|
||||||
end
|
end
|
||||||
window.number_of_vertices+=@vertex_count
|
window.number_of_vertices+=@vertex_count
|
||||||
@model_has_texture = false
|
@has_texture = false
|
||||||
@materials.each do |key, material|
|
@materials.each do |key, material|
|
||||||
if material.texture_id
|
if material.texture_id
|
||||||
@model_has_texture = true
|
@has_texture = true
|
||||||
@textured_material = key
|
@textured_material = key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@aabb_tree = AABBTree.new
|
build_collision_tree
|
||||||
@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
|
end
|
||||||
|
|
||||||
def allocate_gl_objects
|
def allocate_gl_objects
|
||||||
@@ -124,13 +110,36 @@ class IMICFPS
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def build_collision_tree
|
||||||
|
@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
|
||||||
|
|
||||||
|
# FIXME: Handle negatives
|
||||||
|
box.min -= Vector.new(-0.1, -0.1, -0.1)
|
||||||
|
box.max += Vector.new( 0.1, 0.1, 0.1)
|
||||||
|
@aabb_tree.insert(face, box)
|
||||||
|
end
|
||||||
|
puts @aabb_tree.inspect if $debug
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@position = @entity.position
|
@position = @entity.position
|
||||||
@scale = @entity.scale
|
@scale = @entity.scale
|
||||||
# if @scale != @entity.scale
|
end
|
||||||
# puts "oops for #{self}: #{@scale} != #{@entity.scale}"
|
|
||||||
# self.objects.each(&:reflatten) if self.objects && self.objects.count > 0
|
def has_texture?
|
||||||
# end
|
@has_texture
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user