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