cyberarm_engine 0.24.4 → 0.24.5

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/Gemfile.lock +24 -0
  7. data/LICENSE.txt +21 -21
  8. data/README.md +74 -74
  9. data/Rakefile +10 -10
  10. data/assets/shaders/fragment/g_buffer.glsl +30 -30
  11. data/assets/shaders/fragment/lighting.glsl +115 -69
  12. data/assets/shaders/include/light_struct.glsl +11 -11
  13. data/assets/shaders/include/material_struct.glsl +16 -16
  14. data/assets/shaders/vertex/g_buffer.glsl +28 -28
  15. data/assets/shaders/vertex/lighting.glsl +24 -24
  16. data/bin/console +14 -14
  17. data/bin/setup +8 -8
  18. data/cyberarm_engine.gemspec +36 -36
  19. data/lib/cyberarm_engine/animator.rb +219 -219
  20. data/lib/cyberarm_engine/background.rb +180 -179
  21. data/lib/cyberarm_engine/background_image.rb +93 -93
  22. data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
  23. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  24. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  25. data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
  26. data/lib/cyberarm_engine/cache.rb +4 -4
  27. data/lib/cyberarm_engine/common.rb +128 -128
  28. data/lib/cyberarm_engine/config_file.rb +46 -46
  29. data/lib/cyberarm_engine/console/command.rb +157 -157
  30. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  31. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  32. data/lib/cyberarm_engine/console.rb +248 -248
  33. data/lib/cyberarm_engine/game_object.rb +244 -244
  34. data/lib/cyberarm_engine/game_state.rb +124 -124
  35. data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +97 -97
  36. data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
  37. data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
  38. data/lib/cyberarm_engine/model/material.rb +21 -21
  39. data/lib/cyberarm_engine/model/{model_object.rb → mesh.rb} +131 -131
  40. data/lib/cyberarm_engine/model/parser.rb +74 -74
  41. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  42. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  43. data/lib/cyberarm_engine/model.rb +216 -213
  44. data/lib/cyberarm_engine/model_cache.rb +31 -31
  45. data/lib/cyberarm_engine/notification.rb +82 -82
  46. data/lib/cyberarm_engine/notification_manager.rb +241 -241
  47. data/lib/cyberarm_engine/opengl/light.rb +52 -50
  48. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  49. data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -38
  50. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  51. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -165
  52. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -304
  53. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
  54. data/lib/cyberarm_engine/opengl/shader.rb +408 -406
  55. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  56. data/lib/cyberarm_engine/opengl.rb +53 -40
  57. data/lib/cyberarm_engine/ray.rb +56 -56
  58. data/lib/cyberarm_engine/stats.rb +200 -200
  59. data/lib/cyberarm_engine/text.rb +260 -260
  60. data/lib/cyberarm_engine/timer.rb +23 -23
  61. data/lib/cyberarm_engine/transform.rb +296 -296
  62. data/lib/cyberarm_engine/trees/aabb_node.rb +126 -0
  63. data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -0
  64. data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -0
  65. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  66. data/lib/cyberarm_engine/ui/dsl.rb +142 -142
  67. data/lib/cyberarm_engine/ui/element.rb +662 -662
  68. data/lib/cyberarm_engine/ui/elements/button.rb +100 -100
  69. data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
  70. data/lib/cyberarm_engine/ui/elements/container.rb +404 -404
  71. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
  72. data/lib/cyberarm_engine/ui/elements/edit_line.rb +297 -297
  73. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  74. data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
  75. data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
  76. data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
  77. data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
  78. data/lib/cyberarm_engine/ui/elements/progress.rb +93 -93
  79. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  80. data/lib/cyberarm_engine/ui/elements/slider.rb +107 -107
  81. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  82. data/lib/cyberarm_engine/ui/elements/text_block.rb +216 -216
  83. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +67 -67
  84. data/lib/cyberarm_engine/ui/event.rb +54 -54
  85. data/lib/cyberarm_engine/ui/gui_state.rb +321 -321
  86. data/lib/cyberarm_engine/ui/style.rb +50 -50
  87. data/lib/cyberarm_engine/ui/theme.rb +225 -225
  88. data/lib/cyberarm_engine/vector.rb +312 -312
  89. data/lib/cyberarm_engine/version.rb +4 -4
  90. data/lib/cyberarm_engine/window.rb +195 -195
  91. data/lib/cyberarm_engine.rb +70 -78
  92. data/mrbgem.rake +29 -29
  93. metadata +8 -7
@@ -1,200 +1,200 @@
1
- module CyberarmEngine
2
- class Stats
3
- @frames = []
4
- @frame_index = -1
5
- @max_frame_history = 1024
6
-
7
- def self.new_frame
8
- if @frames.size < @max_frame_history
9
- @frames << Frame.new
10
- else
11
- @frames[@frame_index] = Frame.new
12
- end
13
- end
14
-
15
- def self.frame
16
- @frames[@frame_index]
17
- end
18
-
19
- def self.end_frame
20
- frame&.complete
21
-
22
- @frame_index += 1
23
- @frame_index %= @max_frame_history
24
- end
25
-
26
- def self.frames
27
- if @frames.size < @max_frame_history
28
- @frames
29
- else
30
- @frames.rotate(@frame_index - (@max_frame_history - (@frames.size - 1)))
31
- end
32
- end
33
-
34
- def self.frame_index
35
- @frame_index
36
- end
37
-
38
- def self.max_frame_history
39
- @max_frame_history
40
- end
41
-
42
- class Frame
43
- Timing = Struct.new(:start_time, :end_time, :duration)
44
-
45
- attr_reader :frame_timing, :counters, :timings, :multitimings
46
- def initialize
47
- @frame_timing = Timing.new(Gosu.milliseconds, -1, -1)
48
- @attempted_multitiming = false
49
-
50
- @counters = {
51
- gui_recalculations: 0
52
- }
53
-
54
- @timings = {}
55
- @multitimings = {}
56
- end
57
-
58
- def increment(key, number = 1)
59
- @counters[key] ||= 0
60
- @counters[key] += number
61
- end
62
-
63
- def start_timing(key)
64
- raise "key must be a symbol!" unless key.is_a?(Symbol)
65
- if @timings[key]
66
- # FIXME: Make it not spammy...
67
- # warn "Only one timing per key per frame. (Timing for #{key.inspect} already exists!)"
68
- @attempted_multitiming = true
69
- @multitimings[key] = true
70
-
71
- return
72
- end
73
-
74
- @timings[key] = Timing.new(Gosu.milliseconds, -1, -1)
75
- end
76
-
77
- def end_timing(key)
78
- timing = @timings[key]
79
-
80
- # FIXME: Make it not spammy...
81
- # warn "Timing #{key.inspect} already ended!" if timing.end_time != -1
82
-
83
- timing.end_time = Gosu.milliseconds
84
- timing.duration = timing.end_time - timing.start_time
85
- end
86
-
87
- def complete
88
- @frame_timing.end_time = Gosu.milliseconds
89
- @frame_timing.duration = @frame_timing.end_time - @frame_timing.start_time
90
-
91
- # Lock data structures
92
- @frame_timing.freeze
93
- @counters.freeze
94
- @timings.freeze
95
- @multitimings.freeze
96
- end
97
-
98
- def complete?
99
- @frame_timing.duration != -1
100
- end
101
-
102
- def attempted_multitiming?
103
- @attempted_multitiming
104
- end
105
- end
106
-
107
- class StatsPlotter
108
- attr_reader :position
109
-
110
- def initialize(x, y, z = Float::INFINITY, width = 128, height = 128)
111
- @position = Vector.new(x, y, z)
112
- @width = width
113
- @height = height
114
-
115
- @padding = 2
116
- @text_size = 16
117
-
118
- @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true, static: true)
119
- @avg_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding + @height / 2 - @text_size / 2, z: z, size: @text_size, border: true, static: true)
120
- @min_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @height - (@text_size + @padding / 2), z: z, size: @text_size, border: true, static: true)
121
-
122
- @data_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true, static: true)
123
-
124
- @frame_stats = []
125
- @graphs = {
126
- frame_timings: []
127
- }
128
- end
129
-
130
- def calculate_graphs
131
- calculate_frame_timings_graph
132
- end
133
-
134
- def calculate_frame_timings_graph
135
- @graphs[:frame_timings].clear
136
-
137
- samples = @width - @padding
138
- nodes = Array.new(samples.ceil) { [] }
139
-
140
- slice = 0
141
- @frame_stats.each_slice((CyberarmEngine::Stats.max_frame_history / samples.to_f).ceil) do |bucket|
142
- bucket.each do |frame|
143
- nodes[slice] << frame.frame_timing.duration
144
- end
145
-
146
- slice += 1
147
- end
148
-
149
- max_node = CyberarmEngine::Stats.frames.select(&:complete?).map { |f| f.frame_timing.duration }.max
150
- scale = 1
151
- scale = (@height - @padding).to_f / max_node
152
- scale = 1 if scale > 1
153
-
154
- nodes.each_with_index do |cluster, i|
155
- break if cluster.empty?
156
-
157
- @graphs[:frame_timings] << CyberarmEngine::Vector.new(@position.x + @padding + 1 * i, (@position.y + @height - @padding) - cluster.max * scale)
158
- end
159
- end
160
-
161
- def draw
162
- @frame_stats = CyberarmEngine::Stats.frames.select(&:complete?)
163
- return if @frame_stats.empty?
164
-
165
- calculate_graphs
166
-
167
- @max_timing_label.text = "<c=d44>Max:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
168
- @avg_timing_label.text = "<c=f80>Avg:</c> #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
169
- @min_timing_label.text = "<c=0d0>Min:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
170
-
171
- Gosu.draw_rect(@position.x, @position.y, @width, @height, 0xaa_222222, @position.z)
172
- Gosu.draw_rect(@position.x + @padding, @position.y + @padding, @width - @padding * 2, @height - @padding * 2, 0xaa_222222, @position.z)
173
-
174
- draw_graphs
175
-
176
- @max_timing_label.draw
177
- @avg_timing_label.draw
178
- @min_timing_label.draw
179
-
180
- # TODO: Make this optional
181
- draw_timings_and_counters
182
- end
183
-
184
- def draw_graphs
185
- Gosu.draw_path(@graphs[:frame_timings], Gosu::Color::WHITE, Float::INFINITY)
186
- end
187
-
188
- def draw_timings_and_counters
189
- frame = @frame_stats.last
190
-
191
- @data_label.text = "<c=f8f>COUNTERS:</c>\n#{frame.counters.map { |t, v| "#{t}: #{v}" }.join("\n")}\n\n"\
192
- "<c=f80>TIMINGS:</c>\n#{frame.attempted_multitiming? ? "<c=d00>Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }</c>\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
193
- Gosu.draw_rect(@data_label.x - @padding, @data_label.y - @padding, @data_label.width + @padding * 2, @data_label.height + @padding * 2, 0xdd_222222, @position.z)
194
- @data_label.draw
195
-
196
- # puts "Recalcs this frame: #{frame.counters[:gui_recalculations]} [dt: #{(CyberarmEngine::Window.dt * 1000).round} ms]" if frame.counters[:gui_recalculations] && frame.counters[:gui_recalculations].positive?
197
- end
198
- end
199
- end
200
- end
1
+ module CyberarmEngine
2
+ class Stats
3
+ @frames = []
4
+ @frame_index = -1
5
+ @max_frame_history = 1024
6
+
7
+ def self.new_frame
8
+ if @frames.size < @max_frame_history
9
+ @frames << Frame.new
10
+ else
11
+ @frames[@frame_index] = Frame.new
12
+ end
13
+ end
14
+
15
+ def self.frame
16
+ @frames[@frame_index]
17
+ end
18
+
19
+ def self.end_frame
20
+ frame&.complete
21
+
22
+ @frame_index += 1
23
+ @frame_index %= @max_frame_history
24
+ end
25
+
26
+ def self.frames
27
+ if @frames.size < @max_frame_history
28
+ @frames
29
+ else
30
+ @frames.rotate(@frame_index - (@max_frame_history - (@frames.size - 1)))
31
+ end
32
+ end
33
+
34
+ def self.frame_index
35
+ @frame_index
36
+ end
37
+
38
+ def self.max_frame_history
39
+ @max_frame_history
40
+ end
41
+
42
+ class Frame
43
+ Timing = Struct.new(:start_time, :end_time, :duration)
44
+
45
+ attr_reader :frame_timing, :counters, :timings, :multitimings
46
+ def initialize
47
+ @frame_timing = Timing.new(Gosu.milliseconds, -1, -1)
48
+ @attempted_multitiming = false
49
+
50
+ @counters = {
51
+ gui_recalculations: 0
52
+ }
53
+
54
+ @timings = {}
55
+ @multitimings = {}
56
+ end
57
+
58
+ def increment(key, number = 1)
59
+ @counters[key] ||= 0
60
+ @counters[key] += number
61
+ end
62
+
63
+ def start_timing(key)
64
+ raise "key must be a symbol!" unless key.is_a?(Symbol)
65
+ if @timings[key]
66
+ # FIXME: Make it not spammy...
67
+ # warn "Only one timing per key per frame. (Timing for #{key.inspect} already exists!)"
68
+ @attempted_multitiming = true
69
+ @multitimings[key] = true
70
+
71
+ return
72
+ end
73
+
74
+ @timings[key] = Timing.new(Gosu.milliseconds, -1, -1)
75
+ end
76
+
77
+ def end_timing(key)
78
+ timing = @timings[key]
79
+
80
+ # FIXME: Make it not spammy...
81
+ # warn "Timing #{key.inspect} already ended!" if timing.end_time != -1
82
+
83
+ timing.end_time = Gosu.milliseconds
84
+ timing.duration = timing.end_time - timing.start_time
85
+ end
86
+
87
+ def complete
88
+ @frame_timing.end_time = Gosu.milliseconds
89
+ @frame_timing.duration = @frame_timing.end_time - @frame_timing.start_time
90
+
91
+ # Lock data structures
92
+ @frame_timing.freeze
93
+ @counters.freeze
94
+ @timings.freeze
95
+ @multitimings.freeze
96
+ end
97
+
98
+ def complete?
99
+ @frame_timing.duration != -1
100
+ end
101
+
102
+ def attempted_multitiming?
103
+ @attempted_multitiming
104
+ end
105
+ end
106
+
107
+ class StatsPlotter
108
+ attr_reader :position
109
+
110
+ def initialize(x, y, z = Float::INFINITY, width = 128, height = 128)
111
+ @position = Vector.new(x, y, z)
112
+ @width = width
113
+ @height = height
114
+
115
+ @padding = 2
116
+ @text_size = 16
117
+
118
+ @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true, static: true)
119
+ @avg_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding + @height / 2 - @text_size / 2, z: z, size: @text_size, border: true, static: true)
120
+ @min_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @height - (@text_size + @padding / 2), z: z, size: @text_size, border: true, static: true)
121
+
122
+ @data_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true, static: true)
123
+
124
+ @frame_stats = []
125
+ @graphs = {
126
+ frame_timings: []
127
+ }
128
+ end
129
+
130
+ def calculate_graphs
131
+ calculate_frame_timings_graph
132
+ end
133
+
134
+ def calculate_frame_timings_graph
135
+ @graphs[:frame_timings].clear
136
+
137
+ samples = @width - @padding
138
+ nodes = Array.new(samples.ceil) { [] }
139
+
140
+ slice = 0
141
+ @frame_stats.each_slice((CyberarmEngine::Stats.max_frame_history / samples.to_f).ceil) do |bucket|
142
+ bucket.each do |frame|
143
+ nodes[slice] << frame.frame_timing.duration
144
+ end
145
+
146
+ slice += 1
147
+ end
148
+
149
+ max_node = CyberarmEngine::Stats.frames.select(&:complete?).map { |f| f.frame_timing.duration }.max
150
+ scale = 1
151
+ scale = (@height - @padding).to_f / max_node
152
+ scale = 1 if scale > 1
153
+
154
+ nodes.each_with_index do |cluster, i|
155
+ break if cluster.empty?
156
+
157
+ @graphs[:frame_timings] << CyberarmEngine::Vector.new(@position.x + @padding + 1 * i, (@position.y + @height - @padding) - cluster.max * scale)
158
+ end
159
+ end
160
+
161
+ def draw
162
+ @frame_stats = CyberarmEngine::Stats.frames.select(&:complete?)
163
+ return if @frame_stats.empty?
164
+
165
+ calculate_graphs
166
+
167
+ @max_timing_label.text = "<c=d44>Max:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
168
+ @avg_timing_label.text = "<c=f80>Avg:</c> #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
169
+ @min_timing_label.text = "<c=0d0>Min:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
170
+
171
+ Gosu.draw_rect(@position.x, @position.y, @width, @height, 0xaa_222222, @position.z)
172
+ Gosu.draw_rect(@position.x + @padding, @position.y + @padding, @width - @padding * 2, @height - @padding * 2, 0xaa_222222, @position.z)
173
+
174
+ draw_graphs
175
+
176
+ @max_timing_label.draw
177
+ @avg_timing_label.draw
178
+ @min_timing_label.draw
179
+
180
+ # TODO: Make this optional
181
+ draw_timings_and_counters
182
+ end
183
+
184
+ def draw_graphs
185
+ Gosu.draw_path(@graphs[:frame_timings], Gosu::Color::WHITE, Float::INFINITY)
186
+ end
187
+
188
+ def draw_timings_and_counters
189
+ frame = @frame_stats.last
190
+
191
+ @data_label.text = "<c=f8f>COUNTERS:</c>\n#{frame.counters.map { |t, v| "#{t}: #{v}" }.join("\n")}\n\n"\
192
+ "<c=f80>TIMINGS:</c>\n#{frame.attempted_multitiming? ? "<c=d00>Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }</c>\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
193
+ Gosu.draw_rect(@data_label.x - @padding, @data_label.y - @padding, @data_label.width + @padding * 2, @data_label.height + @padding * 2, 0xdd_222222, @position.z)
194
+ @data_label.draw
195
+
196
+ # puts "Recalcs this frame: #{frame.counters[:gui_recalculations]} [dt: #{(CyberarmEngine::Window.dt * 1000).round} ms]" if frame.counters[:gui_recalculations] && frame.counters[:gui_recalculations].positive?
197
+ end
198
+ end
199
+ end
200
+ end