raylib-bindings 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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