bevy 1.0.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 (93) hide show
  1. checksums.yaml +7 -0
  2. data/Cargo.lock +4279 -0
  3. data/Cargo.toml +36 -0
  4. data/README.md +226 -0
  5. data/crates/bevy/Cargo.toml +52 -0
  6. data/crates/bevy/src/app.rs +43 -0
  7. data/crates/bevy/src/component.rs +111 -0
  8. data/crates/bevy/src/entity.rs +30 -0
  9. data/crates/bevy/src/error.rs +32 -0
  10. data/crates/bevy/src/event.rs +190 -0
  11. data/crates/bevy/src/input_bridge.rs +300 -0
  12. data/crates/bevy/src/lib.rs +42 -0
  13. data/crates/bevy/src/mesh_renderer.rs +328 -0
  14. data/crates/bevy/src/query.rs +53 -0
  15. data/crates/bevy/src/render_app.rs +689 -0
  16. data/crates/bevy/src/resource.rs +28 -0
  17. data/crates/bevy/src/schedule.rs +186 -0
  18. data/crates/bevy/src/sprite_renderer.rs +355 -0
  19. data/crates/bevy/src/system.rs +44 -0
  20. data/crates/bevy/src/text_renderer.rs +258 -0
  21. data/crates/bevy/src/types/color.rs +114 -0
  22. data/crates/bevy/src/types/dynamic.rs +131 -0
  23. data/crates/bevy/src/types/math.rs +260 -0
  24. data/crates/bevy/src/types/mod.rs +9 -0
  25. data/crates/bevy/src/types/transform.rs +166 -0
  26. data/crates/bevy/src/world.rs +163 -0
  27. data/crates/bevy_ruby_render/Cargo.toml +22 -0
  28. data/crates/bevy_ruby_render/src/asset.rs +360 -0
  29. data/crates/bevy_ruby_render/src/audio.rs +511 -0
  30. data/crates/bevy_ruby_render/src/camera.rs +365 -0
  31. data/crates/bevy_ruby_render/src/gamepad.rs +398 -0
  32. data/crates/bevy_ruby_render/src/lib.rs +26 -0
  33. data/crates/bevy_ruby_render/src/material.rs +310 -0
  34. data/crates/bevy_ruby_render/src/mesh.rs +491 -0
  35. data/crates/bevy_ruby_render/src/sprite.rs +289 -0
  36. data/ext/bevy/Cargo.toml +20 -0
  37. data/ext/bevy/extconf.rb +6 -0
  38. data/ext/bevy/src/conversions.rs +137 -0
  39. data/ext/bevy/src/lib.rs +29 -0
  40. data/ext/bevy/src/ruby_app.rs +65 -0
  41. data/ext/bevy/src/ruby_color.rs +149 -0
  42. data/ext/bevy/src/ruby_component.rs +189 -0
  43. data/ext/bevy/src/ruby_entity.rs +33 -0
  44. data/ext/bevy/src/ruby_math.rs +384 -0
  45. data/ext/bevy/src/ruby_query.rs +64 -0
  46. data/ext/bevy/src/ruby_render_app.rs +779 -0
  47. data/ext/bevy/src/ruby_system.rs +122 -0
  48. data/ext/bevy/src/ruby_world.rs +107 -0
  49. data/lib/bevy/animation.rb +597 -0
  50. data/lib/bevy/app.rb +675 -0
  51. data/lib/bevy/asset.rb +613 -0
  52. data/lib/bevy/audio.rb +545 -0
  53. data/lib/bevy/audio_effects.rb +224 -0
  54. data/lib/bevy/camera.rb +412 -0
  55. data/lib/bevy/component.rb +91 -0
  56. data/lib/bevy/diagnostics.rb +227 -0
  57. data/lib/bevy/ecs_advanced.rb +296 -0
  58. data/lib/bevy/event.rb +199 -0
  59. data/lib/bevy/gizmos.rb +158 -0
  60. data/lib/bevy/gltf.rb +227 -0
  61. data/lib/bevy/hierarchy.rb +444 -0
  62. data/lib/bevy/input.rb +514 -0
  63. data/lib/bevy/lighting.rb +369 -0
  64. data/lib/bevy/material.rb +248 -0
  65. data/lib/bevy/mesh.rb +257 -0
  66. data/lib/bevy/navigation.rb +344 -0
  67. data/lib/bevy/networking.rb +335 -0
  68. data/lib/bevy/particle.rb +337 -0
  69. data/lib/bevy/physics.rb +396 -0
  70. data/lib/bevy/plugins/default_plugins.rb +34 -0
  71. data/lib/bevy/plugins/input_plugin.rb +49 -0
  72. data/lib/bevy/reflect.rb +361 -0
  73. data/lib/bevy/render_graph.rb +210 -0
  74. data/lib/bevy/resource.rb +185 -0
  75. data/lib/bevy/scene.rb +254 -0
  76. data/lib/bevy/shader.rb +319 -0
  77. data/lib/bevy/shape.rb +195 -0
  78. data/lib/bevy/skeletal.rb +248 -0
  79. data/lib/bevy/sprite.rb +152 -0
  80. data/lib/bevy/sprite_sheet.rb +444 -0
  81. data/lib/bevy/state.rb +277 -0
  82. data/lib/bevy/system.rb +206 -0
  83. data/lib/bevy/text.rb +99 -0
  84. data/lib/bevy/text_advanced.rb +455 -0
  85. data/lib/bevy/timer.rb +147 -0
  86. data/lib/bevy/transform.rb +158 -0
  87. data/lib/bevy/ui.rb +454 -0
  88. data/lib/bevy/ui_advanced.rb +568 -0
  89. data/lib/bevy/version.rb +5 -0
  90. data/lib/bevy/visibility.rb +250 -0
  91. data/lib/bevy/window.rb +302 -0
  92. data/lib/bevy.rb +390 -0
  93. metadata +150 -0
@@ -0,0 +1,319 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bevy
4
+ class ShaderSource
5
+ attr_reader :vertex, :fragment, :compute
6
+
7
+ def initialize(vertex: nil, fragment: nil, compute: nil)
8
+ @vertex = vertex
9
+ @fragment = fragment
10
+ @compute = compute
11
+ end
12
+
13
+ def has_vertex?
14
+ !@vertex.nil?
15
+ end
16
+
17
+ def has_fragment?
18
+ !@fragment.nil?
19
+ end
20
+
21
+ def has_compute?
22
+ !@compute.nil?
23
+ end
24
+
25
+ def type_name
26
+ 'ShaderSource'
27
+ end
28
+ end
29
+
30
+ class Shader
31
+ attr_reader :name, :source, :path
32
+
33
+ def initialize(name:, source: nil, path: nil)
34
+ @name = name
35
+ @source = source
36
+ @path = path
37
+ end
38
+
39
+ def self.from_wgsl(name, wgsl_source)
40
+ new(name: name, source: ShaderSource.new(fragment: wgsl_source, vertex: wgsl_source))
41
+ end
42
+
43
+ def self.from_file(name, path)
44
+ new(name: name, path: path)
45
+ end
46
+
47
+ def loaded?
48
+ @source || @path
49
+ end
50
+
51
+ def type_name
52
+ 'Shader'
53
+ end
54
+ end
55
+
56
+ class ShaderDefVal
57
+ attr_reader :key, :value
58
+
59
+ def initialize(key, value)
60
+ @key = key.to_s
61
+ @value = value
62
+ end
63
+
64
+ def self.bool(key, value)
65
+ new(key, value ? 1 : 0)
66
+ end
67
+
68
+ def self.int(key, value)
69
+ new(key, value.to_i)
70
+ end
71
+
72
+ def self.uint(key, value)
73
+ new(key, value.to_i.abs)
74
+ end
75
+
76
+ def type_name
77
+ 'ShaderDefVal'
78
+ end
79
+ end
80
+
81
+ class ShaderDefs
82
+ def initialize
83
+ @defs = {}
84
+ end
85
+
86
+ def set(key, value)
87
+ @defs[key.to_s] = value
88
+ self
89
+ end
90
+
91
+ def get(key)
92
+ @defs[key.to_s]
93
+ end
94
+
95
+ def remove(key)
96
+ @defs.delete(key.to_s)
97
+ self
98
+ end
99
+
100
+ def to_h
101
+ @defs.dup
102
+ end
103
+
104
+ def type_name
105
+ 'ShaderDefs'
106
+ end
107
+ end
108
+
109
+ class PostProcessSettings
110
+ attr_accessor :enabled, :intensity
111
+
112
+ def initialize(enabled: true, intensity: 1.0)
113
+ @enabled = enabled
114
+ @intensity = intensity.to_f
115
+ end
116
+
117
+ def type_name
118
+ 'PostProcessSettings'
119
+ end
120
+ end
121
+
122
+ class Bloom
123
+ attr_accessor :intensity, :threshold, :soft_threshold, :composite_mode
124
+
125
+ def initialize(intensity: 0.5, threshold: 1.0, soft_threshold: 0.5, composite_mode: :additive)
126
+ @intensity = intensity.to_f
127
+ @threshold = threshold.to_f
128
+ @soft_threshold = soft_threshold.to_f
129
+ @composite_mode = composite_mode
130
+ end
131
+
132
+ def type_name
133
+ 'Bloom'
134
+ end
135
+
136
+ def to_h
137
+ {
138
+ intensity: @intensity,
139
+ threshold: @threshold,
140
+ soft_threshold: @soft_threshold,
141
+ composite_mode: @composite_mode
142
+ }
143
+ end
144
+ end
145
+
146
+ class ChromaticAberration
147
+ attr_accessor :intensity, :max_samples
148
+
149
+ def initialize(intensity: 0.02, max_samples: 8)
150
+ @intensity = intensity.to_f
151
+ @max_samples = max_samples
152
+ end
153
+
154
+ def type_name
155
+ 'ChromaticAberration'
156
+ end
157
+
158
+ def to_h
159
+ {
160
+ intensity: @intensity,
161
+ max_samples: @max_samples
162
+ }
163
+ end
164
+ end
165
+
166
+ class Vignette
167
+ attr_accessor :intensity, :radius, :smoothness, :color
168
+
169
+ def initialize(intensity: 0.5, radius: 0.5, smoothness: 0.5, color: nil)
170
+ @intensity = intensity.to_f
171
+ @radius = radius.to_f
172
+ @smoothness = smoothness.to_f
173
+ @color = color || Color.black
174
+ end
175
+
176
+ def type_name
177
+ 'Vignette'
178
+ end
179
+
180
+ def to_h
181
+ {
182
+ intensity: @intensity,
183
+ radius: @radius,
184
+ smoothness: @smoothness,
185
+ color: @color.to_a
186
+ }
187
+ end
188
+ end
189
+
190
+ class FilmGrain
191
+ attr_accessor :intensity, :response
192
+
193
+ def initialize(intensity: 0.1, response: 0.5)
194
+ @intensity = intensity.to_f
195
+ @response = response.to_f
196
+ end
197
+
198
+ def type_name
199
+ 'FilmGrain'
200
+ end
201
+
202
+ def to_h
203
+ {
204
+ intensity: @intensity,
205
+ response: @response
206
+ }
207
+ end
208
+ end
209
+
210
+ class Tonemapping
211
+ attr_accessor :mode
212
+
213
+ MODES = %i[none reinhard reinhard_luminance aces_fitted aces_approximate tony_mc_mapface blender_filmic].freeze
214
+
215
+ def initialize(mode: :tony_mc_mapface)
216
+ @mode = mode
217
+ end
218
+
219
+ def type_name
220
+ 'Tonemapping'
221
+ end
222
+ end
223
+
224
+ class ColorGrading
225
+ attr_accessor :exposure, :gamma, :saturation, :contrast
226
+
227
+ def initialize(exposure: 0.0, gamma: 1.0, saturation: 1.0, contrast: 1.0)
228
+ @exposure = exposure.to_f
229
+ @gamma = gamma.to_f
230
+ @saturation = saturation.to_f
231
+ @contrast = contrast.to_f
232
+ end
233
+
234
+ def type_name
235
+ 'ColorGrading'
236
+ end
237
+
238
+ def to_h
239
+ {
240
+ exposure: @exposure,
241
+ gamma: @gamma,
242
+ saturation: @saturation,
243
+ contrast: @contrast
244
+ }
245
+ end
246
+ end
247
+
248
+ class DepthOfField
249
+ attr_accessor :focal_distance, :focal_length, :aperture_f_stops, :max_blur
250
+
251
+ def initialize(focal_distance: 10.0, focal_length: 50.0, aperture_f_stops: 2.8, max_blur: 0.01)
252
+ @focal_distance = focal_distance.to_f
253
+ @focal_length = focal_length.to_f
254
+ @aperture_f_stops = aperture_f_stops.to_f
255
+ @max_blur = max_blur.to_f
256
+ end
257
+
258
+ def type_name
259
+ 'DepthOfField'
260
+ end
261
+
262
+ def to_h
263
+ {
264
+ focal_distance: @focal_distance,
265
+ focal_length: @focal_length,
266
+ aperture_f_stops: @aperture_f_stops,
267
+ max_blur: @max_blur
268
+ }
269
+ end
270
+ end
271
+
272
+ class MotionBlur
273
+ attr_accessor :shutter_angle, :samples
274
+
275
+ def initialize(shutter_angle: 0.5, samples: 4)
276
+ @shutter_angle = shutter_angle.to_f
277
+ @samples = samples
278
+ end
279
+
280
+ def type_name
281
+ 'MotionBlur'
282
+ end
283
+
284
+ def to_h
285
+ {
286
+ shutter_angle: @shutter_angle,
287
+ samples: @samples
288
+ }
289
+ end
290
+ end
291
+
292
+ class Fxaa
293
+ attr_accessor :enabled, :edge_threshold, :edge_threshold_min
294
+
295
+ def initialize(enabled: true, edge_threshold: :high, edge_threshold_min: :high)
296
+ @enabled = enabled
297
+ @edge_threshold = edge_threshold
298
+ @edge_threshold_min = edge_threshold_min
299
+ end
300
+
301
+ def type_name
302
+ 'Fxaa'
303
+ end
304
+ end
305
+
306
+ class Smaa
307
+ attr_accessor :preset
308
+
309
+ PRESETS = %i[low medium high ultra].freeze
310
+
311
+ def initialize(preset: :high)
312
+ @preset = preset
313
+ end
314
+
315
+ def type_name
316
+ 'Smaa'
317
+ end
318
+ end
319
+ end
data/lib/bevy/shape.rb ADDED
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bevy
4
+ module Shape
5
+ class Rectangle
6
+ attr_reader :width, :height, :color
7
+
8
+ def initialize(width:, height:, color: Color.white)
9
+ @width = width.to_f
10
+ @height = height.to_f
11
+ @color = color
12
+ end
13
+
14
+ def to_sprite
15
+ Sprite.new(
16
+ color: @color,
17
+ custom_size: Vec2.new(@width, @height)
18
+ )
19
+ end
20
+
21
+ def type_name
22
+ 'Shape::Rectangle'
23
+ end
24
+ end
25
+
26
+ class Circle
27
+ attr_reader :radius, :color, :segments
28
+
29
+ def initialize(radius:, color: Color.white, segments: 32)
30
+ @radius = radius.to_f
31
+ @color = color
32
+ @segments = segments
33
+ end
34
+
35
+ def diameter
36
+ @radius * 2.0
37
+ end
38
+
39
+ def to_sprite
40
+ Sprite.new(
41
+ color: @color,
42
+ custom_size: Vec2.new(diameter, diameter)
43
+ )
44
+ end
45
+
46
+ def type_name
47
+ 'Shape::Circle'
48
+ end
49
+ end
50
+
51
+ class Line
52
+ attr_reader :start_point, :end_point, :thickness, :color
53
+
54
+ def initialize(start_point:, end_point:, thickness: 2.0, color: Color.white)
55
+ @start_point = start_point
56
+ @end_point = end_point
57
+ @thickness = thickness.to_f
58
+ @color = color
59
+ end
60
+
61
+ def length
62
+ dx = @end_point.x - @start_point.x
63
+ dy = @end_point.y - @start_point.y
64
+ Math.sqrt(dx * dx + dy * dy)
65
+ end
66
+
67
+ def angle
68
+ dx = @end_point.x - @start_point.x
69
+ dy = @end_point.y - @start_point.y
70
+ Math.atan2(dy, dx)
71
+ end
72
+
73
+ def center
74
+ Vec2.new(
75
+ (@start_point.x + @end_point.x) / 2.0,
76
+ (@start_point.y + @end_point.y) / 2.0
77
+ )
78
+ end
79
+
80
+ def to_sprite
81
+ Sprite.new(
82
+ color: @color,
83
+ custom_size: Vec2.new(length, @thickness)
84
+ )
85
+ end
86
+
87
+ def to_transform(z: 0.0)
88
+ center_point = center
89
+ Transform.new(
90
+ translation: Vec3.new(center_point.x, center_point.y, z),
91
+ rotation: Quat.from_rotation_z(angle),
92
+ scale: Vec3.one
93
+ )
94
+ end
95
+
96
+ def type_name
97
+ 'Shape::Line'
98
+ end
99
+ end
100
+
101
+ class Polygon
102
+ attr_reader :points, :color
103
+
104
+ def initialize(points:, color: Color.white)
105
+ @points = points
106
+ @color = color
107
+ end
108
+
109
+ def centroid
110
+ return Vec2.zero if @points.empty?
111
+
112
+ sum_x = @points.sum(&:x)
113
+ sum_y = @points.sum(&:y)
114
+ Vec2.new(sum_x / @points.length, sum_y / @points.length)
115
+ end
116
+
117
+ def bounding_box
118
+ return { min: Vec2.zero, max: Vec2.zero } if @points.empty?
119
+
120
+ min_x = @points.map(&:x).min
121
+ max_x = @points.map(&:x).max
122
+ min_y = @points.map(&:y).min
123
+ max_y = @points.map(&:y).max
124
+
125
+ { min: Vec2.new(min_x, min_y), max: Vec2.new(max_x, max_y) }
126
+ end
127
+
128
+ def to_sprite
129
+ bbox = bounding_box
130
+ width = bbox[:max].x - bbox[:min].x
131
+ height = bbox[:max].y - bbox[:min].y
132
+
133
+ Sprite.new(
134
+ color: @color,
135
+ custom_size: Vec2.new(width, height)
136
+ )
137
+ end
138
+
139
+ def type_name
140
+ 'Shape::Polygon'
141
+ end
142
+ end
143
+
144
+ class RegularPolygon
145
+ attr_reader :radius, :sides, :color
146
+
147
+ def initialize(radius:, sides:, color: Color.white)
148
+ @radius = radius.to_f
149
+ @sides = [sides.to_i, 3].max
150
+ @color = color
151
+ end
152
+
153
+ def points
154
+ (0...@sides).map do |i|
155
+ angle = (2.0 * Math::PI * i / @sides) - (Math::PI / 2.0)
156
+ Vec2.new(
157
+ @radius * Math.cos(angle),
158
+ @radius * Math.sin(angle)
159
+ )
160
+ end
161
+ end
162
+
163
+ def to_sprite
164
+ Sprite.new(
165
+ color: @color,
166
+ custom_size: Vec2.new(@radius * 2, @radius * 2)
167
+ )
168
+ end
169
+
170
+ def type_name
171
+ 'Shape::RegularPolygon'
172
+ end
173
+ end
174
+
175
+ class Triangle < RegularPolygon
176
+ def initialize(radius:, color: Color.white)
177
+ super(radius: radius, sides: 3, color: color)
178
+ end
179
+
180
+ def type_name
181
+ 'Shape::Triangle'
182
+ end
183
+ end
184
+
185
+ class Hexagon < RegularPolygon
186
+ def initialize(radius:, color: Color.white)
187
+ super(radius: radius, sides: 6, color: color)
188
+ end
189
+
190
+ def type_name
191
+ 'Shape::Hexagon'
192
+ end
193
+ end
194
+ end
195
+ end