cyberarm_engine 0.13.1 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -1
  4. data/README.md +1 -1
  5. data/Rakefile +1 -1
  6. data/assets/textures/default.png +0 -0
  7. data/cyberarm_engine.gemspec +12 -9
  8. data/lib/cyberarm_engine.rb +20 -5
  9. data/lib/cyberarm_engine/animator.rb +6 -4
  10. data/lib/cyberarm_engine/background.rb +19 -15
  11. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  12. data/lib/cyberarm_engine/bounding_box.rb +18 -18
  13. data/lib/cyberarm_engine/cache.rb +4 -0
  14. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  15. data/lib/cyberarm_engine/common.rb +16 -16
  16. data/lib/cyberarm_engine/config_file.rb +2 -2
  17. data/lib/cyberarm_engine/game_object.rb +63 -72
  18. data/lib/cyberarm_engine/game_state.rb +6 -3
  19. data/lib/cyberarm_engine/model.rb +207 -0
  20. data/lib/cyberarm_engine/model/material.rb +21 -0
  21. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  22. data/lib/cyberarm_engine/model/parser.rb +74 -0
  23. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  24. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  25. data/lib/cyberarm_engine/model_cache.rb +31 -0
  26. data/lib/cyberarm_engine/opengl.rb +28 -0
  27. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  28. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  29. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  30. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  31. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  32. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  33. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  34. data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
  35. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  36. data/lib/cyberarm_engine/ray.rb +5 -5
  37. data/lib/cyberarm_engine/stats.rb +21 -0
  38. data/lib/cyberarm_engine/text.rb +45 -31
  39. data/lib/cyberarm_engine/timer.rb +1 -1
  40. data/lib/cyberarm_engine/transform.rb +43 -20
  41. data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
  42. data/lib/cyberarm_engine/ui/dsl.rb +49 -10
  43. data/lib/cyberarm_engine/ui/element.rb +73 -21
  44. data/lib/cyberarm_engine/ui/elements/button.rb +121 -28
  45. data/lib/cyberarm_engine/ui/elements/check_box.rb +25 -33
  46. data/lib/cyberarm_engine/ui/elements/container.rb +113 -33
  47. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -0
  48. data/lib/cyberarm_engine/ui/elements/edit_line.rb +145 -45
  49. data/lib/cyberarm_engine/ui/elements/flow.rb +1 -3
  50. data/lib/cyberarm_engine/ui/elements/image.rb +32 -12
  51. data/lib/cyberarm_engine/ui/elements/label.rb +122 -16
  52. data/lib/cyberarm_engine/ui/elements/list_box.rb +82 -0
  53. data/lib/cyberarm_engine/ui/elements/progress.rb +6 -5
  54. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -0
  55. data/lib/cyberarm_engine/ui/elements/slider.rb +104 -0
  56. data/lib/cyberarm_engine/ui/elements/stack.rb +1 -3
  57. data/lib/cyberarm_engine/ui/elements/text_block.rb +156 -0
  58. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +40 -31
  59. data/lib/cyberarm_engine/ui/event.rb +7 -7
  60. data/lib/cyberarm_engine/ui/gui_state.rb +118 -6
  61. data/lib/cyberarm_engine/ui/style.rb +10 -9
  62. data/lib/cyberarm_engine/ui/theme.rb +84 -22
  63. data/lib/cyberarm_engine/vector.rb +33 -30
  64. data/lib/cyberarm_engine/version.rb +2 -2
  65. data/lib/cyberarm_engine/{engine.rb → window.rb} +32 -19
  66. metadata +87 -18
  67. data/lib/cyberarm_engine/gosu_ext/circle.rb +0 -9
@@ -0,0 +1,69 @@
1
+ module CyberarmEngine
2
+ class Texture
3
+ DEFAULT_TEXTURE = "#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/default.png".freeze
4
+
5
+ CACHE = {}
6
+
7
+ def self.release_textures
8
+ CACHE.values.each do |id|
9
+ glDeleteTextures(id)
10
+ end
11
+ end
12
+
13
+ def self.from_cache(path, retro)
14
+ CACHE.dig("#{path}?retro=#{retro}")
15
+ end
16
+
17
+ attr_reader :id
18
+
19
+ def initialize(path: nil, image: nil, retro: false)
20
+ raise "keyword :path or :image must be provided!" if path.nil? && image.nil?
21
+
22
+ @retro = retro
23
+ @path = path
24
+
25
+ if @path
26
+ unless File.exist?(@path)
27
+ warn "Missing texture at: #{@path}"
28
+ @retro = true # override retro setting
29
+ @path = DEFAULT_TEXTURE
30
+ end
31
+
32
+ if texture = Texture.from_cache(@path, @retro)
33
+ @id = texture.id
34
+ return
35
+ end
36
+
37
+ image = load_image(@path)
38
+ @id = create_from_image(image)
39
+ else
40
+ @id = create_from_image(image)
41
+ end
42
+ end
43
+
44
+ def load_image(path)
45
+ CACHE["#{path}?retro=#{@retro}"] = self
46
+ Gosu::Image.new(path, retro: @retro)
47
+ end
48
+
49
+ def create_from_image(image)
50
+ array_of_pixels = image.to_blob
51
+
52
+ tex_names_buf = " " * 4
53
+ glGenTextures(1, tex_names_buf)
54
+ texture_id = tex_names_buf.unpack1("L2")
55
+
56
+ glBindTexture(GL_TEXTURE_2D, texture_id)
57
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, array_of_pixels)
58
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
59
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
60
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) if @retro
61
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) unless @retro
62
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
63
+ glGenerateMipmap(GL_TEXTURE_2D)
64
+ gl_error?
65
+
66
+ texture_id
67
+ end
68
+ end
69
+ end
@@ -4,7 +4,7 @@ module CyberarmEngine
4
4
  raise "Origin must be a Vector!" unless origin.is_a?(Vector)
5
5
  raise "Direction must be a Vector!" unless direction.is_a?(Vector)
6
6
 
7
- @origin = origin
7
+ @origin = origin
8
8
  @direction = direction
9
9
  @range = range
10
10
 
@@ -42,15 +42,15 @@ module CyberarmEngine
42
42
  tmin = max(tmin, min(tz1, tz2))
43
43
  tmax = min(tmax, max(tz1, tz2))
44
44
 
45
- return tmax >= max(tmin, 0.0);
45
+ tmax >= max(tmin, 0.0)
46
46
  end
47
47
 
48
48
  def min(x, y)
49
- ((x) < (y) ? (x) : (y))
49
+ ((x) < (y) ? x : y)
50
50
  end
51
51
 
52
52
  def max(x, y)
53
- ((x) > (y) ? (x) : (y))
53
+ ((x) > (y) ? x : y)
54
54
  end
55
55
  end
56
- end
56
+ end
@@ -0,0 +1,21 @@
1
+ module CyberarmEngine
2
+ class Stats
3
+ @@hash = {
4
+ gui_recalculations_last_frame: 0
5
+ }
6
+
7
+ def self.get(key)
8
+ @@hash.dig(key)
9
+ end
10
+
11
+ def self.increment(key, n)
12
+ @@hash[key] += n
13
+ end
14
+
15
+ def self.clear
16
+ @@hash.each do |key, _value|
17
+ @@hash[key] = 0
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,39 +5,40 @@ module CyberarmEngine
5
5
  attr_accessor :x, :y, :z, :size, :options
6
6
  attr_reader :text, :textobject, :factor_x, :factor_y, :color, :shadow, :shadow_size, :shadow_alpha, :shadow_color
7
7
 
8
- def initialize(text, options={})
8
+ def initialize(text, options = {})
9
9
  @text = text.to_s || ""
10
10
  @options = options
11
11
  @size = options[:size] || 18
12
- @font = options[:font] || "sans-serif"#Gosu.default_font_name
12
+ @font = options[:font] || Gosu.default_font_name
13
13
  @x = options[:x] || 0
14
14
  @y = options[:y] || 0
15
15
  @z = options[:z] || 1025
16
16
  @factor_x = options[:factor_x] || 1
17
17
  @factor_y = options[:factor_y] || 1
18
18
  @color = options[:color] || Gosu::Color::WHITE
19
- @alignment= options[:alignment] || nil
19
+ @mode = options[:mode] || :default
20
+ @alignment = options[:alignment] || nil
20
21
  @shadow = true if options[:shadow] == true
21
22
  @shadow = false if options[:shadow] == false
22
- @shadow = true if options[:shadow] == nil
23
- @shadow_size = options[:shadow_size] ? options[:shadow_size] : 1
24
- @shadow_alpha= options[:shadow_alpha] ? options[:shadow_alpha] : 30
25
- @shadow_alpha= options[:shadow_alpha] ? options[:shadow_alpha] : 30
26
- @shadow_color= options[:shadow_color]
23
+ @shadow = true if options[:shadow].nil?
24
+ @shadow_size = options[:shadow_size] || 1
25
+ @shadow_alpha = options[:shadow_alpha] || 30
26
+ @shadow_alpha = options[:shadow_alpha] || 30
27
+ @shadow_color = options[:shadow_color]
27
28
  @textobject = check_cache(@size, @font)
28
29
 
29
30
  if @alignment
30
31
  case @alignment
31
32
  when :left
32
- @x = 0+BUTTON_PADDING
33
+ @x = 0 + BUTTON_PADDING
33
34
  when :center
34
- @x = ($window.width/2)-(@textobject.text_width(@text)/2)
35
+ @x = ($window.width / 2) - (@textobject.text_width(@text) / 2)
35
36
  when :right
36
- @x = $window.width-BUTTON_PADDING-@textobject.text_width(@text)
37
+ @x = $window.width - BUTTON_PADDING - @textobject.text_width(@text)
37
38
  end
38
39
  end
39
40
 
40
- return self
41
+ self
41
42
  end
42
43
 
43
44
  def check_cache(size, font_name)
@@ -61,7 +62,7 @@ module CyberarmEngine
61
62
  CACHE[@size][@font] = font
62
63
  end
63
64
 
64
- return font
65
+ font
65
66
  end
66
67
 
67
68
  def text=(string)
@@ -73,64 +74,76 @@ module CyberarmEngine
73
74
  @rendered_shadow = nil
74
75
  @factor_x = n
75
76
  end
77
+
76
78
  def factor_y=(n)
77
79
  @rendered_shadow = nil
78
80
  @factor_y = n
79
81
  end
82
+
80
83
  def color=(color)
81
84
  @rendered_shadow = nil
82
85
  @color = color
83
86
  end
87
+
84
88
  def shadow=(boolean)
85
89
  @rendered_shadow = nil
86
90
  @shadow = boolean
87
91
  end
92
+
88
93
  def shadow_size=(n)
89
94
  @rendered_shadow = nil
90
95
  @shadow_size = n
91
96
  end
97
+
92
98
  def shadow_alpha=(n)
93
99
  @rendered_shadow = nil
94
100
  @shadow_alpha = n
95
101
  end
102
+
96
103
  def shadow_color=(n)
97
104
  @rendered_shadow = nil
98
105
  @shadow_color = n
99
106
  end
100
107
 
101
- def width
102
- textobject.text_width(@text)
108
+ def width(text = @text)
109
+ textobject.text_width(text)
110
+ end
111
+
112
+ def markup_width(text = @text)
113
+ textobject.markup_width(text)
103
114
  end
104
115
 
105
- def height
106
- @text.lines.count > 0 ? (@text.lines.count) * textobject.height : @textobject.height
116
+ def height(text = @text)
117
+ text.lines.count > 0 ? text.lines.count * textobject.height : @textobject.height
107
118
  end
108
119
 
109
- def draw
120
+ def draw(method = :draw_markup)
110
121
  if @shadow && !ARGV.join.include?("--no-shadow")
111
122
  shadow_alpha = @color.alpha <= 30 ? @color.alpha : @shadow_alpha
112
- shadow_color = @shadow_color ? @shadow_color : Gosu::Color.rgba(@color.red, @color.green, @color.blue, shadow_alpha)
123
+ shadow_color = @shadow_color || Gosu::Color.rgba(@color.red, @color.green, @color.blue,
124
+ shadow_alpha)
125
+ white = Gosu::Color::WHITE
113
126
 
114
127
  _x = @shadow_size
115
128
  _y = @shadow_size
116
129
 
117
- @rendered_shadow ||= Gosu.render((self.width+(shadow_size*2)).ceil, (self.height+(@shadow_size*2)).ceil) do
118
- @textobject.draw_markup(@text, _x-@shadow_size, _y, @z)
119
- @textobject.draw_markup(@text, _x-@shadow_size, _y-@shadow_size, @z)
130
+ @rendered_shadow ||= Gosu.render((width + (shadow_size * 2)).ceil, (height + (@shadow_size * 2)).ceil) do
131
+ @textobject.send(method, @text, _x - @shadow_size, _y, @z, @factor_x, @factor_y, white, :add)
132
+ @textobject.send(method, @text, _x - @shadow_size, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
120
133
 
121
- @textobject.draw_markup(@text, _x, _y-@shadow_size, @z, @factor_x)
122
- @textobject.draw_markup(@text, _x+@shadow_size, _y-@shadow_size, @z)
134
+ @textobject.send(method, @text, _x, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
135
+ @textobject.send(method, @text, _x + @shadow_size, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
123
136
 
124
- @textobject.draw_markup(@text, _x, _y+@shadow_size, @z)
125
- @textobject.draw_markup(@text, _x-@shadow_size, _y+@shadow_size, @z)
137
+ @textobject.send(method, @text, _x, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
138
+ @textobject.send(method, @text, _x - @shadow_size, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
126
139
 
127
- @textobject.draw_markup(@text, _x+@shadow_size, _y, @z)
128
- @textobject.draw_markup(@text, _x+@shadow_size, _y+@shadow_size, @z)
140
+ @textobject.send(method, @text, _x + @shadow_size, _y, @z, @factor_x, @factor_y, white, :add)
141
+ @textobject.send(method, @text, _x + @shadow_size, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
129
142
  end
130
- @rendered_shadow.draw(@x-@shadow_size, @y-@shadow_size, @z, @factor_x, @factor_y, shadow_color)
143
+ @rendered_shadow.draw(@x - @shadow_size, @y - @shadow_size, @z, @factor_x, @factor_y, shadow_color)
131
144
  end
132
145
 
133
- @textobject.draw_markup(@text, @x, @y, @z, @factor_x, @factor_y, @color)
146
+ @textobject.send(method, @text, @x, @y, @z, @factor_x, @factor_y, @color, @mode)
134
147
  end
135
148
 
136
149
  def alpha=(n)
@@ -141,6 +154,7 @@ module CyberarmEngine
141
154
  @color.alpha
142
155
  end
143
156
 
144
- def update; end
157
+ def update
158
+ end
145
159
  end
146
160
  end
@@ -20,4 +20,4 @@ module CyberarmEngine
20
20
  end
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -2,11 +2,12 @@ module CyberarmEngine
2
2
  # Basic 4x4 matrix operations
3
3
  class Transform
4
4
  attr_reader :elements
5
+
5
6
  def initialize(matrix)
6
7
  @elements = matrix
7
8
 
8
9
  raise "Transform is wrong size! Got #{@elements.size}, expected 16" if 16 != @elements.size
9
- raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric)}
10
+ raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric) }
10
11
  end
11
12
 
12
13
  def self.identity
@@ -27,10 +28,10 @@ module CyberarmEngine
27
28
  double c = Math.cos(angle).degrees_to_radians
28
29
  double s = Math.sin(angle).degrees_to_radians
29
30
  matrix = [
30
- +c, +s, 0, 0,
31
- -s, +c, 0, 0,
32
- 0, 0, 1, 0,
33
- 0, 0, 0, 1,
31
+ +c, +s, 0, 0,
32
+ -s, +c, 0, 0,
33
+ 0, 0, 1, 0,
34
+ 0, 0, 0, 1
34
35
  ]
35
36
 
36
37
  rotate_matrix = Transform.new(matrix, rows: 4, columns: 4)
@@ -44,7 +45,7 @@ module CyberarmEngine
44
45
  )
45
46
  end
46
47
 
47
- return rotate_matrix
48
+ rotate_matrix
48
49
  end
49
50
 
50
51
  # 2d translate operation, replicates Gosu's Gosu.translate function
@@ -54,7 +55,7 @@ module CyberarmEngine
54
55
  1, 0, 0, 0,
55
56
  0, 1, 0, 0,
56
57
  0, 0, 1, 0,
57
- x, y, z, 1,
58
+ x, y, z, 1
58
59
  ]
59
60
 
60
61
  Transform.new(matrix)
@@ -67,7 +68,7 @@ module CyberarmEngine
67
68
  scale_x, 0, 0, 0,
68
69
  0, scale_y, 0, 0,
69
70
  0, 0, scale_z, 0,
70
- 0, 0, 0, 1,
71
+ 0, 0, 0, 1
71
72
  ]
72
73
 
73
74
  scale_matrix = Transform.new(matrix)
@@ -81,7 +82,7 @@ module CyberarmEngine
81
82
  )
82
83
  end
83
84
 
84
- return scale_matrix
85
+ scale_matrix
85
86
  end
86
87
 
87
88
  def self.concat(left, right)
@@ -107,13 +108,13 @@ module CyberarmEngine
107
108
  1, 0, 0, x,
108
109
  0, 1, 0, y,
109
110
  0, 0, 1, z,
110
- 0, 0, 0, 1,
111
+ 0, 0, 0, 1
111
112
  ]
112
113
 
113
114
  Transform.new(matrix)
114
115
  end
115
116
 
116
- def self.rotate_3d(vector, order = "zyx")
117
+ def self.rotate_3d(vector, _order = "zyx")
117
118
  x, y, z = vector.to_a[0..2].map { |axis| axis * Math::PI / 180.0 }
118
119
 
119
120
  rotation_x = Transform.new(
@@ -163,7 +164,7 @@ module CyberarmEngine
163
164
  x * x * n + c, x * y * n - z * s, x * z * n + y * s, 0,
164
165
  y * x * n + z * s, y * y * n + c, y * z * n - x * s, 0,
165
166
  x * z * n - y * s, y * z * n + x * s, z * z * n + c, 0,
166
- 0, 0, 0, 1.0
167
+ 0, 0, 0, 1.0
167
168
  ]
168
169
  )
169
170
  end
@@ -190,12 +191,35 @@ module CyberarmEngine
190
191
  [
191
192
  f / aspect_ratio, 0.0, 0.0, 0.0,
192
193
  0.0, f, 0.0, 0.0,
193
- 0.0, 0.0, zn, zf,
194
+ 0.0, 0.0, zn, zf,
194
195
  0.0, 0.0, -1.0, 0.0
195
196
  ]
196
197
  )
197
198
  end
198
199
 
200
+ def self.orthographic(left, right, bottom, top, near, far)
201
+ s = Vector.new(
202
+ 2 / (right - left.to_f),
203
+ 2 / (top - bottom.to_f),
204
+ -2 / (far - near.to_f)
205
+ )
206
+
207
+ t = Vector.new(
208
+ (right + left.to_f) / (right - left.to_f),
209
+ (top + bottom.to_f) / (top - bottom.to_f),
210
+ (far + near.to_f) / (far - near.to_f)
211
+ )
212
+
213
+ Transform.new(
214
+ [
215
+ s.x, 0.0, 0.0, t.x,
216
+ 0.0, s.y, 0.0, t.y,
217
+ 0.0, 0.0, s.z, t.z,
218
+ 0.0, 0.0, 0.0, 1.0
219
+ ]
220
+ )
221
+ end
222
+
199
223
  def self.view(eye, orientation)
200
224
  # https://www.3dgep.com/understanding-the-view-matrix/#The_View_Matrix
201
225
  cosPitch = Math.cos(orientation.z * Math::PI / 180.0)
@@ -209,16 +233,15 @@ module CyberarmEngine
209
233
 
210
234
  Transform.new(
211
235
  [
212
- x_axis.x, y_axis.y, z_axis.z, 0,
213
- x_axis.x, y_axis.y, z_axis.z, 0,
214
- x_axis.x, y_axis.y, z_axis.z, 0,
236
+ x_axis.x, y_axis.y, z_axis.z, 0,
237
+ x_axis.x, y_axis.y, z_axis.z, 0,
238
+ x_axis.x, y_axis.y, z_axis.z, 0,
215
239
  -x_axis.dot(eye), -y_axis.dot(eye), -z_axis.dot(eye), 1
216
240
  ]
217
241
  )
218
242
  end
219
243
 
220
244
  def *(other)
221
-
222
245
  case other
223
246
  when CyberarmEngine::Vector
224
247
  matrix = @elements.clone
@@ -231,7 +254,7 @@ module CyberarmEngine
231
254
  Transform.new(matrix)
232
255
 
233
256
  when CyberarmEngine::Transform
234
- return multiply_matrices(other)
257
+ multiply_matrices(other)
235
258
  else
236
259
  p other.class
237
260
  raise TypeError, "Expected CyberarmEngine::Vector or CyberarmEngine::Transform got #{other.class}"
@@ -256,7 +279,7 @@ module CyberarmEngine
256
279
  end
257
280
  end
258
281
 
259
- return Transform.new(matrix)
282
+ Transform.new(matrix)
260
283
  end
261
284
 
262
285
  # arranges Matrix in column major form
@@ -270,4 +293,4 @@ module CyberarmEngine
270
293
  ]
271
294
  end
272
295
  end
273
- end
296
+ end