cglm 0.1.0

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