cyberarm_engine 0.25.0 → 0.30.0

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/Gemfile.lock +37 -25
  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 -115
  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/assets/textures/ui/circle.png +0 -0
  17. data/assets/textures/ui/circle_small.png +0 -0
  18. data/assets/textures/ui/rounded.png +0 -0
  19. data/assets/textures/ui/rounded_bottom.png +0 -0
  20. data/assets/textures/ui/rounded_left.png +0 -0
  21. data/assets/textures/ui/rounded_left_bottom.png +0 -0
  22. data/assets/textures/ui/rounded_left_top.png +0 -0
  23. data/assets/textures/ui/rounded_right.png +0 -0
  24. data/assets/textures/ui/rounded_right_bottom.png +0 -0
  25. data/assets/textures/ui/rounded_right_top.png +0 -0
  26. data/assets/textures/ui/rounded_small.png +0 -0
  27. data/assets/textures/ui/rounded_tiny.png +0 -0
  28. data/assets/textures/ui/rounded_top.png +0 -0
  29. data/assets/textures/ui/square.png +0 -0
  30. data/bin/console +14 -14
  31. data/bin/setup +8 -8
  32. data/cyberarm_engine.gemspec +35 -36
  33. data/lib/cyberarm_engine/animator.rb +219 -219
  34. data/lib/cyberarm_engine/background.rb +156 -158
  35. data/lib/cyberarm_engine/background_image.rb +93 -93
  36. data/lib/cyberarm_engine/background_nine_slice.rb +182 -142
  37. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  38. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  39. data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
  40. data/lib/cyberarm_engine/cache.rb +4 -4
  41. data/lib/cyberarm_engine/common.rb +133 -131
  42. data/lib/cyberarm_engine/config_file.rb +46 -46
  43. data/lib/cyberarm_engine/console/command.rb +157 -157
  44. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  45. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  46. data/lib/cyberarm_engine/console.rb +248 -248
  47. data/lib/cyberarm_engine/event_bus.rb +39 -0
  48. data/lib/cyberarm_engine/game_object.rb +244 -244
  49. data/lib/cyberarm_engine/game_state.rb +134 -124
  50. data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +111 -111
  51. data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
  52. data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
  53. data/lib/cyberarm_engine/model/material.rb +21 -21
  54. data/lib/cyberarm_engine/model/mesh.rb +131 -131
  55. data/lib/cyberarm_engine/model/parser.rb +74 -74
  56. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  57. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  58. data/lib/cyberarm_engine/model.rb +216 -216
  59. data/lib/cyberarm_engine/model_cache.rb +31 -31
  60. data/lib/cyberarm_engine/notification.rb +82 -82
  61. data/lib/cyberarm_engine/notification_manager.rb +241 -241
  62. data/lib/cyberarm_engine/opengl/light.rb +52 -52
  63. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  64. data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -41
  65. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  66. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -167
  67. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -307
  68. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
  69. data/lib/cyberarm_engine/opengl/shader.rb +408 -408
  70. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  71. data/lib/cyberarm_engine/opengl.rb +53 -53
  72. data/lib/cyberarm_engine/pathfinding/graph.rb +64 -0
  73. data/lib/cyberarm_engine/pathfinding/graph_search.rb +6 -0
  74. data/lib/cyberarm_engine/pathfinding/graph_searches/astar_search.rb +6 -0
  75. data/lib/cyberarm_engine/pathfinding/graph_searches/breadth_first_search.rb +27 -0
  76. data/lib/cyberarm_engine/pathfinding/graph_searches/dijkstra_search.rb +6 -0
  77. data/lib/cyberarm_engine/pathfinding/graphs/grid.rb +52 -0
  78. data/lib/cyberarm_engine/ray.rb +56 -56
  79. data/lib/cyberarm_engine/result.rb +19 -0
  80. data/lib/cyberarm_engine/stats.rb +200 -200
  81. data/lib/cyberarm_engine/text.rb +288 -260
  82. data/lib/cyberarm_engine/timer.rb +27 -23
  83. data/lib/cyberarm_engine/transform.rb +296 -296
  84. data/lib/cyberarm_engine/trees/aabb_node.rb +126 -126
  85. data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -55
  86. data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -29
  87. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  88. data/lib/cyberarm_engine/ui/dialog.rb +24 -0
  89. data/lib/cyberarm_engine/ui/dsl.rb +170 -142
  90. data/lib/cyberarm_engine/ui/element.rb +664 -662
  91. data/lib/cyberarm_engine/ui/elements/button.rb +99 -100
  92. data/lib/cyberarm_engine/ui/elements/check_box.rb +58 -54
  93. data/lib/cyberarm_engine/ui/elements/container.rb +413 -407
  94. data/lib/cyberarm_engine/ui/elements/edit_box.rb +200 -179
  95. data/lib/cyberarm_engine/ui/elements/edit_line.rb +299 -297
  96. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  97. data/lib/cyberarm_engine/ui/elements/image.rb +78 -72
  98. data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
  99. data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
  100. data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
  101. data/lib/cyberarm_engine/ui/elements/progress.rb +95 -93
  102. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  103. data/lib/cyberarm_engine/ui/elements/slider.rb +111 -107
  104. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  105. data/lib/cyberarm_engine/ui/elements/text_block.rb +236 -222
  106. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +71 -67
  107. data/lib/cyberarm_engine/ui/elements/widget.rb +45 -0
  108. data/lib/cyberarm_engine/ui/event.rb +54 -54
  109. data/lib/cyberarm_engine/ui/gui_state.rb +402 -326
  110. data/lib/cyberarm_engine/ui/page.rb +39 -0
  111. data/lib/cyberarm_engine/ui/style.rb +94 -61
  112. data/lib/cyberarm_engine/ui/theme.rb +237 -225
  113. data/lib/cyberarm_engine/vector.rb +312 -312
  114. data/lib/cyberarm_engine/version.rb +4 -4
  115. data/lib/cyberarm_engine/window.rb +234 -195
  116. data/lib/cyberarm_engine.rb +88 -76
  117. data/mrbgem.rake +29 -29
  118. metadata +30 -5
@@ -1,142 +1,182 @@
1
- module CyberarmEngine
2
- class BackgroundNineSlice
3
- include CyberarmEngine::Common
4
- attr_accessor :x, :y, :z, :width, :height, :left, :top, :right, :bottom, :mode, :color
5
- attr_reader :image
6
-
7
- def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :tiled, left: 1, top: 1, right: 1, bottom: 1, color: Gosu::Color::WHITE)
8
- @image = get_image(image_path) if image_path
9
-
10
- @x = x
11
- @y = y
12
- @z = z
13
-
14
- @width = width
15
- @height = height
16
-
17
- @mode = mode
18
-
19
- @left = left
20
- @top = top
21
- @right = right
22
- @bottom = bottom
23
-
24
- @color = color
25
-
26
- nine_slice if @image
27
- end
28
-
29
- def image=(image_path)
30
- old_image = @image
31
- @image = image_path ? get_image(image_path) : image_path
32
- nine_slice if @image && old_image != @image
33
- end
34
-
35
- def nine_slice
36
- # pp [@left, @top, @right, @bottom, @image.width]
37
-
38
- @segment_top_left = @image.subimage(0, 0, @left, @top)
39
- @segment_top_right = @image.subimage(@image.width - @right, 0, @right, @top)
40
-
41
- @segment_left = @image.subimage(0, @top, @left, @image.height - (@top + @bottom))
42
- @segment_right = @image.subimage(@image.width - @right, @top, @left, @image.height - (@top + @bottom))
43
-
44
- @segment_bottom_left = @image.subimage(0, @image.height - @bottom, @left, @bottom)
45
- @segment_bottom_right = @image.subimage(@image.width - @right, @image.height - @bottom, @right, @bottom)
46
-
47
- @segment_top = @image.subimage(@left, 0, @image.width - (@left + @right), @top)
48
- @segment_bottom = @image.subimage(@left, @image.height - @bottom, @image.width - (@left + @right), @bottom)
49
-
50
- @segment_middle = @image.subimage(@left, @top, @image.width - (@left + @right), @image.height - (@top + @bottom))
51
- end
52
-
53
- def cx
54
- @x + @left
55
- end
56
-
57
- def cy
58
- @y + @top
59
- end
60
-
61
- def cwidth
62
- @cx - @width
63
- end
64
-
65
- def cheight
66
- @cy - @height
67
- end
68
-
69
- def width_scale
70
- scale = (@width.to_f - (@left + @right)) / (@image.width - (@left + @right))
71
- scale.abs
72
- end
73
-
74
- def height_scale
75
- scale = (@height - (@top + @bottom)).to_f / (@image.height - (@top + @bottom))
76
- scale.abs
77
- end
78
-
79
- def draw
80
- return unless @image && @segment_top_left
81
-
82
- @mode == :tiled ? draw_tiled : draw_stretched
83
- end
84
-
85
- def draw_stretched
86
- @segment_top_left.draw(@x, @y, @z, 1, 1, @color)
87
- @segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale, 1, @color) # SCALE X
88
- @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color)
89
-
90
- @segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale, @color) # SCALE Y
91
- @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color)
92
- @segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale, 1, @color) # SCALE X
93
- @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color)
94
- @segment_left.draw(@x, @y + @top, @z, 1, height_scale, @color) # SCALE Y
95
- @segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale, @color) # SCALE X and SCALE Y
96
- end
97
-
98
- def draw_tiled
99
- @segment_top_left.draw(@x, @y, @z, 1, 1, @color)
100
-
101
- # p [width_scale, height_scale]
102
-
103
- Gosu.clip_to(@x + @segment_top_left.width, @y, @segment_top.width * width_scale, @segment_top.height) do
104
- width_scale.ceil.times do |i|
105
- @segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z, 1, 1, @color) # SCALE X
106
- end
107
- end
108
-
109
- @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color)
110
-
111
- Gosu.clip_to(@x + @width - @segment_top_right.width, @y + @top, @segment_right.width, @segment_right.height * height_scale) do
112
- height_scale.ceil.times do |i|
113
- @segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z, 1, 1, @color) # SCALE Y
114
- end
115
- end
116
-
117
- @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color)
118
-
119
- Gosu.clip_to(@x + @segment_top_left.width, @y + @height - @segment_bottom.height, @segment_top.width * width_scale, @segment_bottom.height) do
120
- width_scale.ceil.times do |i|
121
- @segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z, 1, 1, @color) # SCALE X
122
- end
123
- end
124
-
125
- @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color)
126
-
127
- Gosu.clip_to(@x, @y + @top, @segment_left.width, @segment_left.height * height_scale) do
128
- height_scale.ceil.times do |i|
129
- @segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z, 1, 1, @color) # SCALE Y
130
- end
131
- end
132
-
133
- Gosu.clip_to(@x + @segment_top_left.width, @y + @segment_top.height, @width - (@segment_left.width + @segment_right.width), @height - (@segment_top.height + @segment_bottom.height)) do
134
- height_scale.ceil.times do |y|
135
- width_scale.ceil.times do |x|
136
- @segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z, 1, 1, @color) # SCALE X and SCALE Y
137
- end
138
- end
139
- end
140
- end
141
- end
142
- end
1
+ module CyberarmEngine
2
+ class BackgroundNineSlice
3
+ include CyberarmEngine::Common
4
+
5
+ CACHE = {}
6
+
7
+ attr_accessor :x, :y, :z, :width, :height, :mode, :color, :render_mode
8
+ attr_reader :image, :left, :top, :right, :bottom
9
+
10
+ def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :tiled, left: 1, top: 1, right: 1, bottom: 1, color: Gosu::Color::WHITE, render_mode: :default)
11
+ @image = get_image(image_path) if image_path
12
+
13
+ @x = x
14
+ @y = y
15
+ @z = z
16
+
17
+ @width = width
18
+ @height = height
19
+
20
+ @mode = mode
21
+
22
+ @left = left
23
+ @top = top
24
+ @right = right
25
+ @bottom = bottom
26
+
27
+ @color = color
28
+ @render_mode = render_mode
29
+
30
+ nine_slice if @image
31
+ end
32
+
33
+ def image=(image_path)
34
+ old_image = @image
35
+ @image = image_path ? get_image(image_path) : image_path
36
+ nine_slice if @image && old_image != @image
37
+ end
38
+
39
+ def set_edges(left: @left, right: @right, top: @top, bottom: @bottom)
40
+ changed = [left == @left, right == @right, top == @top, bottom == @bottom].any?(false)
41
+
42
+ @left = left
43
+ @top = top
44
+ @right = right
45
+ @bottom = bottom
46
+
47
+ nine_slice if changed
48
+ end
49
+
50
+ def left=(n)
51
+ nine_slice if n != @left
52
+ @left = n
53
+ n
54
+ end
55
+
56
+ def right=(n)
57
+ nine_slice if n != @right
58
+ @right = n
59
+ n
60
+ end
61
+
62
+ def top=(n)
63
+ nine_slice if n != @top
64
+ @top = n
65
+ n
66
+ end
67
+
68
+ def bottom=(n)
69
+ nine_slice if n != @bottom
70
+ @bottom = n
71
+ n
72
+ end
73
+
74
+ def nine_slice
75
+ # pp [@left, @top, @right, @bottom, @image.width, @image.height]
76
+
77
+ @segment_top_left = @image.subimage(0, 0, @left, @top)
78
+ @segment_top_right = @image.subimage(@image.width - @right, 0, @right, @top)
79
+
80
+ @segment_left = @image.subimage(0, @top, @left, @image.height - (@top + @bottom))
81
+ @segment_right = @image.subimage(@image.width - @right, @top, @left, @image.height - (@top + @bottom))
82
+
83
+ @segment_bottom_left = @image.subimage(0, @image.height - @bottom, @left, @bottom)
84
+ @segment_bottom_right = @image.subimage(@image.width - @right, @image.height - @bottom, @right, @bottom)
85
+
86
+ @segment_top = @image.subimage(@left, 0, @image.width - (@left + @right), @top)
87
+ @segment_bottom = @image.subimage(@left, @image.height - @bottom, @image.width - (@left + @right), @bottom)
88
+
89
+ @segment_middle = @image.subimage(@left, @top, @image.width - (@left + @right), @image.height - (@top + @bottom))
90
+ end
91
+
92
+ def cx
93
+ @x + @left
94
+ end
95
+
96
+ def cy
97
+ @y + @top
98
+ end
99
+
100
+ def cwidth
101
+ @cx - @width
102
+ end
103
+
104
+ def cheight
105
+ @cy - @height
106
+ end
107
+
108
+ def width_scale
109
+ scale = (@width.to_f - (@left + @right)) / (@image.width - (@left + @right))
110
+ scale.abs
111
+ end
112
+
113
+ def height_scale
114
+ scale = (@height - (@top + @bottom)).to_f / (@image.height - (@top + @bottom))
115
+ scale.abs
116
+ end
117
+
118
+ def draw
119
+ return unless @image && @segment_top_left
120
+
121
+ @mode == :tiled ? draw_tiled : draw_stretched
122
+ end
123
+
124
+ def draw_stretched
125
+ @segment_top_left.draw(@x, @y, @z, 1, 1, @color, @render_mode)
126
+ @segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale, 1, @color, @render_mode) # SCALE X
127
+ @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color, @render_mode)
128
+
129
+ @segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale, @color, @render_mode) # SCALE Y
130
+ @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color, @render_mode)
131
+ @segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale, 1, @color, @render_mode) # SCALE X
132
+ @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color, @render_mode)
133
+ @segment_left.draw(@x, @y + @top, @z, 1, height_scale, @color, @render_mode) # SCALE Y
134
+
135
+ @segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale, @color, @render_mode) # SCALE X and SCALE Y
136
+ end
137
+
138
+ def draw_tiled
139
+ @segment_top_left.draw(@x, @y, @z, 1, 1, @color, @render_mode)
140
+
141
+ # p [width_scale, height_scale]
142
+
143
+ Gosu.clip_to(@x + @segment_top_left.width, @y, @segment_top.width * width_scale, @segment_top.height) do
144
+ width_scale.ceil.times do |i|
145
+ @segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z, 1, 1, @color, @render_mode) # SCALE X
146
+ end
147
+ end
148
+
149
+ @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color, @render_mode)
150
+
151
+ Gosu.clip_to(@x + @width - @segment_top_right.width, @y + @top, @segment_right.width, @segment_right.height * height_scale) do
152
+ height_scale.ceil.times do |i|
153
+ @segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z, 1, 1, @color, @render_mode) # SCALE Y
154
+ end
155
+ end
156
+
157
+ @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color, @render_mode)
158
+
159
+ Gosu.clip_to(@x + @segment_top_left.width, @y + @height - @segment_bottom.height, @segment_top.width * width_scale, @segment_bottom.height) do
160
+ width_scale.ceil.times do |i|
161
+ @segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z, 1, 1, @color, @render_mode) # SCALE X
162
+ end
163
+ end
164
+
165
+ @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color, @render_mode)
166
+
167
+ Gosu.clip_to(@x, @y + @top, @segment_left.width, @segment_left.height * height_scale) do
168
+ height_scale.ceil.times do |i|
169
+ @segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z, 1, 1, @color, @render_mode) # SCALE Y
170
+ end
171
+ end
172
+
173
+ Gosu.clip_to(@x + @segment_top_left.width, @y + @segment_top.height, @width - (@segment_left.width + @segment_right.width), @height - (@segment_top.height + @segment_bottom.height)) do
174
+ height_scale.ceil.times do |y|
175
+ width_scale.ceil.times do |x|
176
+ @segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z, 1, 1, @color, @render_mode) # SCALE X and SCALE Y
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
@@ -1,150 +1,150 @@
1
- module CyberarmEngine
2
- class BoundingBox
3
- attr_accessor :min, :max
4
-
5
- def initialize(*args)
6
- case args.size
7
- when 0
8
- @min = Vector.new(0, 0, 0)
9
- @max = Vector.new(0, 0, 0)
10
- when 2
11
- @min = args.first.clone
12
- @max = args.last.clone
13
- when 4
14
- @min = Vector.new(args[0], args[1], 0)
15
- @max = Vector.new(args[2], args[3], 0)
16
- when 6
17
- @min = Vector.new(args[0], args[1], args[2])
18
- @max = Vector.new(args[3], args[4], args[5])
19
- else
20
- raise "Invalid number of arguments! Got: #{args.size}, expected: 0, 2, 4, or 6."
21
- end
22
- end
23
-
24
- def ==(other)
25
- @min == other.min &&
26
- @max == other.max
27
- end
28
-
29
- # returns a new bounding box that includes both bounding boxes
30
- def union(other)
31
- temp = BoundingBox.new
32
- temp.min.x = [@min.x, other.min.x].min
33
- temp.min.y = [@min.y, other.min.y].min
34
- temp.min.z = [@min.z, other.min.z].min
35
-
36
- temp.max.x = [@max.x, other.max.x].max
37
- temp.max.y = [@max.y, other.max.y].max
38
- temp.max.z = [@max.z, other.max.z].max
39
-
40
- temp
41
- end
42
-
43
- # returns the difference between both bounding boxes
44
- def difference(other)
45
- temp = BoundingBox.new
46
- temp.min = @min - other.min
47
- temp.max = @max - other.max
48
-
49
- temp
50
- end
51
-
52
- # returns whether bounding box intersects other
53
- def intersect?(other)
54
- if other.is_a?(Ray)
55
- other.intersect?(self)
56
- elsif other.is_a?(BoundingBox)
57
- (@min.x <= other.max.x && @max.x >= other.min.x) &&
58
- (@min.y <= other.max.y && @max.y >= other.min.y) &&
59
- (@min.z <= other.max.z && @max.z >= other.min.z)
60
- else
61
- raise "Unknown collider: #{other.class}"
62
- end
63
- end
64
-
65
- # does this bounding box envelop other bounding box? (inclusive of border)
66
- def contains?(other)
67
- other.min.x >= min.x && other.min.y >= min.y && other.min.z >= min.z &&
68
- other.max.x <= max.x && other.max.y <= max.y && other.max.z <= max.z
69
- end
70
-
71
- # returns whether the 3D vector is inside of the bounding box
72
- def inside?(vector)
73
- (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
74
- (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y)) &&
75
- (vector.z.between?(@min.z, @max.z) || vector.z.between?(@max.z, @min.z))
76
- end
77
-
78
- # returns whether the 2D vector is inside of the bounding box
79
- def point?(vector)
80
- (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
81
- (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y))
82
- end
83
-
84
- def volume
85
- width * height * depth
86
- end
87
-
88
- def width
89
- @max.x - @min.x
90
- end
91
-
92
- def height
93
- @max.y - @min.y
94
- end
95
-
96
- def depth
97
- @max.z - @min.z
98
- end
99
-
100
- def normalize(entity)
101
- temp = BoundingBox.new
102
- temp.min.x = @min.x.to_f * entity.scale.x
103
- temp.min.y = @min.y.to_f * entity.scale.y
104
- temp.min.z = @min.z.to_f * entity.scale.z
105
-
106
- temp.max.x = @max.x.to_f * entity.scale.x
107
- temp.max.y = @max.y.to_f * entity.scale.y
108
- temp.max.z = @max.z.to_f * entity.scale.z
109
-
110
- temp
111
- end
112
-
113
- def normalize_with_offset(entity)
114
- temp = BoundingBox.new
115
- temp.min.x = @min.x.to_f * entity.scale.x + entity.position.x
116
- temp.min.y = @min.y.to_f * entity.scale.y + entity.position.y
117
- temp.min.z = @min.z.to_f * entity.scale.z + entity.position.z
118
-
119
- temp.max.x = @max.x.to_f * entity.scale.x + entity.position.x
120
- temp.max.y = @max.y.to_f * entity.scale.y + entity.position.y
121
- temp.max.z = @max.z.to_f * entity.scale.z + entity.position.z
122
-
123
- temp
124
- end
125
-
126
- def +(other)
127
- box = BoundingBox.new
128
- box.min = min + other.min
129
- box.min = max + other.max
130
-
131
- box
132
- end
133
-
134
- def -(other)
135
- box = BoundingBox.new
136
- box.min = min - other.min
137
- box.min = max - other.max
138
-
139
- box
140
- end
141
-
142
- def sum
143
- @min.sum + @max.sum
144
- end
145
-
146
- def clone
147
- BoundingBox.new(@min.x, @min.y, @min.z, @max.x, @max.y, @max.z)
148
- end
149
- end
150
- end
1
+ module CyberarmEngine
2
+ class BoundingBox
3
+ attr_accessor :min, :max
4
+
5
+ def initialize(*args)
6
+ case args.size
7
+ when 0
8
+ @min = Vector.new(0, 0, 0)
9
+ @max = Vector.new(0, 0, 0)
10
+ when 2
11
+ @min = args.first.clone
12
+ @max = args.last.clone
13
+ when 4
14
+ @min = Vector.new(args[0], args[1], 0)
15
+ @max = Vector.new(args[2], args[3], 0)
16
+ when 6
17
+ @min = Vector.new(args[0], args[1], args[2])
18
+ @max = Vector.new(args[3], args[4], args[5])
19
+ else
20
+ raise "Invalid number of arguments! Got: #{args.size}, expected: 0, 2, 4, or 6."
21
+ end
22
+ end
23
+
24
+ def ==(other)
25
+ @min == other.min &&
26
+ @max == other.max
27
+ end
28
+
29
+ # returns a new bounding box that includes both bounding boxes
30
+ def union(other)
31
+ temp = BoundingBox.new
32
+ temp.min.x = [@min.x, other.min.x].min
33
+ temp.min.y = [@min.y, other.min.y].min
34
+ temp.min.z = [@min.z, other.min.z].min
35
+
36
+ temp.max.x = [@max.x, other.max.x].max
37
+ temp.max.y = [@max.y, other.max.y].max
38
+ temp.max.z = [@max.z, other.max.z].max
39
+
40
+ temp
41
+ end
42
+
43
+ # returns the difference between both bounding boxes
44
+ def difference(other)
45
+ temp = BoundingBox.new
46
+ temp.min = @min - other.min
47
+ temp.max = @max - other.max
48
+
49
+ temp
50
+ end
51
+
52
+ # returns whether bounding box intersects other
53
+ def intersect?(other)
54
+ if other.is_a?(Ray)
55
+ other.intersect?(self)
56
+ elsif other.is_a?(BoundingBox)
57
+ (@min.x <= other.max.x && @max.x >= other.min.x) &&
58
+ (@min.y <= other.max.y && @max.y >= other.min.y) &&
59
+ (@min.z <= other.max.z && @max.z >= other.min.z)
60
+ else
61
+ raise "Unknown collider: #{other.class}"
62
+ end
63
+ end
64
+
65
+ # does this bounding box envelop other bounding box? (inclusive of border)
66
+ def contains?(other)
67
+ other.min.x >= min.x && other.min.y >= min.y && other.min.z >= min.z &&
68
+ other.max.x <= max.x && other.max.y <= max.y && other.max.z <= max.z
69
+ end
70
+
71
+ # returns whether the 3D vector is inside of the bounding box
72
+ def inside?(vector)
73
+ (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
74
+ (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y)) &&
75
+ (vector.z.between?(@min.z, @max.z) || vector.z.between?(@max.z, @min.z))
76
+ end
77
+
78
+ # returns whether the 2D vector is inside of the bounding box
79
+ def point?(vector)
80
+ (vector.x.between?(@min.x, @max.x) || vector.x.between?(@max.x, @min.x)) &&
81
+ (vector.y.between?(@min.y, @max.y) || vector.y.between?(@max.y, @min.y))
82
+ end
83
+
84
+ def volume
85
+ width * height * depth
86
+ end
87
+
88
+ def width
89
+ @max.x - @min.x
90
+ end
91
+
92
+ def height
93
+ @max.y - @min.y
94
+ end
95
+
96
+ def depth
97
+ @max.z - @min.z
98
+ end
99
+
100
+ def normalize(entity)
101
+ temp = BoundingBox.new
102
+ temp.min.x = @min.x.to_f * entity.scale.x
103
+ temp.min.y = @min.y.to_f * entity.scale.y
104
+ temp.min.z = @min.z.to_f * entity.scale.z
105
+
106
+ temp.max.x = @max.x.to_f * entity.scale.x
107
+ temp.max.y = @max.y.to_f * entity.scale.y
108
+ temp.max.z = @max.z.to_f * entity.scale.z
109
+
110
+ temp
111
+ end
112
+
113
+ def normalize_with_offset(entity)
114
+ temp = BoundingBox.new
115
+ temp.min.x = @min.x.to_f * entity.scale.x + entity.position.x
116
+ temp.min.y = @min.y.to_f * entity.scale.y + entity.position.y
117
+ temp.min.z = @min.z.to_f * entity.scale.z + entity.position.z
118
+
119
+ temp.max.x = @max.x.to_f * entity.scale.x + entity.position.x
120
+ temp.max.y = @max.y.to_f * entity.scale.y + entity.position.y
121
+ temp.max.z = @max.z.to_f * entity.scale.z + entity.position.z
122
+
123
+ temp
124
+ end
125
+
126
+ def +(other)
127
+ box = BoundingBox.new
128
+ box.min = min + other.min
129
+ box.min = max + other.max
130
+
131
+ box
132
+ end
133
+
134
+ def -(other)
135
+ box = BoundingBox.new
136
+ box.min = min - other.min
137
+ box.min = max - other.max
138
+
139
+ box
140
+ end
141
+
142
+ def sum
143
+ @min.sum + @max.sum
144
+ end
145
+
146
+ def clone
147
+ BoundingBox.new(@min.x, @min.y, @min.z, @max.x, @max.y, @max.z)
148
+ end
149
+ end
150
+ end