Class: Engine::GameObject
- Inherits:
-
Object
- Object
- Engine::GameObject
- Defined in:
- lib/engine/game_object.rb
Instance Attribute Summary collapse
-
#components ⇒ Object
Returns the value of attribute components.
-
#created_at ⇒ Object
Returns the value of attribute created_at.
-
#name ⇒ Object
Returns the value of attribute name.
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#pos ⇒ Object
Returns the value of attribute pos.
-
#renderers ⇒ Object
Returns the value of attribute renderers.
-
#scale ⇒ Object
Returns the value of attribute scale.
-
#ui_renderers ⇒ Object
Returns the value of attribute ui_renderers.
Class Method Summary collapse
- .destroy_all ⇒ Object
- .destroyed_objects ⇒ Object
- .erase_destroyed_objects ⇒ Object
- .mesh_renderers ⇒ Object
- .method_added(name) ⇒ Object
- .object_spawned(object) ⇒ Object
- .objects ⇒ Object
- .render_ui(delta_time) ⇒ Object
- .update_all(delta_time) ⇒ Object
Instance Method Summary collapse
- #_erase! ⇒ Object
- #add_child(child) ⇒ Object
- #children ⇒ Object
- #destroy! ⇒ Object
- #destroyed? ⇒ Boolean
- #euler_angles ⇒ Object
- #forward ⇒ Object
-
#initialize(name = "Game Object", pos: Vector[0, 0, 0], rotation: 0, scale: Vector[1, 1, 1], components: [], parent: nil) ⇒ GameObject
constructor
A new instance of GameObject.
- #local_to_world_coordinate(local) ⇒ Object
- #local_to_world_direction(local) ⇒ Object
- #model_matrix ⇒ Object
- #right ⇒ Object
- #rotate_around(axis, angle) ⇒ Object
- #rotation ⇒ Object
- #rotation=(value) ⇒ Object
- #to_s ⇒ Object
- #up ⇒ Object
- #world_to_local_coordinate(world) ⇒ Object
- #x ⇒ Object
- #x=(value) ⇒ Object
- #y ⇒ Object
- #y=(value) ⇒ Object
- #z ⇒ Object
- #z=(value) ⇒ Object
Constructor Details
#initialize(name = "Game Object", pos: Vector[0, 0, 0], rotation: 0, scale: Vector[1, 1, 1], components: [], parent: nil) ⇒ GameObject
Returns a new instance of GameObject.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/engine/game_object.rb', line 13 def initialize(name = "Game Object", pos: Vector[0, 0, 0], rotation: 0, scale: Vector[1, 1, 1], components: [], parent: nil) GameObject.object_spawned(self) @pos = Vector[pos[0], pos[1], pos[2] || 0] if rotation.is_a?(Numeric) self.rotation = Quaternion.from_euler(Vector[0, 0, rotation]) elsif rotation.is_a?(Quaternion) self.rotation = rotation else self.rotation = Quaternion.from_euler(rotation) end @scale = scale @name = name @components = components.select { |component| !component.renderer? && !component.ui_renderer? } @renderers = components.select { |component| component.renderer? } @ui_renderers = components.select { |component| component.ui_renderer? } @created_at = Time.now @parent = parent parent.add_child(self) if parent components.each { |component| component.set_game_object(self) } components.each(&:start) end |
Instance Attribute Details
#components ⇒ Object
Returns the value of attribute components.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def components @components end |
#created_at ⇒ Object
Returns the value of attribute created_at.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def created_at @created_at end |
#name ⇒ Object
Returns the value of attribute name.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def name @name end |
#parent ⇒ Object
Returns the value of attribute parent.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def parent @parent end |
#pos ⇒ Object
Returns the value of attribute pos.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def pos @pos end |
#renderers ⇒ Object
Returns the value of attribute renderers.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def renderers @renderers end |
#scale ⇒ Object
Returns the value of attribute scale.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def scale @scale end |
#ui_renderers ⇒ Object
Returns the value of attribute ui_renderers.
11 12 13 |
# File 'lib/engine/game_object.rb', line 11 def ui_renderers @ui_renderers end |
Class Method Details
.destroy_all ⇒ Object
195 196 197 198 199 |
# File 'lib/engine/game_object.rb', line 195 def self.destroy_all GameObject.objects.dup.each do |object| object.destroy! unless object.destroyed? end end |
.destroyed_objects ⇒ Object
230 231 232 |
# File 'lib/engine/game_object.rb', line 230 def self.destroyed_objects @destroyed_objects ||= [] end |
.erase_destroyed_objects ⇒ Object
170 171 172 173 174 175 |
# File 'lib/engine/game_object.rb', line 170 def self.erase_destroyed_objects destroyed_objects.each do |object| object._erase! end @destroyed_objects = [] end |
.mesh_renderers ⇒ Object
210 211 212 213 214 |
# File 'lib/engine/game_object.rb', line 210 def self.mesh_renderers GameObject.objects.flat_map do |object| object.renderers end end |
.method_added(name) ⇒ Object
5 6 7 8 9 |
# File 'lib/engine/game_object.rb', line 5 def self.method_added(name) @methods ||= Set.new return if name == :initialize || name == :destroyed? @methods.add(name) end |
.object_spawned(object) ⇒ Object
222 223 224 |
# File 'lib/engine/game_object.rb', line 222 def self.object_spawned(object) objects << object end |
.objects ⇒ Object
226 227 228 |
# File 'lib/engine/game_object.rb', line 226 def self.objects @objects ||= [] end |
.render_ui(delta_time) ⇒ Object
216 217 218 219 220 |
# File 'lib/engine/game_object.rb', line 216 def self.render_ui(delta_time) GameObject.objects.each do |object| object.ui_renderers.each { |renderer| renderer.update(delta_time) } end end |
.update_all(delta_time) ⇒ Object
201 202 203 204 205 206 207 208 |
# File 'lib/engine/game_object.rb', line 201 def self.update_all(delta_time) GameObject.objects.each do |object| object.components.each { |component| component.update(delta_time) } end Component.erase_destroyed_components GameObject.erase_destroyed_objects end |
Instance Method Details
#_erase! ⇒ Object
160 161 162 163 164 165 166 167 168 |
# File 'lib/engine/game_object.rb', line 160 def _erase! GameObject.objects.delete(self) parent.children.delete(self) if parent name = @name self.class.instance_variable_get(:@methods).each do |method| singleton_class.send(:undef_method, method) singleton_class.send(:define_method, method) { raise "This object has been destroyed: #{name}" } end end |
#add_child(child) ⇒ Object
44 45 46 47 |
# File 'lib/engine/game_object.rb', line 44 def add_child(child) child.parent = self children << child end |
#children ⇒ Object
40 41 42 |
# File 'lib/engine/game_object.rb', line 40 def children @children ||= Set.new end |
#destroy! ⇒ Object
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/engine/game_object.rb', line 149 def destroy! return unless GameObject.objects.include?(self) children.each(&:destroy!) components.each(&:destroy!) ui_renderers.each(&:destroy!) renderers.each(&:destroy!) GameObject.destroyed_objects << self unless @destroyed @destroyed = true end |
#destroyed? ⇒ Boolean
145 146 147 |
# File 'lib/engine/game_object.rb', line 145 def destroyed? @destroyed end |
#euler_angles ⇒ Object
65 66 67 |
# File 'lib/engine/game_object.rb', line 65 def euler_angles rotation.to_euler end |
#forward ⇒ Object
189 190 191 192 193 |
# File 'lib/engine/game_object.rb', line 189 def forward return @forward if @cached_forward_rotation == rotation @cached_forward_rotation = rotation.dup @forward = local_to_world_direction(Vector[0, 0, 1]) end |
#local_to_world_coordinate(local) ⇒ Object
93 94 95 96 97 |
# File 'lib/engine/game_object.rb', line 93 def local_to_world_coordinate(local) local_x4 = Matrix[[local[0], local[1], local[2], 1.0]] world = local_x4 * model_matrix Vector[world[0, 0], world[0, 1], world[0, 2]] end |
#local_to_world_direction(local) ⇒ Object
105 106 107 |
# File 'lib/engine/game_object.rb', line 105 def local_to_world_direction(local) local_to_world_coordinate(local) - pos end |
#model_matrix ⇒ Object
115 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 |
# File 'lib/engine/game_object.rb', line 115 def model_matrix cache_key = [@pos.dup, rotation.dup, @scale.dup, @parent&.model_matrix&.to_a] @model_matrix = nil if @model_matrix_cache_key != cache_key @model_matrix_cache_key = cache_key @model_matrix ||= begin rot = euler_angles * Math::PI / 180 cos_x = Math.cos(rot[0]) cos_y = Math.cos(rot[1]) cos_z = Math.cos(rot[2]) sin_x = Math.sin(rot[0]) sin_y = Math.sin(rot[1]) sin_z = Math.sin(rot[2]) Matrix[ [scale[0] * (cos_y * cos_z), scale[0] * (-cos_y * sin_z), scale[0] * sin_y, 0], [scale[1] * (cos_x * sin_z + sin_x * sin_y * cos_z), scale[1] * (cos_x * cos_z - sin_x * sin_y * sin_z), scale[1] * -sin_x * cos_y, 0], [scale[2] * (sin_x * sin_z - cos_x * sin_y * cos_z), scale[2] * (sin_x * cos_z + cos_x * sin_y * sin_z), scale[2] * cos_x * cos_y, 0], [x, y, z, 1] ] end if parent @model_matrix * parent.model_matrix else @model_matrix end end |
#right ⇒ Object
183 184 185 186 187 |
# File 'lib/engine/game_object.rb', line 183 def right return @right if @cached_right_rotation == rotation @cached_right_rotation = rotation.dup @right = local_to_world_direction(Vector[1, 0, 0]) end |
#rotate_around(axis, angle) ⇒ Object
109 110 111 112 113 |
# File 'lib/engine/game_object.rb', line 109 def rotate_around(axis, angle) rotation_quaternion = Quaternion.from_angle_axis(angle, axis) self.rotation = rotation_quaternion * rotation end |
#rotation ⇒ Object
55 56 57 |
# File 'lib/engine/game_object.rb', line 55 def rotation @rotation_quaternion end |
#rotation=(value) ⇒ Object
59 60 61 62 63 |
# File 'lib/engine/game_object.rb', line 59 def rotation=(value) raise "Rotation must be a Quaternion" unless value.is_a?(Quaternion) @rotation_quaternion = value end |
#to_s ⇒ Object
36 37 38 |
# File 'lib/engine/game_object.rb', line 36 def to_s @name end |
#up ⇒ Object
177 178 179 180 181 |
# File 'lib/engine/game_object.rb', line 177 def up return @up if @cached_up_rotation == rotation @cached_up_rotation = rotation.dup @up = local_to_world_direction(Vector[0, 1, 0]) end |
#world_to_local_coordinate(world) ⇒ Object
99 100 101 102 103 |
# File 'lib/engine/game_object.rb', line 99 def world_to_local_coordinate(world) world_x4 = Matrix[[world[0], world[1], world[2], 1.0]] local = world_x4 * model_matrix.inverse Vector[local[0, 0], local[0, 1], local[0, 2]] end |
#x ⇒ Object
69 70 71 |
# File 'lib/engine/game_object.rb', line 69 def x @pos[0] end |
#x=(value) ⇒ Object
73 74 75 |
# File 'lib/engine/game_object.rb', line 73 def x=(value) @pos = Vector[value, y, z] end |
#y ⇒ Object
77 78 79 |
# File 'lib/engine/game_object.rb', line 77 def y @pos[1] end |
#y=(value) ⇒ Object
81 82 83 |
# File 'lib/engine/game_object.rb', line 81 def y=(value) @pos = Vector[x, value, z] end |
#z ⇒ Object
85 86 87 |
# File 'lib/engine/game_object.rb', line 85 def z @pos[2] end |
#z=(value) ⇒ Object
89 90 91 |
# File 'lib/engine/game_object.rb', line 89 def z=(value) @pos = Vector[x, y, value] end |