raylib-bindings 0.5.7 → 0.5.8pre1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/raylib_helper.rb CHANGED
@@ -1,384 +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
- end
79
-
80
- class Vector3
81
- def self.create(x = 0, y = 0, z = 0)
82
- Vector3.new.set(x, y, z)
83
- end
84
-
85
- def self.copy_from(vec)
86
- Vector3.create(vec[:x], vec[:y], vec[:z])
87
- end
88
-
89
- def set(x, y, z)
90
- self[:x] = x
91
- self[:y] = y
92
- self[:z] = z
93
- self
94
- end
95
- end
96
-
97
- class Vector4
98
- def self.create(x = 0, y = 0, z = 0, w = 0)
99
- Vector4.new.set(x, y, z, w)
100
- end
101
-
102
- def self.copy_from(vec)
103
- Vector4.create(vec[:x], vec[:y], vec[:z], vec[:w])
104
- end
105
-
106
- def set(x, y, z, w)
107
- self[:x] = x
108
- self[:y] = y
109
- self[:z] = z
110
- self[:w] = w
111
- self
112
- end
113
- end
114
-
115
- class Quaternion
116
- def self.create(x = 0, y = 0, z = 0, w = 0)
117
- Quaternion.new.set(x, y, z, w)
118
- end
119
-
120
- def self.copy_from(quat)
121
- Quaternion.create(quat[:x], quat[:y], quat[:z], quat[:w])
122
- end
123
-
124
- def set(x, y, z, w)
125
- self[:x] = x
126
- self[:y] = y
127
- self[:z] = z
128
- self[:w] = w
129
- self
130
- end
131
- end
132
-
133
- class Rectangle
134
- def self.create(x = 0, y = 0, width = 0, height = 0)
135
- Rectangle.new.set(x, y, width, height)
136
- end
137
-
138
- def set(x, y, width, height)
139
- self[:x] = x
140
- self[:y] = y
141
- self[:width] = width
142
- self[:height] = height
143
- self
144
- end
145
- end
146
-
147
- class BoundingBox
148
- def self.create(*args)
149
- case args.size
150
- when 2
151
- instance = BoundingBox.new
152
- instance[:min] = args[0] # min
153
- instance[:max] = args[1] # max
154
- instance
155
- when 6
156
- instance = BoundingBox.new
157
- instance[:min] = Vector3.create(args[0], args[1], args[2]) # min_x, min_y, min_z
158
- instance[:max] = Vector3.create(args[3], args[4], args[5]) # max_x, max_y, max_z
159
- instance
160
- else
161
- raise ArgumentError.new 'BoundingBox.create : Number of arguments must be 2 or 6'
162
- end
163
- end
164
-
165
- def with_min(x, y, z)
166
- self[:min].set(x, y, z)
167
- self
168
- end
169
-
170
- def with_max(x, y, z)
171
- self[:max].set(x, y, z)
172
- self
173
- end
174
- end
175
-
176
- def Vector3ToFloat(vec)
177
- Vector3ToFloatV(vec)[:v].to_a
178
- end
179
-
180
- def MatrixToFloat(mat)
181
- MatrixToFloatV(mat)[:v].to_a
182
- end
183
-
184
- #
185
- # Camera helper
186
- #
187
-
188
- class Camera3D
189
- def with_position(x, y, z)
190
- self[:position].set(x, y, z)
191
- self
192
- end
193
-
194
- def with_target(x, y, z)
195
- self[:target].set(x, y, z)
196
- self
197
- end
198
-
199
- def with_up(x, y, z)
200
- self[:up].set(x, y, z)
201
- self
202
- end
203
-
204
- def with_fovy(fovy)
205
- self[:fovy] = fovy
206
- self
207
- end
208
-
209
- def with_projection(projection)
210
- self[:projection] = projection
211
- self
212
- end
213
- end
214
-
215
- class Camera2D
216
- def with_offset(x, y)
217
- self[:offset].set(x, y)
218
- self
219
- end
220
-
221
- def with_target(x, y)
222
- self[:target].set(x, y)
223
- self
224
- end
225
-
226
- def with_rotation(rotation)
227
- self[:rotation] = rotation
228
- self
229
- end
230
-
231
- def with_zoom(zoom)
232
- self[:zoom] = zoom
233
- self
234
- end
235
- end
236
-
237
- #
238
- # Transform helper
239
- #
240
-
241
- class Transform
242
- def t = self[:translation]
243
- def r = self[:rotation]
244
- def s = self[:scale]
245
- end
246
-
247
- #
248
- # Model helper
249
- #
250
-
251
- # DrawModelEx : Draw a model with extended parameters
252
- # @param model [Model]
253
- # @param position [Vector3]
254
- # @param rotationAxis [Vector3]
255
- # @param rotationAngle [float]
256
- # @param scale [Vector3]
257
- # @param tint [Color]
258
- # @return [void]
259
- def DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint)
260
- # [NOTE] Fixing unintended matrix modification
261
- # - In C, DrawModelEx uses the whole copy of `model` on stack, which will never affect the content of original `model`.
262
- # 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).
263
- # So here I copy the transform into `mtx_clone` and copy back this to the original after finished calling DrawModelEx.
264
- # - Other DrawXXX members (DrawModel, DrawModelWires, DrawModelWiresEx) are free from this problem.
265
- # - They call DrawModelEx in C layer, which will use the copy of `model` on stack.
266
- mtx_clone = model[:transform].clone
267
- internalDrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint)
268
- model[:transform] = mtx_clone
269
- end
270
-
271
- class Model
272
- # GetModelMaterial (ruby raylib original)
273
- # @param index [int] 0 ~ materialCount
274
- # @return [Material]
275
- def material(index = 0)
276
- Material.new(self[:materials] + index * Material.size)
277
- end
278
-
279
- # GetModelMaterialCount (ruby raylib original)
280
- # @return [int]
281
- def material_count
282
- self[:materialCount]
283
- end
284
-
285
- # GetModelBoneCount (ruby raylib original)
286
- # @return [int]
287
- def bone_count
288
- self[:boneCount]
289
- end
290
-
291
- # @return BoneInfo
292
- def bone_info(index)
293
- BoneInfo.new(self[:bones] + index * BoneInfo.size)
294
- end
295
-
296
- # @return Transform
297
- def bind_pose_transform(index)
298
- Transform.new(self[:bindPose] + index * Transform.size)
299
- end
300
- end
301
-
302
- class BoneInfo
303
- def parent_bone_index
304
- self[:parent]
305
- end
306
- end
307
-
308
- #
309
- # ModelAnimation helper
310
- #
311
-
312
- # Manages a set of ModelAnimation (ruby raylib original)
313
- class ModelAnimations
314
- attr_reader :anims, :anim_ptrs
315
-
316
- def initialize
317
- @anims = nil
318
- @anim_ptrs = nil
319
- @framePoses = nil # array of Transform**
320
- end
321
-
322
- def anim(index) = @anims[index]
323
- def anims_count = @anims.length
324
- def frame_count(index) = @anims[index][:frameCount]
325
-
326
- # @return BoneInfo
327
- def bone_info(anim_index, bone_index)
328
- BoneInfo.new(@anims[anim_index][:bones] + bone_index * BoneInfo.size)
329
- end
330
-
331
- # @return Transform*
332
- def frame_pose(index, frame)
333
- @framePoses[index] + frame * FFI::NativeType::POINTER.size # Transform*
334
- end
335
-
336
- # @return Transform
337
- def bone_transform(frame_pose, bone_index)
338
- Transform.new(frame_pose.read_pointer + bone_index * Transform.size)
339
- end
340
-
341
- # @return Transform
342
- def bone_transform_of_frame_pose(anim_index, frame, bone_index)
343
- bone_transform(frame_pose(anim_index, frame), bone_index)
344
- end
345
-
346
- # @return self
347
- def setup(fileName)
348
- @anims, @anim_ptrs = LoadAndAllocateModelAnimations(fileName)
349
- @framePoses = []
350
- @anims.each do |anim|
351
- @framePoses << anim[:framePoses]
352
- end
353
- self
354
- end
355
-
356
- def cleanup
357
- UnloadAndFreeModelAnimations(@anims, @anim_ptrs)
358
- end
359
- end
360
-
361
- # LoadAndAllocateModelAnimations : (ruby raylib original)
362
- # @param fileName [const char *]
363
- # @return array of ModelAnimation and pointer to loaded memory
364
- def LoadAndAllocateModelAnimations(fileName)
365
- animsCount_buf = FFI::MemoryPointer.new(:uint, 1)
366
- anim_ptrs = LoadModelAnimations(fileName, animsCount_buf)
367
- animsCount = animsCount_buf.read_uint
368
- anims = animsCount.times.map do |i|
369
- ModelAnimation.new(anim_ptrs + i * ModelAnimation.size)
370
- end
371
- return anims, anim_ptrs
372
- end
373
-
374
- # UnloadAndFreeModelAnimations : (ruby raylib original)
375
- # @param anims [array of ModelAnimation]
376
- # @param anim_ptrs [pointer to loaded memory]
377
- def UnloadAndFreeModelAnimations(anims, anim_ptrs)
378
- anims.each do |anim|
379
- UnloadModelAnimation(anim)
380
- end
381
- MemFree(anim_ptrs)
382
- end
383
-
384
- end
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