Class: CyberarmEngine::Model
- Inherits:
-
Object
- Object
- CyberarmEngine::Model
- Includes:
- CyberarmEngine, OpenGL
- Defined in:
- lib/cyberarm_engine/model.rb,
lib/cyberarm_engine/model/mesh.rb,
lib/cyberarm_engine/model/parser.rb,
lib/cyberarm_engine/model/material.rb
Defined Under Namespace
Classes: Material, Mesh, Parser
Constant Summary
Constants included from CyberarmEngine
Instance Attribute Summary collapse
-
#aabb_tree ⇒ Object
readonly
Returns the value of attribute aabb_tree.
-
#bones ⇒ Object
Returns the value of attribute bones.
-
#bounding_box ⇒ Object
readonly
Returns the value of attribute bounding_box.
-
#colors ⇒ Object
Returns the value of attribute colors.
-
#colors_buffer_id ⇒ Object
readonly
Returns the value of attribute colors_buffer_id.
-
#current_material ⇒ Object
Returns the value of attribute current_material.
-
#current_object ⇒ Object
Returns the value of attribute current_object.
-
#faces ⇒ Object
Returns the value of attribute faces.
-
#file_path ⇒ Object
readonly
Returns the value of attribute file_path.
-
#material_file ⇒ Object
Returns the value of attribute material_file.
-
#materials ⇒ Object
Returns the value of attribute materials.
-
#normals ⇒ Object
Returns the value of attribute normals.
-
#normals_buffer_id ⇒ Object
readonly
Returns the value of attribute normals_buffer_id.
-
#objects ⇒ Object
Returns the value of attribute objects.
-
#position ⇒ Object
readonly
Returns the value of attribute position.
-
#positions_buffer_id ⇒ Object
readonly
Returns the value of attribute positions_buffer_id.
-
#smoothing ⇒ Object
Returns the value of attribute smoothing.
-
#textured_material ⇒ Object
readonly
Returns the value of attribute textured_material.
-
#textures_buffer_id ⇒ Object
readonly
Returns the value of attribute textures_buffer_id.
-
#texures ⇒ Object
Returns the value of attribute texures.
-
#uvs ⇒ Object
Returns the value of attribute uvs.
-
#uvs_buffer_id ⇒ Object
readonly
Returns the value of attribute uvs_buffer_id.
-
#vertex_array_id ⇒ Object
readonly
Returns the value of attribute vertex_array_id.
-
#vertex_count ⇒ Object
Returns the value of attribute vertex_count.
-
#vertices ⇒ Object
Returns the value of attribute vertices.
-
#vertices_count ⇒ Object
readonly
Returns the value of attribute vertices_count.
Instance Method Summary collapse
- #allocate_gl_objects ⇒ Object
- #build_collision_tree ⇒ Object
- #calculate_bounding_box(vertices, bounding_box) ⇒ Object
- #configure_vao ⇒ Object
- #has_texture? ⇒ Boolean
-
#initialize(file_path:) ⇒ Model
constructor
A new instance of Model.
- #parse(parser) ⇒ Object
- #populate_vertex_buffer ⇒ Object
- #release_gl_resources ⇒ Object
Methods included from CyberarmEngine
#gl_error?, #preload_default_shaders
Constructor Details
#initialize(file_path:) ⇒ Model
Returns a new instance of Model.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/cyberarm_engine/model.rb', line 12 def initialize(file_path:) @file_path = file_path @material_file = nil @current_object = nil @current_material = nil @vertex_count = 0 @objects = [] @materials = {} @vertices = [] @colors = [] @uvs = [] @normals = [] @faces = [] @bones = [] @smoothing = 0 @vertices_count = 0 @bounding_box = BoundingBox.new start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) type = File.basename(file_path).split(".").last.to_sym parser = Model::Parser.find(type) raise "Unsupported model type '.#{type}', supported models are: #{Model::Parser.supported_formats}" unless parser parse(parser) @vertices_count = @vertices.size @has_texture = false @materials.each do |_key, material| @has_texture = true if material.texture_id end allocate_gl_objects populate_vertex_buffer configure_vao @objects.each { |o| @vertex_count += o.vertices.size } start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) build_collision_tree puts " Building mesh collision tree took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) - start_time) / 1000.0).round(2)} seconds" end |
Instance Attribute Details
#aabb_tree ⇒ Object (readonly)
Returns the value of attribute aabb_tree.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def aabb_tree @aabb_tree end |
#bones ⇒ Object
Returns the value of attribute bones.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def bones @bones end |
#bounding_box ⇒ Object (readonly)
Returns the value of attribute bounding_box.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def bounding_box @bounding_box end |
#colors ⇒ Object
Returns the value of attribute colors.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def colors @colors end |
#colors_buffer_id ⇒ Object (readonly)
Returns the value of attribute colors_buffer_id.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def colors_buffer_id @colors_buffer_id end |
#current_material ⇒ Object
Returns the value of attribute current_material.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def current_material @current_material end |
#current_object ⇒ Object
Returns the value of attribute current_object.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def current_object @current_object end |
#faces ⇒ Object
Returns the value of attribute faces.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def faces @faces end |
#file_path ⇒ Object (readonly)
Returns the value of attribute file_path.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def file_path @file_path end |
#material_file ⇒ Object
Returns the value of attribute material_file.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def material_file @material_file end |
#materials ⇒ Object
Returns the value of attribute materials.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def materials @materials end |
#normals ⇒ Object
Returns the value of attribute normals.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def normals @normals end |
#normals_buffer_id ⇒ Object (readonly)
Returns the value of attribute normals_buffer_id.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def normals_buffer_id @normals_buffer_id end |
#objects ⇒ Object
Returns the value of attribute objects.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def objects @objects end |
#position ⇒ Object (readonly)
Returns the value of attribute position.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def position @position end |
#positions_buffer_id ⇒ Object (readonly)
Returns the value of attribute positions_buffer_id.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def positions_buffer_id @positions_buffer_id end |
#smoothing ⇒ Object
Returns the value of attribute smoothing.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def smoothing @smoothing end |
#textured_material ⇒ Object (readonly)
Returns the value of attribute textured_material.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def textured_material @textured_material end |
#textures_buffer_id ⇒ Object (readonly)
Returns the value of attribute textures_buffer_id.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def textures_buffer_id @textures_buffer_id end |
#texures ⇒ Object
Returns the value of attribute texures.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def texures @texures end |
#uvs ⇒ Object
Returns the value of attribute uvs.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def uvs @uvs end |
#uvs_buffer_id ⇒ Object (readonly)
Returns the value of attribute uvs_buffer_id.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def uvs_buffer_id @uvs_buffer_id end |
#vertex_array_id ⇒ Object (readonly)
Returns the value of attribute vertex_array_id.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def vertex_array_id @vertex_array_id end |
#vertex_count ⇒ Object
Returns the value of attribute vertex_count.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def vertex_count @vertex_count end |
#vertices ⇒ Object
Returns the value of attribute vertices.
6 7 8 |
# File 'lib/cyberarm_engine/model.rb', line 6 def vertices @vertices end |
#vertices_count ⇒ Object (readonly)
Returns the value of attribute vertices_count.
8 9 10 |
# File 'lib/cyberarm_engine/model.rb', line 8 def vertices_count @vertices_count end |
Instance Method Details
#allocate_gl_objects ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/cyberarm_engine/model.rb', line 87 def allocate_gl_objects # Allocate arrays for future use @vertex_array_id = nil buffer = " " * 4 glGenVertexArrays(1, buffer) @vertex_array_id = buffer.unpack1("L2") # Allocate buffers for future use @positions_buffer_id = nil buffer = " " * 4 glGenBuffers(1, buffer) @positions_buffer_id = buffer.unpack1("L2") @colors_buffer_id = nil buffer = " " * 4 glGenBuffers(1, buffer) @colors_buffer_id = buffer.unpack1("L2") @normals_buffer_id = nil buffer = " " * 4 glGenBuffers(1, buffer) @normals_buffer_id = buffer.unpack1("L2") @uvs_buffer_id = nil buffer = " " * 4 glGenBuffers(1, buffer) @uvs_buffer_id = buffer.unpack1("L2") end |
#build_collision_tree ⇒ Object
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/cyberarm_engine/model.rb', line 183 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 *= 1.5 box.max *= 1.5 @aabb_tree.insert(face, box) end end |
#calculate_bounding_box(vertices, bounding_box) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/cyberarm_engine/model.rb', line 64 def calculate_bounding_box(vertices, bounding_box) unless bounding_box.min.x.is_a?(Float) vertex = vertices.last bounding_box.min.x = vertex.x bounding_box.min.y = vertex.y bounding_box.min.z = vertex.z bounding_box.max.x = vertex.x bounding_box.max.y = vertex.y bounding_box.max.z = vertex.z end vertices.each do |vertex| bounding_box.min.x = vertex.x if vertex.x <= bounding_box.min.x bounding_box.min.y = vertex.y if vertex.y <= bounding_box.min.y bounding_box.min.z = vertex.z if vertex.z <= bounding_box.min.z bounding_box.max.x = vertex.x if vertex.x >= bounding_box.max.x bounding_box.max.y = vertex.y if vertex.y >= bounding_box.max.y bounding_box.max.z = vertex.z if vertex.z >= bounding_box.max.z end end |
#configure_vao ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/cyberarm_engine/model.rb', line 148 def configure_vao glBindVertexArray(@vertex_array_id) gl_error? # index, size, type, normalized, stride, pointer # vertices (positions) glBindBuffer(GL_ARRAY_BUFFER, @positions_buffer_id) gl_error? # in_position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nil) gl_error? # colors glBindBuffer(GL_ARRAY_BUFFER, @colors_buffer_id) # in_color glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nil) gl_error? # normals glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id) # in_normal glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, nil) gl_error? if has_texture? # uvs glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id) # in_uv glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, nil) gl_error? end glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) end |
#has_texture? ⇒ Boolean
206 207 208 |
# File 'lib/cyberarm_engine/model.rb', line 206 def has_texture? @has_texture end |
#parse(parser) ⇒ Object
60 61 62 |
# File 'lib/cyberarm_engine/model.rb', line 60 def parse(parser) parser.new(self).parse end |
#populate_vertex_buffer ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/cyberarm_engine/model.rb', line 116 def populate_vertex_buffer pos = [] colors = [] norms = [] uvs = [] @faces.each do |face| pos << face.vertices.map { |vert| [vert.x, vert.y, vert.z] } colors << face.colors.map { |color| [color.red, color.green, color.blue] } norms << face.normals.map { |vert| [vert.x, vert.y, vert.z, vert.weight] } uvs << face.uvs.map { |vert| [vert.x, vert.y, vert.z] } if has_texture? end glBindBuffer(GL_ARRAY_BUFFER, @positions_buffer_id) glBufferData(GL_ARRAY_BUFFER, pos.flatten.size * Fiddle::SIZEOF_FLOAT, pos.flatten.pack("f*"), GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, @colors_buffer_id) glBufferData(GL_ARRAY_BUFFER, colors.flatten.size * Fiddle::SIZEOF_FLOAT, colors.flatten.pack("f*"), GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, @normals_buffer_id) glBufferData(GL_ARRAY_BUFFER, norms.flatten.size * Fiddle::SIZEOF_FLOAT, norms.flatten.pack("f*"), GL_STATIC_DRAW) if has_texture? glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id) glBufferData(GL_ARRAY_BUFFER, uvs.flatten.size * Fiddle::SIZEOF_FLOAT, uvs.flatten.pack("f*"), GL_STATIC_DRAW) end glBindBuffer(GL_ARRAY_BUFFER, 0) end |
#release_gl_resources ⇒ Object
210 211 212 213 214 |
# File 'lib/cyberarm_engine/model.rb', line 210 def release_gl_resources if @vertex_array_id end end |