cglm 0.1.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.
@@ -0,0 +1,724 @@
1
+ #include "rb_cglm.h"
2
+
3
+ VALUE rb_cglm_vec4_aref(VALUE self, VALUE index) {
4
+ CHECK_RANGE(index, 0, 3);
5
+ return DBL2NUM(VAL2VEC4(self)[NUM2INT(index)]);
6
+ }
7
+
8
+ VALUE rb_cglm_vec4_aset(VALUE self, VALUE index, VALUE val) {
9
+ CHECK_RANGE(index, 0, 3);
10
+ VAL2VEC4(self)[NUM2INT(index)] = NUM2DBL(val);
11
+ return self;
12
+ }
13
+
14
+ VALUE rb_cglm_vec4_size_bytes(VALUE klass) { return SIZET2NUM(vec4_size()); }
15
+
16
+ VALUE rb_cglm_vec4_alignment_bytes(VALUE klass) { return SIZET2NUM(VEC4_ALIGNMENT); }
17
+
18
+ /* call-seq: to_vec3([dest]) => dest | new Vec3 */
19
+ VALUE rb_cglm_vec4_to_vec3(int argc, VALUE *argv, VALUE self) {
20
+ VALUE dest;
21
+ rb_scan_args(argc, argv, "01", &dest);
22
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
23
+ glm_vec3(VAL2VEC4(self), VAL2VEC3(dest));
24
+ return dest;
25
+ }
26
+
27
+ VALUE rb_cglm_vec4_one(VALUE self) {
28
+ VALUE dest = VEC4_NEW(ALLOC_VEC4);
29
+ vec4 one = GLM_VEC4_ONE;
30
+ memcpy(&VAL2VEC4(dest), &one, sizeof(vec4));
31
+ return dest;
32
+ }
33
+
34
+ VALUE rb_cglm_vec4_black(VALUE self) {
35
+ VALUE dest = VEC4_NEW(ALLOC_VEC4);
36
+ vec4 black = GLM_VEC4_BLACK;
37
+ memcpy(&VAL2VEC4(dest), &black, sizeof(vec4));
38
+ return dest;
39
+ }
40
+
41
+ VALUE rb_cglm_vec4_zero(VALUE self) {
42
+ VALUE dest = VEC4_NEW(ALLOC_VEC4);
43
+ vec4 zero = GLM_VEC4_ZERO;
44
+ memcpy(&VAL2VEC4(dest), &zero, sizeof(vec4));
45
+ return dest;
46
+ }
47
+
48
+ VALUE rb_cglm_vec4_copy_to(VALUE self, VALUE other) {
49
+ glm_vec4_copy(VAL2VEC4(self), VAL2VEC4(other));
50
+ return other;
51
+ }
52
+
53
+ /* call-seq: zero! => self
54
+ *
55
+ * Sets all fields in `self` to `0` and returns `self`.
56
+ */
57
+ VALUE rb_cglm_vec4_zero_self(VALUE self) {
58
+ glm_vec4_zero(VAL2VEC4(self));
59
+ return self;
60
+ }
61
+
62
+ /* call-seq: one! => self
63
+ *
64
+ * Sets all fields in `self` to `1` and returns `self`.
65
+ */
66
+ VALUE rb_cglm_vec4_one_self(VALUE self) {
67
+ glm_vec4_one(VAL2VEC4(self));
68
+ return self;
69
+ }
70
+
71
+ VALUE rb_cglm_vec4_dot(VALUE self, VALUE other) {
72
+ return DBL2NUM(glm_vec4_dot(VAL2VEC4(self), VAL2VEC4(other)));
73
+ }
74
+
75
+ /* call-seq: norm2 => Numeric
76
+ *
77
+ * Returns the norm (magnitude) of this vector, squared. Call this rather than
78
+ * `norm ** 2` to avoid an unnecessary square root.
79
+ */
80
+ VALUE rb_cglm_vec4_norm2(VALUE self) {
81
+ return DBL2NUM(glm_vec4_norm2(VAL2VEC4(self)));
82
+ }
83
+
84
+ /* call-seq: norm => Numeric
85
+ *
86
+ * Returns the norm (magnitude) of this vector.
87
+ */
88
+ VALUE rb_cglm_vec4_norm(VALUE self) {
89
+ return DBL2NUM(glm_vec4_norm(VAL2VEC4(self)));
90
+ }
91
+
92
+ /* call-seq: add_vec4(b[, dest]) => dest | new Vec4
93
+ *
94
+ * Adds `self` and `b` together, placing the result in `dest`. If `dest` is
95
+ * omitted, a new Vec4 is created and returned.
96
+ */
97
+ VALUE rb_cglm_vec4_add_vec4(int argc, VALUE *argv, VALUE self) {
98
+ VALUE b, dest;
99
+ rb_scan_args(argc, argv, "11", &b, &dest);
100
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
101
+ glm_vec4_add(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(dest));
102
+ return dest;
103
+ }
104
+
105
+ /* call-seq: add_scalar(b[, dest]) => dest | new Vec4
106
+ *
107
+ * Adds the Numeric `b` to each component of `self`, placing the result in
108
+ * `dest`. If `dest` is omitted, a new Vec4 is created and returned.
109
+ */
110
+ VALUE rb_cglm_vec4_add_scalar(int argc, VALUE *argv, VALUE self) {
111
+ VALUE b, dest;
112
+ rb_scan_args(argc, argv, "11", &b, &dest);
113
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
114
+ glm_vec4_adds(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(dest));
115
+ return dest;
116
+ }
117
+
118
+ /* call-seq: sub_vec4(b[, dest]) => dest | new Vec4
119
+ *
120
+ * Subtracts `b` from `self`, placing the result in `dest`. If `dest` is
121
+ * omitted, a new Vec4 is created and returned.
122
+ */
123
+ VALUE rb_cglm_vec4_sub_vec4(int argc, VALUE *argv, VALUE self) {
124
+ VALUE b, dest;
125
+ rb_scan_args(argc, argv, "11", &b, &dest);
126
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
127
+ glm_vec4_sub(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(dest));
128
+ return dest;
129
+ }
130
+
131
+ /* call-seq: sub_scalar(b[, dest]) => dest | new Vec4
132
+ *
133
+ * Subtracts the Numeric `b` from each component of `self`, placing the result
134
+ * in `dest`. If `dest` is omitted, a new Vec4 is created and returned.
135
+ */
136
+ VALUE rb_cglm_vec4_sub_scalar(int argc, VALUE *argv, VALUE self) {
137
+ VALUE b, dest;
138
+ rb_scan_args(argc, argv, "11", &b, &dest);
139
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
140
+ glm_vec4_subs(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(dest));
141
+ return dest;
142
+ }
143
+
144
+ /* call-seq: add_vec4!(b) => self
145
+ *
146
+ * Adds `self` and `b` together, modifying `self` in-place and returning it.
147
+ */
148
+ VALUE rb_cglm_vec4_add_vec4_self(VALUE self, VALUE b) {
149
+ glm_vec4_add(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(self));
150
+ return self;
151
+ }
152
+
153
+ /* call-seq: add_scalar!(b) => self
154
+ *
155
+ * Adds the Numeric `b` to each component of `self`, modifying `self` in-place
156
+ * and returning it.
157
+ */
158
+ VALUE rb_cglm_vec4_add_scalar_self(VALUE self, VALUE b) {
159
+ glm_vec4_adds(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(self));
160
+ return self;
161
+ }
162
+
163
+ /* call-seq: sub_vec4!(b) => self
164
+ *
165
+ * Subtracts `b` from `self`, modifying `self` in-place and returning it.
166
+ */
167
+ VALUE rb_cglm_vec4_sub_vec4_self(VALUE self, VALUE b) {
168
+ glm_vec4_sub(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(self));
169
+ return self;
170
+ }
171
+
172
+ /* call-seq: sub_scalar!(b) => self
173
+ *
174
+ * Subtracts the Numeric `b` from each component of `self`, modifying `self`
175
+ * in-place and returning it.
176
+ */
177
+ VALUE rb_cglm_vec4_sub_scalar_self(VALUE self, VALUE b) {
178
+ glm_vec4_subs(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(self));
179
+ return self;
180
+ }
181
+
182
+ /* call-seq: mul_vec4(b[, dest]) => dest | new Vec4
183
+ *
184
+ * Multiplies two vectors (component-wise multiplication). Places the result
185
+ * in `dest` and returns `dest`. If `dest` is omitted, a new Vec4 is used
186
+ * instead.
187
+ */
188
+ VALUE rb_cglm_vec4_mul_vec4(int argc, VALUE *argv, VALUE self) {
189
+ VALUE b, dest;
190
+ rb_scan_args(argc, argv, "11", &b, &dest);
191
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
192
+ glm_vec4_mul(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(dest));
193
+ return dest;
194
+ }
195
+
196
+ /* call-seq: mul_vec4!(b) => self
197
+ *
198
+ * Multiplies two vectors (component-wise multiplication). Modifies `self`
199
+ * in-place and returns `self`.
200
+ */
201
+ VALUE rb_cglm_vec4_mul_vec4_self(VALUE self, VALUE b) {
202
+ glm_vec4_mul(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(self));
203
+ return self;
204
+ }
205
+
206
+ /* call-seq: mul_scalar(b[, dest]) => dest | new Vec4
207
+ *
208
+ * Multiplies each component in `self` with the scalar `b` and places the
209
+ * result into `dest`. If `dest` is omitted, a new Vec4 is used
210
+ * instead. Returns `dest`.
211
+ */
212
+ VALUE rb_cglm_vec4_mul_scalar(int argc, VALUE *argv, VALUE self) {
213
+ VALUE b, dest;
214
+ rb_scan_args(argc, argv, "11", &b, &dest);
215
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
216
+ glm_vec4_scale(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(dest));
217
+ return dest;
218
+ }
219
+
220
+ /* call-seq: mul_scalar!(b) => self
221
+ *
222
+ * Multiplies each component in `self` with the scalar `b`. Modifies `self`
223
+ * in-place and returns `self`.
224
+ */
225
+ VALUE rb_cglm_vec4_mul_scalar_self(VALUE self, VALUE b) {
226
+ glm_vec4_scale(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(self));
227
+ return self;
228
+ }
229
+
230
+ /* call-seq: resize(b[, dest]) => dest | new Vec4
231
+ *
232
+ * Same as `normalize(self) * b`. Places the result in `dest` and
233
+ * creates a new Vec4 if `dest` is omitted.
234
+ */
235
+ VALUE rb_cglm_vec4_resize(int argc, VALUE *argv, VALUE self) {
236
+ VALUE b, dest;
237
+ rb_scan_args(argc, argv, "11", &b, &dest);
238
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
239
+ glm_vec4_scale_as(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(dest));
240
+ return dest;
241
+ }
242
+
243
+ /* call-seq: resize!(b) => self
244
+ *
245
+ * Same as `normalize(self) * b`. Modifies `self` in-place and returns `self`.
246
+ */
247
+ VALUE rb_cglm_vec4_resize_self(VALUE self, VALUE b) {
248
+ glm_vec4_scale_as(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(self));
249
+ return self;
250
+ }
251
+
252
+ /* call-seq: div_vec4(b[, dest]) => dest | new Vec4
253
+ *
254
+ * Divides two vectors (component-wise division). Places the result
255
+ * in `dest` and returns `dest`. If `dest` is omitted, a new Vec4 is used
256
+ * instead.
257
+ */
258
+ VALUE rb_cglm_vec4_div_vec4(int argc, VALUE *argv, VALUE self) {
259
+ VALUE b, dest;
260
+ rb_scan_args(argc, argv, "11", &b, &dest);
261
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
262
+ glm_vec4_div(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(dest));
263
+ return dest;
264
+ }
265
+
266
+ /* call-seq: div_vec4!(b) => self
267
+ *
268
+ * Divides two vectors (component-wise division). Modifies `self`
269
+ * in-place and returns `self`.
270
+ */
271
+ VALUE rb_cglm_vec4_div_vec4_self(VALUE self, VALUE b) {
272
+ glm_vec4_div(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(self));
273
+ return self;
274
+ }
275
+
276
+ /* call-seq: div_scalar(b[, dest]) => dest | new Vec4
277
+ *
278
+ * Divides each component in `self` by the scalar `b` and places the
279
+ * result into `dest`. If `dest` is omitted, a new Vec4 is used
280
+ * instead. Returns `dest`.
281
+ */
282
+ VALUE rb_cglm_vec4_div_scalar(int argc, VALUE *argv, VALUE self) {
283
+ VALUE b, dest;
284
+ rb_scan_args(argc, argv, "11", &b, &dest);
285
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
286
+ glm_vec4_divs(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(dest));
287
+ return dest;
288
+ }
289
+
290
+ /* call-seq: div_scalar!(b) => self
291
+ *
292
+ * Divides each component in `self` by the scalar `b`. Modifies `self`
293
+ * in-place and returns `self`.
294
+ */
295
+ VALUE rb_cglm_vec4_div_scalar_self(VALUE self, VALUE b) {
296
+ glm_vec4_divs(VAL2VEC4(self), NUM2FLT(b), VAL2VEC4(self));
297
+ return self;
298
+ }
299
+
300
+ /* call-seq: addadd_vec4(other, dest) => dest
301
+ *
302
+ * Adds `self` to `other` and adds that result to `dest`. Equivalent to
303
+ * `dest += (self + other)`. Returns `dest`.
304
+ *
305
+ * * `dest` is not optional for this method, as it is for most others.
306
+ */
307
+ VALUE rb_cglm_vec4_addadd_vec4(VALUE self, VALUE other, VALUE dest) {
308
+ glm_vec4_addadd(VAL2VEC4(self), VAL2VEC4(other), VAL2VEC4(dest));
309
+ return dest;
310
+ }
311
+
312
+ /* call-seq: subadd_vec4(other, dest) => dest
313
+ *
314
+ * Subtracts `other` from `self` and adds that result to `dest`. Equivalent to
315
+ * `dest += (self - other)`. Returns `dest`.
316
+ *
317
+ * * `dest` is not optional for this method, as it is for most others.
318
+ */
319
+ VALUE rb_cglm_vec4_subadd_vec4(VALUE self, VALUE other, VALUE dest) {
320
+ glm_vec4_subadd(VAL2VEC4(self), VAL2VEC4(other), VAL2VEC4(dest));
321
+ return dest;
322
+ }
323
+
324
+ /* call-seq: muladd_vec4(other, dest) => dest
325
+ *
326
+ * Multiplies `self` with `other` and adds that result to `dest`. Equivalent to
327
+ * `dest += (self * other)`. Returns `dest`.
328
+ *
329
+ * * `dest` is not optional for this method, as it is for most others.
330
+ */
331
+ VALUE rb_cglm_vec4_muladd_vec4(VALUE self, VALUE other, VALUE dest) {
332
+ glm_vec4_muladd(VAL2VEC4(self), VAL2VEC4(other), VAL2VEC4(dest));
333
+ return dest;
334
+ }
335
+
336
+ /* call-seq: muladd_scalar(other, dest) => dest
337
+ *
338
+ * Multiplies `self` with `other` and adds that result to `dest`. Equivalent to
339
+ * `dest += (self * other)`. Returns `dest`.
340
+ *
341
+ * * `other` is a Numeric, not a vector type.
342
+ *
343
+ * * `dest` is not optional for this method, as it is for most others.
344
+ */
345
+ VALUE rb_cglm_vec4_muladd_scalar(VALUE self, VALUE other, VALUE dest) {
346
+ glm_vec4_muladds(VAL2VEC4(self), NUM2FLT(other), VAL2VEC4(dest));
347
+ return dest;
348
+ }
349
+
350
+ /* call-seq: flip_signs([dest]) => dest | new Vec4
351
+ *
352
+ * Flips the sign of each component and places the result into `dest`. Returns
353
+ * `dest`. If `dest` is omitted, a new Vec4 is allocated.
354
+ */
355
+ VALUE rb_cglm_vec4_flip_signs(int argc, VALUE *argv, VALUE self) {
356
+ VALUE dest;
357
+ rb_scan_args(argc, argv, "01", &dest);
358
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
359
+ glm_vec4_flipsign_to(VAL2VEC4(self), VAL2VEC4(dest));
360
+ return dest;
361
+ }
362
+
363
+ /* call-seq: flip_signs! => self
364
+ *
365
+ * Flips the sign of each component, modifying `self` in-place. Returns `self`.
366
+ */
367
+ VALUE rb_cglm_vec4_flip_signs_self(VALUE self) {
368
+ glm_vec4_flipsign(VAL2VEC4(self));
369
+ return self;
370
+ }
371
+
372
+ /* call-seq: distance(vec) => Numeric
373
+ *
374
+ * Returns the distance between this vector and the specified one.
375
+ */
376
+ VALUE rb_cglm_vec4_distance(VALUE self, VALUE b) {
377
+ return DBL2NUM(glm_vec4_distance(VAL2VEC4(self), VAL2VEC4(b)));
378
+ }
379
+
380
+ /* call-seq: max(vec[, dest]) => dest | new Vec4
381
+ *
382
+ * Finds the higher of each component (x, y, z) between `self` and `vec`.
383
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
384
+ * Vec4 if `dest` is omitted.
385
+ */
386
+ VALUE rb_cglm_vec4_max(int argc, VALUE *argv, VALUE self) {
387
+ VALUE b, dest;
388
+ rb_scan_args(argc, argv, "11", &b, &dest);
389
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
390
+ glm_vec4_maxv(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(dest));
391
+ return dest;
392
+ }
393
+
394
+ /* call-seq: min(vec[, dest]) => dest | new Vec4
395
+ *
396
+ * Finds the lower of each component (x, y, z) between `self` and `vec`.
397
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
398
+ * Vec4 if `dest` is omitted.
399
+ */
400
+ VALUE rb_cglm_vec4_min(int argc, VALUE *argv, VALUE self) {
401
+ VALUE b, dest;
402
+ rb_scan_args(argc, argv, "11", &b, &dest);
403
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
404
+ glm_vec4_minv(VAL2VEC4(self), VAL2VEC4(b), VAL2VEC4(dest));
405
+ return dest;
406
+ }
407
+
408
+ /* call-seq: clamp_scalar(min, max[, dest]) => dest | new Vec4
409
+ *
410
+ * Clamps each component in `self` to the range given by `min` and `max`.
411
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
412
+ * Vec4 if `dest` is omitted.
413
+ */
414
+ VALUE rb_cglm_vec4_clamp_scalar(int argc, VALUE *argv, VALUE self) {
415
+ VALUE a, b, dest;
416
+ rb_scan_args(argc, argv, "21", &a, &b, &dest);
417
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
418
+ memcpy(&VAL2VEC4(dest), &VAL2VEC4(self), sizeof(vec4));
419
+ glm_vec4_clamp(VAL2VEC4(dest), NUM2FLT(a), NUM2FLT(b));
420
+ return dest;
421
+ }
422
+
423
+ /* call-seq: clamp_scalar!(min, max) => self
424
+ *
425
+ * Clamps each component in `self` to the range given by `min` and `max`.
426
+ * Places the result into `self` and returns `self`.
427
+ */
428
+ VALUE rb_cglm_vec4_clamp_scalar_self(VALUE self, VALUE a, VALUE b) {
429
+ glm_vec4_clamp(VAL2VEC4(self), NUM2FLT(a), NUM2FLT(b));
430
+ return self;
431
+ }
432
+
433
+ /* call-seq: clamp_vec4(min, max[, dest]) => dest | new Vec4
434
+ *
435
+ * Clamps each component in `self` to the range given by `min` and `max`.
436
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
437
+ * Vec4 if `dest` is omitted.
438
+ */
439
+ VALUE rb_cglm_vec4_clamp_vec4(int argc, VALUE *argv, VALUE self) {
440
+ VALUE a, b, dest;
441
+ rb_scan_args(argc, argv, "21", &a, &b, &dest);
442
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
443
+ memcpy(&VAL2VEC4(dest), &VAL2VEC4(self), sizeof(vec4));
444
+ vec4 *s = &VAL2VEC4(dest);
445
+ vec4 *low = &VAL2VEC4(a);
446
+ vec4 *high = &VAL2VEC4(b);
447
+ for (int i = 0; i < 4; i++) {
448
+ (*s)[i] = (*low)[i] > (*high)[i] ? (*low)[i] : (*high)[i];
449
+ }
450
+ return dest;
451
+ }
452
+
453
+ /* call-seq: clamp_vec4!(min, max) => self
454
+ *
455
+ * Clamps each component in `self` to the range given by `min` and `max`.
456
+ * Places the result into `self` and returns `self`.
457
+ */
458
+ VALUE rb_cglm_vec4_clamp_vec4_self(VALUE self, VALUE a, VALUE b) {
459
+ vec4 *s = &VAL2VEC4(self);
460
+ vec4 *low = &VAL2VEC4(a);
461
+ vec4 *high = &VAL2VEC4(b);
462
+ for (int i = 0; i < 4; i++) {
463
+ (*s)[i] = (*low)[i] > (*high)[i] ? (*low)[i] : (*high)[i];
464
+ }
465
+ return self;
466
+ }
467
+
468
+ /* call-seq: lerp!(from, to, amount) => self
469
+ *
470
+ * Performs linear interpolation between `from` and `to`, both of which should
471
+ * be Vec4's, by the specified `amount` which should be a number. Modifies
472
+ * `self` in-place and returns `self`.
473
+ */
474
+ VALUE rb_cglm_vec4_lerp_self(VALUE self, VALUE from, VALUE to, VALUE amount) {
475
+ glm_vec4_lerp(VAL2VEC4(from), VAL2VEC4(to), NUM2FLT(amount), VAL2VEC4(self));
476
+ return self;
477
+ }
478
+
479
+ /* call-seq: broadcast!(val) => self
480
+ *
481
+ * Sets each member of `self` to the specified Numeric value and returns
482
+ * `self`.
483
+ */
484
+ VALUE rb_cglm_vec4_broadcast_self(VALUE self, VALUE val) {
485
+ glm_vec4_broadcast(NUM2FLT(val), VAL2VEC4(self));
486
+ return self;
487
+ }
488
+
489
+ /* call-seq: equals_scalar(val) => true|false
490
+ *
491
+ * Returns true if the given scalar value exactly equals each component of
492
+ * this Vec4, false otherwise.
493
+ */
494
+ VALUE rb_cglm_vec4_equals_scalar(VALUE self, VALUE val) {
495
+ return glm_vec4_eq(VAL2VEC4(self), NUM2FLT(val)) ? Qtrue : Qfalse;
496
+ }
497
+
498
+ /* call-seq: equalish_scalar(val[, epsilon]) => true|false
499
+ *
500
+ * Returns true if the given scalar value is very close to each component of
501
+ * this Vec4, false otherwise. Useful for dealing with the loss of precision
502
+ * during floating point arithmetic.
503
+ */
504
+ VALUE rb_cglm_vec4_equalish_scalar(int argc, VALUE *argv, VALUE self) {
505
+ VALUE val, eps;
506
+ float epsil = FLT_EPSILON;
507
+ rb_scan_args(argc, argv, "11", &val, &eps);
508
+ if (!NIL_P(eps)) epsil = NUM2FLT(eps);
509
+ float s = NUM2FLT(val);
510
+ vec3 *v = &VAL2VEC3(self);
511
+ return fabsf((*v)[0] - s) <= eps &&
512
+ fabsf((*v)[1] - s) <= eps &&
513
+ fabsf((*v)[2] - s) <= eps ? Qtrue : Qfalse;
514
+ }
515
+
516
+ /* call-seq: equals_all => true|false
517
+ *
518
+ * Returns true if each component in this Vec4 has the same exact value.
519
+ */
520
+ VALUE rb_cglm_vec4_equals_all(VALUE self) {
521
+ return glm_vec4_eq_all(VAL2VEC4(self)) ? Qtrue : Qfalse;
522
+ }
523
+
524
+ /* call-seq: equals_vec4(other) => true|false
525
+ *
526
+ * Returns true if this vector exactly matches the given one.
527
+ */
528
+ VALUE rb_cglm_vec4_equals_vec4(VALUE self, VALUE other) {
529
+ return glm_vec4_eqv(VAL2VEC4(self), VAL2VEC4(other)) ? Qtrue : Qfalse;
530
+ }
531
+
532
+ /* call-seq: equalish_vec4(other[, epsilon]) => true|false
533
+ *
534
+ * Returns true if this vector is very close to equal to the given one. Useful
535
+ * for dealing with the loss of precision during floating point arithmetic.
536
+ */
537
+ VALUE rb_cglm_vec4_equalish_vec4(int argc, VALUE *argv, VALUE self) {
538
+ VALUE val, eps;
539
+ float epsil = FLT_EPSILON;
540
+ rb_scan_args(argc, argv, "11", &val, &eps);
541
+ if (!NIL_P(eps)) epsil = NUM2FLT(eps);
542
+ vec4 *s = &VAL2VEC4(val);
543
+ vec4 *v = &VAL2VEC4(self);
544
+ return fabsf((*v)[0] - (*s)[0]) <= eps &&
545
+ fabsf((*v)[1] - (*s)[1]) <= eps &&
546
+ fabsf((*v)[2] - (*s)[2]) <= eps &&
547
+ fabsf((*v)[3] - (*s)[3]) <= eps ? Qtrue : Qfalse;
548
+ }
549
+
550
+ /* call-seq: highest => Numeric
551
+ *
552
+ * Returns the value of the highest component in this Vec4.
553
+ */
554
+ VALUE rb_cglm_vec4_highest(VALUE self) {
555
+ return DBL2NUM(glm_vec4_max(VAL2VEC4(self)));
556
+ }
557
+
558
+ /* call-seq: lowest => Numeric
559
+ *
560
+ * Returns the value of the lowest component in this Vec4.
561
+ */
562
+ VALUE rb_cglm_vec4_lowest(VALUE self) {
563
+ return DBL2NUM(glm_vec4_min(VAL2VEC4(self)));
564
+ }
565
+
566
+ /* call-seq: nan? => true|false
567
+ *
568
+ * Returns true if any component in this vector is nan, false otherwise.
569
+ * You should only use this in DEBUG mode or very critical asserts.
570
+ */
571
+ VALUE rb_cglm_vec4_is_nan(VALUE self) {
572
+ return glm_vec4_isnan(VAL2VEC4(self)) ? Qtrue : Qfalse;
573
+ }
574
+
575
+ /* call-seq: inf? => true|false
576
+ *
577
+ * Returns true if any component in this vector is inf, false otherwise.
578
+ * You should only use this in DEBUG mode or very critical asserts.
579
+ */
580
+ VALUE rb_cglm_vec4_is_inf(VALUE self) {
581
+ return glm_vec4_isinf(VAL2VEC4(self)) ? Qtrue : Qfalse;
582
+ }
583
+
584
+ /* call-seq: valid? => true|false
585
+ *
586
+ * Returns true if no component in this vector is NaN or infinite, false
587
+ * otherwise. You should only use this in DEBUG mode or very critical asserts.
588
+ */
589
+ VALUE rb_cglm_vec4_is_valid(VALUE self) {
590
+ return glm_vec4_isvalid(VAL2VEC4(self)) ? Qtrue : Qfalse;
591
+ }
592
+
593
+ /* call-seq: signs([dest]) => dest | new Vec4
594
+ *
595
+ * Places `+1`, `0` or `-1` into each component of `dest` based on whether the
596
+ * corresponding component of this Vec4 is positive, `0`/`NaN`, or negative.
597
+ * If `dest` is omitted, a new Vec4 is created and returned.
598
+ */
599
+ VALUE rb_cglm_vec4_signs(int argc, VALUE *argv, VALUE self) {
600
+ VALUE dest;
601
+ rb_scan_args(argc, argv, "01", &dest);
602
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
603
+ glm_vec4_sign(VAL2VEC4(self), VAL2VEC4(dest));
604
+ return dest;
605
+ }
606
+
607
+ /* call-seq: sqrt([dest]) => dest | new Vec4
608
+ *
609
+ * For each component of this Vec4, places the square root of that component
610
+ * into `dest`. If `dest` is omitted, a new Vec4 is created. Returns `dest`.
611
+ */
612
+ VALUE rb_cglm_vec4_sqrt(int argc, VALUE *argv, VALUE self) {
613
+ VALUE dest;
614
+ rb_scan_args(argc, argv, "01", &dest);
615
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
616
+ glm_vec4_sqrt(VAL2VEC4(self), VAL2VEC4(dest));
617
+ return dest;
618
+ }
619
+
620
+ /* call-seq: random([dest]) => dest | new Vec4
621
+ *
622
+ * Fills `dest` or a new Vec4 with random values, and returns it.
623
+ */
624
+ VALUE rb_cglm_vec4_new_random(int argc, VALUE *argv, VALUE self) {
625
+ VALUE dest;
626
+ rb_scan_args(argc, argv, "01", &dest);
627
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
628
+
629
+ VAL2VEC4(dest)[0] = drand48();
630
+ VAL2VEC4(dest)[1] = drand48();
631
+ VAL2VEC4(dest)[2] = drand48();
632
+ VAL2VEC4(dest)[3] = drand48();
633
+
634
+ return dest;
635
+ }
636
+
637
+ /* call-seq: normalize([dest]) => dest | new Vec4
638
+ */
639
+ VALUE rb_cglm_vec4_normalize(int argc, VALUE *argv, VALUE self) {
640
+ VALUE dest;
641
+ rb_scan_args(argc, argv, "01", &dest);
642
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
643
+ glm_vec4_normalize_to(VAL2VEC4(self), VAL2VEC4(dest));
644
+ return dest;
645
+ }
646
+
647
+ /* call-seq: normalize! => self
648
+ */
649
+ VALUE rb_cglm_vec4_normalize_self(VALUE self) {
650
+ glm_vec4_normalize(VAL2VEC4(self));
651
+ return self;
652
+ }
653
+
654
+ void Init_cglm_vec4() {
655
+ rb_define_method(rb_cVec4, "[]", rb_cglm_vec4_aref, 1);
656
+ rb_define_method(rb_cVec4, "[]=", rb_cglm_vec4_aset, 2);
657
+ rb_define_method(rb_cVec4, "to_vec3", rb_cglm_vec4_to_vec3, -1);
658
+ rb_define_method(rb_cVec4, "copy_to", rb_cglm_vec4_copy_to, 1);
659
+ rb_define_method(rb_cVec4, "zero!", rb_cglm_vec4_zero_self, 0);
660
+ rb_define_method(rb_cVec4, "one!", rb_cglm_vec4_one_self, 0);
661
+ rb_define_method(rb_cVec4, "dot", rb_cglm_vec4_dot, 1);
662
+ rb_define_method(rb_cVec4, "norm2", rb_cglm_vec4_norm2, 0);
663
+ rb_define_method(rb_cVec4, "norm", rb_cglm_vec4_norm, 0);
664
+ rb_define_method(rb_cVec4, "add_vec4", rb_cglm_vec4_add_vec4, -1);
665
+ rb_define_method(rb_cVec4, "add_scalar", rb_cglm_vec4_add_scalar, -1);
666
+ rb_define_method(rb_cVec4, "sub_vec4", rb_cglm_vec4_sub_vec4, -1);
667
+ rb_define_method(rb_cVec4, "sub_scalar", rb_cglm_vec4_sub_scalar, -1);
668
+ rb_define_method(rb_cVec4, "add_vec4!", rb_cglm_vec4_add_vec4_self, 1);
669
+ rb_define_method(rb_cVec4, "add_scalar!", rb_cglm_vec4_add_scalar_self, 1);
670
+ rb_define_method(rb_cVec4, "sub_vec4!", rb_cglm_vec4_sub_vec4_self, 1);
671
+ rb_define_method(rb_cVec4, "sub_scalar!", rb_cglm_vec4_sub_scalar_self, 1);
672
+ rb_define_method(rb_cVec4, "mul_vec4", rb_cglm_vec4_mul_vec4, -1);
673
+ rb_define_method(rb_cVec4, "mul_vec4!", rb_cglm_vec4_mul_vec4_self, 1);
674
+ rb_define_method(rb_cVec4, "mul_scalar", rb_cglm_vec4_mul_scalar, -1);
675
+ rb_define_method(rb_cVec4, "mul_scalar!", rb_cglm_vec4_mul_scalar_self, 1);
676
+ rb_define_method(rb_cVec4, "div_vec4", rb_cglm_vec4_div_vec4, -1);
677
+ rb_define_method(rb_cVec4, "div_vec4!", rb_cglm_vec4_div_vec4_self, 1);
678
+ rb_define_method(rb_cVec4, "div_scalar", rb_cglm_vec4_div_scalar, -1);
679
+ rb_define_method(rb_cVec4, "div_scalar!", rb_cglm_vec4_div_scalar_self, 1);
680
+ rb_define_method(rb_cVec4, "resize", rb_cglm_vec4_resize, -1);
681
+ rb_define_method(rb_cVec4, "resize!", rb_cglm_vec4_resize_self, 1);
682
+ rb_define_method(rb_cVec4, "addadd_vec4", rb_cglm_vec4_addadd_vec4, 2);
683
+ rb_define_method(rb_cVec4, "subadd_vec4", rb_cglm_vec4_subadd_vec4, 2);
684
+ rb_define_method(rb_cVec4, "muladd_scalar", rb_cglm_vec4_muladd_scalar, 2);
685
+ rb_define_method(rb_cVec4, "muladd_vec4", rb_cglm_vec4_muladd_vec4, 2);
686
+ rb_define_method(rb_cVec4, "flip_signs", rb_cglm_vec4_flip_signs, -1);
687
+ rb_define_method(rb_cVec4, "flip_signs!", rb_cglm_vec4_flip_signs_self, 0);
688
+ rb_define_method(rb_cVec4, "distance", rb_cglm_vec4_distance, 1);
689
+ rb_define_method(rb_cVec4, "max", rb_cglm_vec4_max, -1);
690
+ rb_define_method(rb_cVec4, "min", rb_cglm_vec4_min, -1);
691
+ rb_define_method(rb_cVec4, "clamp_scalar", rb_cglm_vec4_clamp_scalar, -1);
692
+ rb_define_method(rb_cVec4, "clamp_scalar!", rb_cglm_vec4_clamp_scalar_self, 2);
693
+ rb_define_method(rb_cVec4, "clamp_vec4", rb_cglm_vec4_clamp_vec4, -1);
694
+ rb_define_method(rb_cVec4, "clamp_vec4!", rb_cglm_vec4_clamp_vec4_self, 2);
695
+ rb_define_method(rb_cVec4, "lerp!", rb_cglm_vec4_lerp_self, 3);
696
+ rb_define_method(rb_cVec4, "broadcast!", rb_cglm_vec4_broadcast_self, 1);
697
+ rb_define_method(rb_cVec4, "equals_scalar", rb_cglm_vec4_equals_scalar, 1);
698
+ rb_define_method(rb_cVec4, "equalish_scalar", rb_cglm_vec4_equalish_scalar, -1);
699
+ rb_define_method(rb_cVec4, "equals_all", rb_cglm_vec4_equals_all, 0);
700
+ rb_define_method(rb_cVec4, "equals_vec4", rb_cglm_vec4_equals_vec4, 1);
701
+ rb_define_method(rb_cVec4, "equalish_vec4", rb_cglm_vec4_equalish_vec4, -1);
702
+ rb_define_method(rb_cVec4, "highest", rb_cglm_vec4_highest, 0);
703
+ rb_define_method(rb_cVec4, "lowest", rb_cglm_vec4_lowest, 0);
704
+ rb_define_method(rb_cVec4, "nan?", rb_cglm_vec4_is_nan, 0);
705
+ rb_define_method(rb_cVec4, "inf?", rb_cglm_vec4_is_inf, 0);
706
+ rb_define_method(rb_cVec4, "valid?", rb_cglm_vec4_is_valid, 0);
707
+ rb_define_method(rb_cVec4, "signs", rb_cglm_vec4_signs, -1);
708
+ rb_define_method(rb_cVec4, "sqrt", rb_cglm_vec4_sqrt, -1);
709
+ rb_define_method(rb_cVec4, "normalize", rb_cglm_vec4_normalize, -1);
710
+ rb_define_method(rb_cVec4, "normalize!", rb_cglm_vec4_normalize_self, 0);
711
+
712
+ rb_define_alias(rb_cVec4, "invert", "flip_signs");
713
+ rb_define_alias(rb_cVec4, "invert!", "flip_signs!");
714
+ rb_define_alias(rb_cVec4, "magnitude", "norm");
715
+ rb_define_alias(rb_cVec4, "mag", "norm");
716
+
717
+ rb_define_singleton_method(rb_cVec4, "random", rb_cglm_vec4_new_random, -1);
718
+ rb_define_singleton_method(rb_cVec4, "rand", rb_cglm_vec4_new_random, -1);
719
+ rb_define_singleton_method(rb_cVec4, "size", rb_cglm_vec4_size_bytes, 0);
720
+ rb_define_singleton_method(rb_cVec4, "alignment", rb_cglm_vec4_alignment_bytes, 0);
721
+ rb_define_singleton_method(rb_cVec4, "one", rb_cglm_vec4_one, 0);
722
+ rb_define_singleton_method(rb_cVec4, "black", rb_cglm_vec4_black, 0);
723
+ rb_define_singleton_method(rb_cVec4, "zero", rb_cglm_vec4_zero, 0);
724
+ }