raylib-bindings 0.5.8pre1-arm64-darwin

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.
data/lib/raylib.rb ADDED
@@ -0,0 +1,62 @@
1
+ # Yet another raylib wrapper for Ruby
2
+ #
3
+ # * https://github.com/vaiorabbit/raylib-bindings
4
+
5
+ require 'ffi'
6
+ require 'fileutils'
7
+ require_relative 'raylib_main'
8
+ require_relative 'config'
9
+ require_relative 'raymath'
10
+ require_relative 'rcamera'
11
+ require_relative 'rlgl'
12
+ require_relative 'raygui_main'
13
+ require_relative 'physac'
14
+ require_relative 'raylib_helper'
15
+ require_relative 'raygui_helper'
16
+
17
+ module Raylib
18
+ extend FFI::Library
19
+
20
+ def self.load_lib(libpath, raygui_libpath: nil, physac_libpath: nil)
21
+ lib_paths = [libpath, raygui_libpath, physac_libpath].compact
22
+
23
+ ffi_lib_flags :now, :global
24
+ ffi_lib(*lib_paths)
25
+ setup_symbols
26
+
27
+ setup_raygui_symbols unless raygui_libpath.nil?
28
+ setup_physac_symbols unless physac_libpath.nil?
29
+ rescue LoadError => e
30
+ warn e
31
+ end
32
+
33
+ def self.setup_symbols
34
+ setup_raylib_symbols
35
+ setup_raymath_symbols
36
+ setup_rcamera_symbols
37
+ setup_rlgl_symbols
38
+ end
39
+
40
+ #
41
+ # Generate sample code
42
+ #
43
+ def self.template
44
+ # Copy template code to user's current directory
45
+ example_path = "#{Gem::Specification.find_by_name('raylib-bindings').full_gem_path}/examples"
46
+ template_code_src = "#{example_path}/template.rb"
47
+ unless File.exist? template_code_src
48
+ warn "[Error] Raylib.template : Template source #{template_code_src} not found"
49
+ return false
50
+ end
51
+
52
+ template_code_dst = "#{Dir.getwd}/template.rb"
53
+ if File.exist? template_code_dst
54
+ warn "[Error] Raylib.template : Template destination #{template_code_dst} already exists"
55
+ return false
56
+ end
57
+
58
+ warn "[Info] Raylib.template : #{template_code_src} => #{template_code_dst}"
59
+ FileUtils.copy template_code_src, template_code_dst
60
+ warn '[Info] Raylib.template : Done'
61
+ end
62
+ end
@@ -0,0 +1,400 @@
1
+ # Yet another raylib wrapper for Ruby
2
+ #
3
+ # * https://github.com/vaiorabbit/raylib-bindings
4
+
5
+ module Raylib
6
+ #
7
+ # Color helper
8
+ #
9
+
10
+ class Color
11
+ def self.from_u8(r = 0, g = 0, b = 0, a = 255)
12
+ Color.new.set(r, g, b, a)
13
+ end
14
+
15
+ def set(r, g, b, a)
16
+ self[:r] = r
17
+ self[:g] = g
18
+ self[:b] = b
19
+ self[:a] = a
20
+ self
21
+ end
22
+
23
+ def copy(other)
24
+ self[:r] = other.r
25
+ self[:g] = other.g
26
+ self[:b] = other.b
27
+ self[:a] = other.a
28
+ self
29
+ end
30
+ end
31
+
32
+ LIGHTGRAY = Color.from_u8(200, 200, 200, 255)
33
+ GRAY = Color.from_u8(130, 130, 130, 255)
34
+ DARKGRAY = Color.from_u8(80, 80, 80, 255)
35
+ YELLOW = Color.from_u8(253, 249, 0, 255)
36
+ GOLD = Color.from_u8(255, 203, 0, 255)
37
+ ORANGE = Color.from_u8(255, 161, 0, 255)
38
+ PINK = Color.from_u8(255, 109, 194, 255)
39
+ RED = Color.from_u8(230, 41, 55, 255)
40
+ MAROON = Color.from_u8(190, 33, 55, 255)
41
+ GREEN = Color.from_u8(0, 228, 48, 255)
42
+ LIME = Color.from_u8(0, 158, 47, 255)
43
+ DARKGREEN = Color.from_u8(0, 117, 44, 255)
44
+ SKYBLUE = Color.from_u8(102, 191, 255, 255)
45
+ BLUE = Color.from_u8(0, 121, 241, 255)
46
+ DARKBLUE = Color.from_u8(0, 82, 172, 255)
47
+ PURPLE = Color.from_u8(200, 122, 255, 255)
48
+ VIOLET = Color.from_u8(135, 60, 190, 255)
49
+ DARKPURPLE = Color.from_u8(112, 31, 126, 255)
50
+ BEIGE = Color.from_u8(211, 176, 131, 255)
51
+ BROWN = Color.from_u8(127, 106, 79, 255)
52
+ DARKBROWN = Color.from_u8(76, 63, 47, 255)
53
+
54
+ WHITE = Color.from_u8(255, 255, 255, 255)
55
+ BLACK = Color.from_u8(0, 0, 0, 255)
56
+ BLANK = Color.from_u8(0, 0, 0, 0)
57
+ MAGENTA = Color.from_u8(255, 0, 255, 255)
58
+ RAYWHITE = Color.from_u8(245, 245, 245, 255)
59
+
60
+ #
61
+ # Math helper
62
+ #
63
+
64
+ class Vector2
65
+ def self.create(x = 0, y = 0)
66
+ Vector2.new.set(x, y)
67
+ end
68
+
69
+ def self.copy_from(vec)
70
+ Vector2.create(vec[:x], vec[:y])
71
+ end
72
+
73
+ def set(x, y)
74
+ self[:x] = x
75
+ self[:y] = y
76
+ self
77
+ end
78
+
79
+ def to_a
80
+ [x, y]
81
+ end
82
+ end
83
+
84
+ class Vector3
85
+ def self.create(x = 0, y = 0, z = 0)
86
+ Vector3.new.set(x, y, z)
87
+ end
88
+
89
+ def self.copy_from(vec)
90
+ Vector3.create(vec[:x], vec[:y], vec[:z])
91
+ end
92
+
93
+ def set(x, y, z)
94
+ self[:x] = x
95
+ self[:y] = y
96
+ self[:z] = z
97
+ self
98
+ end
99
+
100
+ def to_a
101
+ [x, y, z]
102
+ end
103
+ end
104
+
105
+ class Vector4
106
+ def self.create(x = 0, y = 0, z = 0, w = 0)
107
+ Vector4.new.set(x, y, z, w)
108
+ end
109
+
110
+ def self.copy_from(vec)
111
+ Vector4.create(vec[:x], vec[:y], vec[:z], vec[:w])
112
+ end
113
+
114
+ def set(x, y, z, w)
115
+ self[:x] = x
116
+ self[:y] = y
117
+ self[:z] = z
118
+ self[:w] = w
119
+ self
120
+ end
121
+
122
+ def to_a
123
+ [x, y, z, w]
124
+ end
125
+ end
126
+
127
+ class Quaternion
128
+ def self.create(x = 0, y = 0, z = 0, w = 0)
129
+ Quaternion.new.set(x, y, z, w)
130
+ end
131
+
132
+ def self.copy_from(quat)
133
+ Quaternion.create(quat[:x], quat[:y], quat[:z], quat[:w])
134
+ end
135
+
136
+ def set(x, y, z, w)
137
+ self[:x] = x
138
+ self[:y] = y
139
+ self[:z] = z
140
+ self[:w] = w
141
+ self
142
+ end
143
+
144
+ def to_a
145
+ [x, y, z, w]
146
+ end
147
+ end
148
+
149
+ class Rectangle
150
+ def self.create(x = 0, y = 0, width = 0, height = 0)
151
+ Rectangle.new.set(x, y, width, height)
152
+ end
153
+
154
+ def set(x, y, width, height)
155
+ self[:x] = x
156
+ self[:y] = y
157
+ self[:width] = width
158
+ self[:height] = height
159
+ self
160
+ end
161
+ end
162
+
163
+ class BoundingBox
164
+ def self.create(*args)
165
+ case args.size
166
+ when 2
167
+ instance = BoundingBox.new
168
+ instance[:min] = args[0] # min
169
+ instance[:max] = args[1] # max
170
+ instance
171
+ when 6
172
+ instance = BoundingBox.new
173
+ instance[:min] = Vector3.create(args[0], args[1], args[2]) # min_x, min_y, min_z
174
+ instance[:max] = Vector3.create(args[3], args[4], args[5]) # max_x, max_y, max_z
175
+ instance
176
+ else
177
+ raise ArgumentError.new 'BoundingBox.create : Number of arguments must be 2 or 6'
178
+ end
179
+ end
180
+
181
+ def with_min(x, y, z)
182
+ self[:min].set(x, y, z)
183
+ self
184
+ end
185
+
186
+ def with_max(x, y, z)
187
+ self[:max].set(x, y, z)
188
+ self
189
+ end
190
+ end
191
+
192
+ def Vector3ToFloat(vec)
193
+ Vector3ToFloatV(vec)[:v].to_a
194
+ end
195
+
196
+ def MatrixToFloat(mat)
197
+ MatrixToFloatV(mat)[:v].to_a
198
+ end
199
+
200
+ #
201
+ # Camera helper
202
+ #
203
+
204
+ class Camera3D
205
+ def with_position(x, y, z)
206
+ self[:position].set(x, y, z)
207
+ self
208
+ end
209
+
210
+ def with_target(x, y, z)
211
+ self[:target].set(x, y, z)
212
+ self
213
+ end
214
+
215
+ def with_up(x, y, z)
216
+ self[:up].set(x, y, z)
217
+ self
218
+ end
219
+
220
+ def with_fovy(fovy)
221
+ self[:fovy] = fovy
222
+ self
223
+ end
224
+
225
+ def with_projection(projection)
226
+ self[:projection] = projection
227
+ self
228
+ end
229
+ end
230
+
231
+ class Camera2D
232
+ def with_offset(x, y)
233
+ self[:offset].set(x, y)
234
+ self
235
+ end
236
+
237
+ def with_target(x, y)
238
+ self[:target].set(x, y)
239
+ self
240
+ end
241
+
242
+ def with_rotation(rotation)
243
+ self[:rotation] = rotation
244
+ self
245
+ end
246
+
247
+ def with_zoom(zoom)
248
+ self[:zoom] = zoom
249
+ self
250
+ end
251
+ end
252
+
253
+ #
254
+ # Transform helper
255
+ #
256
+
257
+ class Transform
258
+ def t = self[:translation]
259
+ def r = self[:rotation]
260
+ def s = self[:scale]
261
+ end
262
+
263
+ #
264
+ # Model helper
265
+ #
266
+
267
+ # DrawModelEx : Draw a model with extended parameters
268
+ # @param model [Model]
269
+ # @param position [Vector3]
270
+ # @param rotationAxis [Vector3]
271
+ # @param rotationAngle [float]
272
+ # @param scale [Vector3]
273
+ # @param tint [Color]
274
+ # @return [void]
275
+ def DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint)
276
+ # [NOTE] Fixing unintended matrix modification
277
+ # - In C, DrawModelEx uses the whole copy of `model` on stack, which will never affect the content of original `model`.
278
+ # But Ruby FFI seems to pass the reference of `model` to DrawModelEx, which results in transform accumulation (e.g.:`model` get rotated by `rotationAngle` around `rotationAxis` every frame).
279
+ # So here I copy the transform into `mtx_clone` and copy back this to the original after finished calling DrawModelEx.
280
+ # - Other DrawXXX members (DrawModel, DrawModelWires, DrawModelWiresEx) are free from this problem.
281
+ # - They call DrawModelEx in C layer, which will use the copy of `model` on stack.
282
+ mtx_clone = model[:transform].clone
283
+ internalDrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint)
284
+ model[:transform] = mtx_clone
285
+ end
286
+
287
+ class Model
288
+ # GetModelMaterial (ruby raylib original)
289
+ # @param index [int] 0 ~ materialCount
290
+ # @return [Material]
291
+ def material(index = 0)
292
+ Material.new(self[:materials] + index * Material.size)
293
+ end
294
+
295
+ # GetModelMaterialCount (ruby raylib original)
296
+ # @return [int]
297
+ def material_count
298
+ self[:materialCount]
299
+ end
300
+
301
+ # GetModelBoneCount (ruby raylib original)
302
+ # @return [int]
303
+ def bone_count
304
+ self[:boneCount]
305
+ end
306
+
307
+ # @return BoneInfo
308
+ def bone_info(index)
309
+ BoneInfo.new(self[:bones] + index * BoneInfo.size)
310
+ end
311
+
312
+ # @return Transform
313
+ def bind_pose_transform(index)
314
+ Transform.new(self[:bindPose] + index * Transform.size)
315
+ end
316
+ end
317
+
318
+ class BoneInfo
319
+ def parent_bone_index
320
+ self[:parent]
321
+ end
322
+ end
323
+
324
+ #
325
+ # ModelAnimation helper
326
+ #
327
+
328
+ # Manages a set of ModelAnimation (ruby raylib original)
329
+ class ModelAnimations
330
+ attr_reader :anims, :anim_ptrs
331
+
332
+ def initialize
333
+ @anims = nil
334
+ @anim_ptrs = nil
335
+ @framePoses = nil # array of Transform**
336
+ end
337
+
338
+ def anim(index) = @anims[index]
339
+ def anims_count = @anims.length
340
+ def frame_count(index) = @anims[index][:frameCount]
341
+
342
+ # @return BoneInfo
343
+ def bone_info(anim_index, bone_index)
344
+ BoneInfo.new(@anims[anim_index][:bones] + bone_index * BoneInfo.size)
345
+ end
346
+
347
+ # @return Transform*
348
+ def frame_pose(index, frame)
349
+ @framePoses[index] + frame * FFI::NativeType::POINTER.size # Transform*
350
+ end
351
+
352
+ # @return Transform
353
+ def bone_transform(frame_pose, bone_index)
354
+ Transform.new(frame_pose.read_pointer + bone_index * Transform.size)
355
+ end
356
+
357
+ # @return Transform
358
+ def bone_transform_of_frame_pose(anim_index, frame, bone_index)
359
+ bone_transform(frame_pose(anim_index, frame), bone_index)
360
+ end
361
+
362
+ # @return self
363
+ def setup(fileName)
364
+ @anims, @anim_ptrs = LoadAndAllocateModelAnimations(fileName)
365
+ @framePoses = []
366
+ @anims.each do |anim|
367
+ @framePoses << anim[:framePoses]
368
+ end
369
+ self
370
+ end
371
+
372
+ def cleanup
373
+ UnloadAndFreeModelAnimations(@anims, @anim_ptrs)
374
+ end
375
+ end
376
+
377
+ # LoadAndAllocateModelAnimations : (ruby raylib original)
378
+ # @param fileName [const char *]
379
+ # @return array of ModelAnimation and pointer to loaded memory
380
+ def LoadAndAllocateModelAnimations(fileName)
381
+ animsCount_buf = FFI::MemoryPointer.new(:uint, 1)
382
+ anim_ptrs = LoadModelAnimations(fileName, animsCount_buf)
383
+ animsCount = animsCount_buf.read_uint
384
+ anims = animsCount.times.map do |i|
385
+ ModelAnimation.new(anim_ptrs + i * ModelAnimation.size)
386
+ end
387
+ return anims, anim_ptrs
388
+ end
389
+
390
+ # UnloadAndFreeModelAnimations : (ruby raylib original)
391
+ # @param anims [array of ModelAnimation]
392
+ # @param anim_ptrs [pointer to loaded memory]
393
+ def UnloadAndFreeModelAnimations(anims, anim_ptrs)
394
+ anims.each do |anim|
395
+ UnloadModelAnimation(anim)
396
+ end
397
+ MemFree(anim_ptrs)
398
+ end
399
+
400
+ end