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,396 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bevy
4
+ module RigidBodyType
5
+ DYNAMIC = :dynamic
6
+ STATIC = :static
7
+ KINEMATIC = :kinematic
8
+ end
9
+
10
+ class RigidBody
11
+ attr_accessor :body_type, :mass, :gravity_scale, :linear_damping, :angular_damping
12
+ attr_accessor :linear_velocity, :angular_velocity
13
+ attr_accessor :locked_axes, :can_sleep, :sleeping
14
+
15
+ def initialize(
16
+ body_type: RigidBodyType::DYNAMIC,
17
+ mass: 1.0,
18
+ gravity_scale: 1.0,
19
+ linear_damping: 0.0,
20
+ angular_damping: 0.0
21
+ )
22
+ @body_type = body_type
23
+ @mass = mass.to_f
24
+ @gravity_scale = gravity_scale.to_f
25
+ @linear_damping = linear_damping.to_f
26
+ @angular_damping = angular_damping.to_f
27
+ @linear_velocity = Vec3.zero
28
+ @angular_velocity = Vec3.zero
29
+ @locked_axes = []
30
+ @can_sleep = true
31
+ @sleeping = false
32
+ end
33
+
34
+ def dynamic?
35
+ @body_type == RigidBodyType::DYNAMIC
36
+ end
37
+
38
+ def static?
39
+ @body_type == RigidBodyType::STATIC
40
+ end
41
+
42
+ def kinematic?
43
+ @body_type == RigidBodyType::KINEMATIC
44
+ end
45
+
46
+ def apply_impulse(impulse)
47
+ return unless dynamic?
48
+
49
+ @linear_velocity = Vec3.new(
50
+ @linear_velocity.x + impulse.x / @mass,
51
+ @linear_velocity.y + impulse.y / @mass,
52
+ @linear_velocity.z + impulse.z / @mass
53
+ )
54
+ end
55
+
56
+ def apply_force(force, delta)
57
+ return unless dynamic?
58
+
59
+ acceleration = Vec3.new(
60
+ force.x / @mass,
61
+ force.y / @mass,
62
+ force.z / @mass
63
+ )
64
+ @linear_velocity = Vec3.new(
65
+ @linear_velocity.x + acceleration.x * delta,
66
+ @linear_velocity.y + acceleration.y * delta,
67
+ @linear_velocity.z + acceleration.z * delta
68
+ )
69
+ end
70
+
71
+ def type_name
72
+ 'RigidBody'
73
+ end
74
+
75
+ def to_h
76
+ {
77
+ body_type: @body_type,
78
+ mass: @mass,
79
+ gravity_scale: @gravity_scale,
80
+ linear_damping: @linear_damping,
81
+ angular_damping: @angular_damping,
82
+ linear_velocity: [@linear_velocity.x, @linear_velocity.y, @linear_velocity.z],
83
+ angular_velocity: [@angular_velocity.x, @angular_velocity.y, @angular_velocity.z]
84
+ }
85
+ end
86
+ end
87
+
88
+ module ColliderShape
89
+ BALL = :ball
90
+ BOX = :box
91
+ CAPSULE = :capsule
92
+ CYLINDER = :cylinder
93
+ CONVEX_HULL = :convex_hull
94
+ TRIANGLE_MESH = :triangle_mesh
95
+ end
96
+
97
+ class Collider
98
+ attr_accessor :shape, :size, :radius, :height, :friction, :restitution
99
+ attr_accessor :sensor, :collision_groups
100
+
101
+ def initialize(
102
+ shape: ColliderShape::BOX,
103
+ size: nil,
104
+ radius: nil,
105
+ height: nil,
106
+ friction: 0.5,
107
+ restitution: 0.0,
108
+ sensor: false
109
+ )
110
+ @shape = shape
111
+ @size = size || Vec3.new(1.0, 1.0, 1.0)
112
+ @radius = radius || 0.5
113
+ @height = height || 1.0
114
+ @friction = friction.to_f
115
+ @restitution = restitution.to_f
116
+ @sensor = sensor
117
+ @collision_groups = 0xFFFFFFFF
118
+ end
119
+
120
+ def self.ball(radius)
121
+ new(shape: ColliderShape::BALL, radius: radius)
122
+ end
123
+
124
+ def self.box(half_extents)
125
+ new(shape: ColliderShape::BOX, size: half_extents)
126
+ end
127
+
128
+ def self.capsule(radius, height)
129
+ new(shape: ColliderShape::CAPSULE, radius: radius, height: height)
130
+ end
131
+
132
+ def self.cylinder(radius, height)
133
+ new(shape: ColliderShape::CYLINDER, radius: radius, height: height)
134
+ end
135
+
136
+ def sensor?
137
+ @sensor
138
+ end
139
+
140
+ def type_name
141
+ 'Collider'
142
+ end
143
+
144
+ def to_h
145
+ {
146
+ shape: @shape,
147
+ size: [@size.x, @size.y, @size.z],
148
+ radius: @radius,
149
+ height: @height,
150
+ friction: @friction,
151
+ restitution: @restitution,
152
+ sensor: @sensor
153
+ }
154
+ end
155
+ end
156
+
157
+ class CollisionEvent
158
+ attr_reader :entity_a, :entity_b, :collision_type
159
+
160
+ def initialize(entity_a, entity_b, collision_type = :started)
161
+ @entity_a = entity_a
162
+ @entity_b = entity_b
163
+ @collision_type = collision_type
164
+ end
165
+
166
+ def started?
167
+ @collision_type == :started
168
+ end
169
+
170
+ def stopped?
171
+ @collision_type == :stopped
172
+ end
173
+
174
+ def type_name
175
+ 'CollisionEvent'
176
+ end
177
+ end
178
+
179
+ class ContactPoint
180
+ attr_reader :position, :normal, :depth
181
+
182
+ def initialize(position:, normal:, depth: 0.0)
183
+ @position = position
184
+ @normal = normal
185
+ @depth = depth.to_f
186
+ end
187
+
188
+ def type_name
189
+ 'ContactPoint'
190
+ end
191
+ end
192
+
193
+ class Collision
194
+ attr_reader :entity_a, :entity_b, :contacts
195
+
196
+ def initialize(entity_a, entity_b, contacts = [])
197
+ @entity_a = entity_a
198
+ @entity_b = entity_b
199
+ @contacts = contacts
200
+ end
201
+
202
+ def type_name
203
+ 'Collision'
204
+ end
205
+ end
206
+
207
+ class Velocity
208
+ attr_accessor :linear, :angular
209
+
210
+ def initialize(linear: nil, angular: nil)
211
+ @linear = linear || Vec3.zero
212
+ @angular = angular || Vec3.zero
213
+ end
214
+
215
+ def type_name
216
+ 'Velocity'
217
+ end
218
+
219
+ def to_h
220
+ {
221
+ linear: [@linear.x, @linear.y, @linear.z],
222
+ angular: [@angular.x, @angular.y, @angular.z]
223
+ }
224
+ end
225
+ end
226
+
227
+ class ExternalForce
228
+ attr_accessor :force, :torque
229
+
230
+ def initialize(force: nil, torque: nil)
231
+ @force = force || Vec3.zero
232
+ @torque = torque || Vec3.zero
233
+ end
234
+
235
+ def apply(force_vec)
236
+ @force = Vec3.new(
237
+ @force.x + force_vec.x,
238
+ @force.y + force_vec.y,
239
+ @force.z + force_vec.z
240
+ )
241
+ end
242
+
243
+ def apply_torque(torque_vec)
244
+ @torque = Vec3.new(
245
+ @torque.x + torque_vec.x,
246
+ @torque.y + torque_vec.y,
247
+ @torque.z + torque_vec.z
248
+ )
249
+ end
250
+
251
+ def clear
252
+ @force = Vec3.zero
253
+ @torque = Vec3.zero
254
+ end
255
+
256
+ def type_name
257
+ 'ExternalForce'
258
+ end
259
+ end
260
+
261
+ class ExternalImpulse
262
+ attr_accessor :impulse, :torque_impulse
263
+
264
+ def initialize(impulse: nil, torque_impulse: nil)
265
+ @impulse = impulse || Vec3.zero
266
+ @torque_impulse = torque_impulse || Vec3.zero
267
+ end
268
+
269
+ def apply(impulse_vec)
270
+ @impulse = Vec3.new(
271
+ @impulse.x + impulse_vec.x,
272
+ @impulse.y + impulse_vec.y,
273
+ @impulse.z + impulse_vec.z
274
+ )
275
+ end
276
+
277
+ def clear
278
+ @impulse = Vec3.zero
279
+ @torque_impulse = Vec3.zero
280
+ end
281
+
282
+ def type_name
283
+ 'ExternalImpulse'
284
+ end
285
+ end
286
+
287
+ class GravityScale
288
+ attr_accessor :scale
289
+
290
+ def initialize(scale = 1.0)
291
+ @scale = scale.to_f
292
+ end
293
+
294
+ def type_name
295
+ 'GravityScale'
296
+ end
297
+ end
298
+
299
+ class LockedAxes
300
+ attr_accessor :translation_locked, :rotation_locked
301
+
302
+ def initialize(translation_locked: [], rotation_locked: [])
303
+ @translation_locked = translation_locked
304
+ @rotation_locked = rotation_locked
305
+ end
306
+
307
+ def lock_translation_x
308
+ @translation_locked << :x unless @translation_locked.include?(:x)
309
+ self
310
+ end
311
+
312
+ def lock_translation_y
313
+ @translation_locked << :y unless @translation_locked.include?(:y)
314
+ self
315
+ end
316
+
317
+ def lock_translation_z
318
+ @translation_locked << :z unless @translation_locked.include?(:z)
319
+ self
320
+ end
321
+
322
+ def lock_rotation_x
323
+ @rotation_locked << :x unless @rotation_locked.include?(:x)
324
+ self
325
+ end
326
+
327
+ def lock_rotation_y
328
+ @rotation_locked << :y unless @rotation_locked.include?(:y)
329
+ self
330
+ end
331
+
332
+ def lock_rotation_z
333
+ @rotation_locked << :z unless @rotation_locked.include?(:z)
334
+ self
335
+ end
336
+
337
+ def type_name
338
+ 'LockedAxes'
339
+ end
340
+ end
341
+
342
+ class PhysicsWorld
343
+ attr_accessor :gravity, :timestep
344
+
345
+ def initialize(gravity: nil, timestep: 1.0 / 60.0)
346
+ @gravity = gravity || Vec3.new(0.0, -9.81, 0.0)
347
+ @timestep = timestep.to_f
348
+ @collisions = []
349
+ end
350
+
351
+ def add_collision(collision)
352
+ @collisions << collision
353
+ end
354
+
355
+ def collisions
356
+ @collisions.dup
357
+ end
358
+
359
+ def clear_collisions
360
+ @collisions.clear
361
+ end
362
+
363
+ def type_name
364
+ 'PhysicsWorld'
365
+ end
366
+ end
367
+
368
+ class RayCast
369
+ attr_reader :origin, :direction, :max_distance
370
+
371
+ def initialize(origin:, direction:, max_distance: Float::INFINITY)
372
+ @origin = origin
373
+ @direction = direction.normalize
374
+ @max_distance = max_distance
375
+ end
376
+
377
+ def type_name
378
+ 'RayCast'
379
+ end
380
+ end
381
+
382
+ class RayCastHit
383
+ attr_reader :entity, :point, :normal, :distance
384
+
385
+ def initialize(entity:, point:, normal:, distance:)
386
+ @entity = entity
387
+ @point = point
388
+ @normal = normal
389
+ @distance = distance.to_f
390
+ end
391
+
392
+ def type_name
393
+ 'RayCastHit'
394
+ end
395
+ end
396
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bevy
4
+ module Plugins
5
+ class DefaultPlugins < Plugin
6
+ def build(app)
7
+ add_core_plugins(app)
8
+ add_input_plugins(app) unless app.respond_to?(:headless?) && app.headless?
9
+ add_render_plugins(app) if app.render_enabled?
10
+ end
11
+
12
+ private
13
+
14
+ def add_core_plugins(app)
15
+ app.insert_resource(Time.new) unless app.resources.has?(Time)
16
+ app.insert_resource(FixedTime.new) unless app.resources.has?(FixedTime)
17
+ end
18
+
19
+ def add_input_plugins(app)
20
+ app.add_plugins(InputPlugin.new) unless app.resources.has?(KeyboardInput)
21
+ end
22
+
23
+ def add_render_plugins(app)
24
+ end
25
+ end
26
+
27
+ class MinimalPlugins < Plugin
28
+ def build(app)
29
+ app.insert_resource(Time.new) unless app.resources.has?(Time)
30
+ app.insert_resource(FixedTime.new) unless app.resources.has?(FixedTime)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bevy
4
+ module Plugins
5
+ class InputPlugin < Plugin
6
+ def build(app)
7
+ setup_keyboard(app)
8
+ setup_mouse(app)
9
+ setup_gamepads(app)
10
+ setup_touch(app) if respond_to?(:touch_enabled?) && touch_enabled?
11
+ end
12
+
13
+ private
14
+
15
+ def setup_keyboard(app)
16
+ app.insert_resource(KeyboardInput.new) unless app.resources.has?(KeyboardInput)
17
+ end
18
+
19
+ def setup_mouse(app)
20
+ app.insert_resource(MouseInput.new) unless app.resources.has?(MouseInput)
21
+ end
22
+
23
+ def setup_gamepads(app)
24
+ app.insert_resource(Gamepads.new) unless app.resources.has?(Gamepads)
25
+ end
26
+
27
+ def setup_touch(app)
28
+ end
29
+ end
30
+
31
+ class KeyboardPlugin < Plugin
32
+ def build(app)
33
+ app.insert_resource(KeyboardInput.new) unless app.resources.has?(KeyboardInput)
34
+ end
35
+ end
36
+
37
+ class MousePlugin < Plugin
38
+ def build(app)
39
+ app.insert_resource(MouseInput.new) unless app.resources.has?(MouseInput)
40
+ end
41
+ end
42
+
43
+ class GamepadPlugin < Plugin
44
+ def build(app)
45
+ app.insert_resource(Gamepads.new) unless app.resources.has?(Gamepads)
46
+ end
47
+ end
48
+ end
49
+ end