From 954c6899be2aaa6cf80d500b1d299bf31b3b591b Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Wed, 25 Sep 2019 11:52:19 -0500 Subject: [PATCH] Made model/entity manifest a first class object --- i-mic-fps.rb | 1 + lib/game_objects/entity.rb | 5 ++-- lib/game_objects/model_loader.rb | 20 +++++++-------- lib/manifest.rb | 33 +++++++++++++++++++++++++ lib/states/game_states/game.rb | 8 +++--- lib/states/game_states/loading_state.rb | 3 ++- 6 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 lib/manifest.rb diff --git a/i-mic-fps.rb b/i-mic-fps.rb index f0bb4ce..833d10f 100644 --- a/i-mic-fps.rb +++ b/i-mic-fps.rb @@ -119,6 +119,7 @@ require_relative "lib/game_objects/entities/terrain" require_relative "lib/wavefront/model" require_relative "lib/map" +require_relative "lib/manifest" require_relative "lib/window" diff --git a/lib/game_objects/entity.rb b/lib/game_objects/entity.rb index 5b00e3f..a82f195 100644 --- a/lib/game_objects/entity.rb +++ b/lib/game_objects/entity.rb @@ -9,7 +9,8 @@ class IMICFPS attr_accessor :position, :orientation, :velocity attr_reader :name, :debug_color, :bounding_box, :collision, :physics, :mass, :drag, :camera - def initialize(map_entity: nil, spawnpoint: nil, backface_culling: true, auto_manage: true) + def initialize(manifest:, map_entity: nil, spawnpoint: nil, backface_culling: true, auto_manage: true) + @manifest = manifest @position = map_entity ? map_entity.position : spawnpoint.position @orientation = map_entity ? map_entity.orientation : spawnpoint.orientation @scale = map_entity ? map_entity.scale : 1.0 @@ -56,7 +57,7 @@ class IMICFPS end def bind_model(package, name) - model = ModelLoader.new(manifest_file: IMICFPS.assets_path + "/#{package}/#{name}/manifest.yaml", entity: @dummy_entity) + model = ModelLoader.new(manifest: @manifest, entity: @dummy_entity) raise "model isn't a model!" unless model.is_a?(ModelLoader) @bound_model = model diff --git a/lib/game_objects/model_loader.rb b/lib/game_objects/model_loader.rb index 793d4f7..939ce8b 100644 --- a/lib/game_objects/model_loader.rb +++ b/lib/game_objects/model_loader.rb @@ -8,13 +8,11 @@ class IMICFPS attr_reader :model, :name, :debug_color - def initialize(manifest_file:, entity: nil) - @manifest = YAML.load(File.read(manifest_file)) - # pp @manifest - @file_path = File.expand_path("./../model/", manifest_file) + "/#{@manifest["model"]}" - @name = @manifest["name"] + def initialize(manifest:, entity: nil) + @name = manifest.name + @model_file = model_file = manifest.file_path + "/model/#{manifest.model}" - @type = File.basename(@file_path).split(".").last.to_sym + @type = File.basename(@model_file).split(".").last.to_sym @debug_color = Color.new(0.0, 1.0, 0.0) @model = nil @@ -23,7 +21,7 @@ class IMICFPS unless load_model_from_cache case @type when :obj - @model = Wavefront::Model.new(file_path: @file_path, entity: entity) + @model = Wavefront::Model.new(file_path: @model_file, entity: entity) else raise "Unsupported model type, supported models are: #{@supported_models.join(', ')}" end @@ -38,9 +36,9 @@ class IMICFPS def load_model_from_cache found = false if CACHE[@type].is_a?(Hash) - if CACHE[@type][@file_path] - @model = CACHE[@type][@file_path]#.dup # Don't know why, but adding .dup improves performance with Sponza (1 fps -> 20 fps) - puts "Used cached model for: #{@file_path.split('/').last}" if $debug.get(:stats) + if CACHE[@type][@model_file] + @model = CACHE[@type][@model_file]#.dup # Don't know why, but adding .dup improves performance with Sponza (1 fps -> 20 fps) + puts "Used cached model for: #{@model_file.split('/').last}" if $debug.get(:stats) found = true end end @@ -50,7 +48,7 @@ class IMICFPS def cache_model CACHE[@type] = {} unless CACHE[@type].is_a?(Hash) - CACHE[@type][@file_path] = @model + CACHE[@type][@model_file] = @model end end end diff --git a/lib/manifest.rb b/lib/manifest.rb new file mode 100644 index 0000000..58418df --- /dev/null +++ b/lib/manifest.rb @@ -0,0 +1,33 @@ +class IMICFPS + class Manifest + attr_reader :name, :model, :collision, :collision_mesh, :scripts, :uses + def initialize(manifest_file: nil, package: nil, model: nil) + unless manifest_file + raise "Entity package not specified!" unless package + raise "Entity model not specified!" unless model + manifest_file = "#{IMICFPS.assets_path}/#{package}/#{model}/manifest.yaml" + end + + @file = manifest_file + parse(manifest_file) + end + + def parse(file) + data = YAML.load(File.read(file)) + + # required + @name = data["name"] + @model = data["model"] + + # optional + @collision = data["collision"] ? data["collision"] : nil + @collision_mesh = data["collision_mesh"] ? data["collision_mesh"] : nil + @scripts = data["scripts"] ? data["scripts"] : [] + @uses = data["uses"] ? data["uses"] : [] # List of entities that this Entity uses + end + + def file_path + File.expand_path("./../", @file) + end + end +end \ No newline at end of file diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index d4edd0e..478afd2 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -6,17 +6,17 @@ class IMICFPS @collision_manager = CollisionManager.new(game_state: self) @renderer = Renderer.new(game_state: self) @map = @options[:map] - add_entity(Terrain.new(map_entity: @map.terrain)) + add_entity(Terrain.new(map_entity: @map.terrain, manifest: Manifest.new(package: @map.terrain.package, model: @map.terrain.model))) @draw_skydome = true - @skydome = Skydome.new(map_entity: @map.skydome, backface_culling: false) + @skydome = Skydome.new(map_entity: @map.skydome, manifest: Manifest.new(package: @map.skydome.package, model: @map.skydome.model), backface_culling: false) add_entity(@skydome) @map.entities.each do |ent| - add_entity(Entity.new(map_entity: ent)) + add_entity(Entity.new(map_entity: ent, manifest: Manifest.new(package: ent.package, model: ent.model))) end - @player = Player.new(spawnpoint: @map.spawnpoints.sample) + @player = Player.new(spawnpoint: @map.spawnpoints.sample, manifest: Manifest.new(package: "base", model: "biped")) add_entity(@player) @camera = Camera.new(position: @player.position.clone) @camera.attach_to(@player) diff --git a/lib/states/game_states/loading_state.rb b/lib/states/game_states/loading_state.rb index c031f8c..a932c14 100644 --- a/lib/states/game_states/loading_state.rb +++ b/lib/states/game_states/loading_state.rb @@ -52,7 +52,8 @@ class IMICFPS hash = @assets[@asset_index] case hash[:type] when :model - ModelLoader.new(manifest_file: IMICFPS.assets_path + "/#{hash[:package]}/#{hash[:name]}/manifest.yaml", entity: @dummy_entity) + manifest = Manifest.new(manifest_file: IMICFPS.assets_path + "/#{hash[:package]}/#{hash[:name]}/manifest.yaml") + ModelLoader.new(manifest: manifest, entity: @dummy_entity) when :shader Shader.new(name: hash[:name], vertex: "shaders/vertex/#{hash[:name]}.glsl", fragment: "shaders/fragment/#{hash[:name]}.glsl") else