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,57 @@
1
+ #include "rb_cglm.h"
2
+
3
+ /* call-seq: transform(mat4[, dest]) => dest | new Sphere
4
+ *
5
+ * Transforms this sphere to put it in the space described by `mat4`, and
6
+ * puts the result into `dest`. If `dest` is omitted, a new Sphere is created.
7
+ */
8
+ VALUE rb_cglm_sphere_transform(int argc, VALUE *argv, VALUE self) {
9
+ VALUE matrix, dest;
10
+ rb_scan_args(argc, argv, "11", &matrix, &dest);
11
+ if (NIL_P(dest)) dest = rb_funcall(rb_cSphere, rb_intern("new"), 0);
12
+ glm_sphere_transform(VAL2VEC4(self), VAL2MAT4(matrix), VAL2VEC4(dest));
13
+ return dest;
14
+ }
15
+
16
+ /* call-seq: merge(other[, dest]) => dest | new Sphere
17
+ *
18
+ * Merges two spheres (`self` and `other`) and places the result in `dest`. If
19
+ * `dest` is omitted, a new Sphere will be created.
20
+ *
21
+ * Both spheres must be in the same space. For instance, if one is in world
22
+ * space then the other must be in world space and not in local space.
23
+ *
24
+ * * `other` must be a Sphere or a Vec4 with the layout `[x, y, z, radius]`.
25
+ */
26
+ VALUE rb_cglm_sphere_merge(int argc, VALUE *argv, VALUE self) {
27
+ VALUE other, dest;
28
+ rb_scan_args(argc, argv, "11", &other, &dest);
29
+ if (NIL_P(dest)) dest = rb_funcall(rb_cSphere, rb_intern("new"), 0);
30
+ glm_sphere_merge(VAL2VEC4(self), VAL2VEC4(other), VAL2VEC4(dest));
31
+ return dest;
32
+ }
33
+
34
+ /* call-seq: intersects_sphere?(other) => true|false
35
+ *
36
+ * Returns true if `self` intersects `other`, false otherwise.
37
+ *
38
+ * * `other` must be a Sphere or a Vec4 with the layout `[x, y, z, radius]`.
39
+ */
40
+ VALUE rb_cglm_sphere_intersects_sphere(VALUE self, VALUE other) {
41
+ return glm_sphere_sphere(VAL2VEC4(self), VAL2VEC4(other)) ? Qtrue : Qfalse;
42
+ }
43
+
44
+ /* call-seq: contains_point?(point) => true|false
45
+ *
46
+ * Returns true if `self` contains the specified Vec3, false otherwise.
47
+ */
48
+ VALUE rb_cglm_sphere_contains_point(VALUE self, VALUE point) {
49
+ return glm_sphere_point(VAL2VEC4(self), VAL2VEC3(point)) ? Qtrue : Qfalse;
50
+ }
51
+
52
+ void Init_cglm_sphere() {
53
+ rb_define_method(rb_cSphere, "transform", rb_cglm_sphere_transform, -1);
54
+ rb_define_method(rb_cSphere, "merge", rb_cglm_sphere_merge, -1);
55
+ rb_define_method(rb_cSphere, "intersects_sphere?", rb_cglm_sphere_intersects_sphere, 1);
56
+ rb_define_method(rb_cSphere, "contains_point?", rb_cglm_sphere_contains_point, 1);
57
+ }
@@ -0,0 +1,882 @@
1
+ #include "rb_cglm.h"
2
+
3
+ VALUE rb_cglm_vec3_aref(VALUE self, VALUE index) {
4
+ CHECK_RANGE(index, 0, 2);
5
+ return DBL2NUM(VAL2VEC3(self)[NUM2INT(index)]);
6
+ }
7
+
8
+ VALUE rb_cglm_vec3_aset(VALUE self, VALUE index, VALUE val) {
9
+ CHECK_RANGE(index, 0, 2);
10
+ VAL2VEC3(self)[NUM2INT(index)] = NUM2DBL(val);
11
+ return self;
12
+ }
13
+
14
+ VALUE rb_cglm_vec3_size_bytes(VALUE klass) {
15
+ return SIZET2NUM(vec3_size());
16
+ }
17
+
18
+ VALUE rb_cglm_vec3_alignment_bytes(VALUE klass) {
19
+ return SIZET2NUM(VEC3_ALIGNMENT);
20
+ }
21
+
22
+ VALUE rb_cglm_vec3_xup(VALUE self) {
23
+ VALUE dest = VEC3_NEW(ALLOC_VEC3);
24
+ vec3 yup = GLM_XUP;
25
+ memcpy(&VAL2VEC3(dest), &yup, sizeof(vec3));
26
+ return dest;
27
+ }
28
+
29
+ VALUE rb_cglm_vec3_yup(VALUE self) {
30
+ VALUE dest = VEC3_NEW(ALLOC_VEC3);
31
+ vec3 yup = GLM_YUP;
32
+ memcpy(&VAL2VEC3(dest), &yup, sizeof(vec3));
33
+ return dest;
34
+ }
35
+
36
+ VALUE rb_cglm_vec3_zup(VALUE self) {
37
+ VALUE dest = VEC3_NEW(ALLOC_VEC3);
38
+ vec3 yup = GLM_ZUP;
39
+ memcpy(&VAL2VEC3(dest), &yup, sizeof(vec3));
40
+ return dest;
41
+ }
42
+
43
+ VALUE rb_cglm_vec3_one(VALUE self) {
44
+ VALUE dest = VEC3_NEW(ALLOC_VEC3);
45
+ vec3 yup = GLM_VEC3_ONE;
46
+ memcpy(&VAL2VEC3(dest), &yup, sizeof(vec3));
47
+ return dest;
48
+ }
49
+
50
+ VALUE rb_cglm_vec3_zero(VALUE self) {
51
+ VALUE dest = VEC3_NEW(ALLOC_VEC3);
52
+ vec3 yup = GLM_VEC3_ZERO;
53
+ memcpy(&VAL2VEC3(dest), &yup, sizeof(vec3));
54
+ return dest;
55
+ }
56
+
57
+ VALUE rb_cglm_vec3_zero_self(VALUE self) {
58
+ glm_vec_zero(VAL2VEC3(self));
59
+ return self;
60
+ }
61
+
62
+ VALUE rb_cglm_vec3_one_self(VALUE self) {
63
+ glm_vec_one(VAL2VEC3(self));
64
+ return self;
65
+ }
66
+
67
+ VALUE rb_cglm_vec3_dot(VALUE self, VALUE other) {
68
+ return DBL2NUM(glm_vec_dot(VAL2VEC3(self), VAL2VEC3(self)));
69
+ }
70
+
71
+ /* call-seq: cross(b[, dest]) => dest | new Vec3 */
72
+ VALUE rb_cglm_vec3_cross(int argc, VALUE *argv, VALUE self) {
73
+ VALUE b, dest;
74
+ rb_scan_args(argc, argv, "11", &b, &dest);
75
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
76
+ glm_vec_cross(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
77
+ return dest;
78
+ }
79
+
80
+ /* call-seq: norm2 => Numeric
81
+ *
82
+ * Returns the norm (magnitude) of this vector, squared. Call this rather than
83
+ * `norm ** 2` to avoid an unnecessary square root.
84
+ */
85
+ VALUE rb_cglm_vec3_norm2(VALUE self) {
86
+ return DBL2NUM(glm_vec_norm2(VAL2VEC3(self)));
87
+ }
88
+
89
+ /* call-seq: norm => Numeric
90
+ *
91
+ * Returns the norm (magnitude) of this vector.
92
+ */
93
+ VALUE rb_cglm_vec3_norm(VALUE self) {
94
+ return DBL2NUM(glm_vec_norm(VAL2VEC3(self)));
95
+ }
96
+
97
+ /* call-seq: add_vec3(b[, dest]) => dest | new Vec3
98
+ *
99
+ * Adds `self` and `b` together, placing the result in `dest`. If `dest` is
100
+ * omitted, a new Vec3 is created and returned.
101
+ */
102
+ VALUE rb_cglm_vec3_add_vec3(int argc, VALUE *argv, VALUE self) {
103
+ VALUE b, dest;
104
+ rb_scan_args(argc, argv, "11", &b, &dest);
105
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
106
+ glm_vec_add(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
107
+ return dest;
108
+ }
109
+
110
+ /* call-seq: add_scalar(b[, dest]) => dest | new Vec3
111
+ *
112
+ * Adds the Numeric `b` to each component of `self`, placing the result in
113
+ * `dest`. If `dest` is omitted, a new Vec3 is created and returned.
114
+ */
115
+ VALUE rb_cglm_vec3_add_scalar(int argc, VALUE *argv, VALUE self) {
116
+ VALUE b, dest;
117
+ rb_scan_args(argc, argv, "11", &b, &dest);
118
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
119
+ glm_vec_adds(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(dest));
120
+ return dest;
121
+ }
122
+
123
+ /* call-seq: sub_vec3(b[, dest]) => dest | new Vec3
124
+ *
125
+ * Subtracts `b` from `self`, placing the result in `dest`. If `dest` is
126
+ * omitted, a new Vec3 is created and returned.
127
+ */
128
+ VALUE rb_cglm_vec3_sub_vec3(int argc, VALUE *argv, VALUE self) {
129
+ VALUE b, dest;
130
+ rb_scan_args(argc, argv, "11", &b, &dest);
131
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
132
+ glm_vec_sub(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
133
+ return dest;
134
+ }
135
+
136
+ /* call-seq: sub_scalar(b[, dest]) => dest | new Vec3
137
+ *
138
+ * Subtracts the Numeric `b` from each component of `self`, placing the result
139
+ * in `dest`. If `dest` is omitted, a new Vec3 is created and returned.
140
+ */
141
+ VALUE rb_cglm_vec3_sub_scalar(int argc, VALUE *argv, VALUE self) {
142
+ VALUE b, dest;
143
+ rb_scan_args(argc, argv, "11", &b, &dest);
144
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
145
+ glm_vec_subs(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(dest));
146
+ return dest;
147
+ }
148
+
149
+ /* call-seq: add_vec3!(b) => self
150
+ *
151
+ * Adds `self` and `b` together, modifying `self` in-place and returning it.
152
+ */
153
+ VALUE rb_cglm_vec3_add_vec3_self(VALUE self, VALUE b) {
154
+ glm_vec_add(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(self));
155
+ return self;
156
+ }
157
+
158
+ /* call-seq: add_scalar!(b) => self
159
+ *
160
+ * Adds the Numeric `b` to each component of `self`, modifying `self` in-place
161
+ * and returning it.
162
+ */
163
+ VALUE rb_cglm_vec3_add_scalar_self(VALUE self, VALUE b) {
164
+ glm_vec_adds(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(self));
165
+ return self;
166
+ }
167
+
168
+ /* call-seq: sub_vec3!(b) => self
169
+ *
170
+ * Subtracts `b` from `self`, modifying `self` in-place and returning it.
171
+ */
172
+ VALUE rb_cglm_vec3_sub_vec3_self(VALUE self, VALUE b) {
173
+ glm_vec_sub(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(self));
174
+ return self;
175
+ }
176
+
177
+ /* call-seq: sub_scalar!(b) => self
178
+ *
179
+ * Subtracts the Numeric `b` from each component of `self`, modifying `self`
180
+ * in-place and returning it.
181
+ */
182
+ VALUE rb_cglm_vec3_sub_scalar_self(VALUE self, VALUE b) {
183
+ glm_vec_subs(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(self));
184
+ return self;
185
+ }
186
+
187
+ /* call-seq: mul_vec3(b[, dest]) => dest | new Vec3
188
+ *
189
+ * Multiplies two vectors (component-wise multiplication). Places the result
190
+ * in `dest` and returns `dest`. If `dest` is omitted, a new Vec3 is used
191
+ * instead.
192
+ */
193
+ VALUE rb_cglm_vec3_mul_vec3(int argc, VALUE *argv, VALUE self) {
194
+ VALUE b, dest;
195
+ rb_scan_args(argc, argv, "11", &b, &dest);
196
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
197
+ glm_vec_mul(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
198
+ return dest;
199
+ }
200
+
201
+ /* call-seq: mul_vec3!(b) => self
202
+ *
203
+ * Multiplies two vectors (component-wise multiplication). Modifies `self`
204
+ * in-place and returns `self`.
205
+ */
206
+ VALUE rb_cglm_vec3_mul_vec3_self(VALUE self, VALUE b) {
207
+ glm_vec_mul(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(self));
208
+ return self;
209
+ }
210
+
211
+ /* call-seq: mul_scalar(b[, dest]) => dest | new Vec3
212
+ *
213
+ * Multiplies each component in `self` with the scalar `b` and places the
214
+ * result into `dest`. If `dest` is omitted, a new Vec3 is used
215
+ * instead. Returns `dest`.
216
+ */
217
+ VALUE rb_cglm_vec3_mul_scalar(int argc, VALUE *argv, VALUE self) {
218
+ VALUE b, dest;
219
+ rb_scan_args(argc, argv, "11", &b, &dest);
220
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
221
+ glm_vec_scale(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(dest));
222
+ return dest;
223
+ }
224
+
225
+ /* call-seq: mul_scalar!(b) => self
226
+ *
227
+ * Multiplies each component in `self` with the scalar `b`. Modifies `self`
228
+ * in-place and returns `self`.
229
+ */
230
+ VALUE rb_cglm_vec3_mul_scalar_self(VALUE self, VALUE b) {
231
+ glm_vec_scale(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(self));
232
+ return self;
233
+ }
234
+
235
+ /* call-seq: resize(b[, dest]) => dest | new Vec3
236
+ *
237
+ * Same as `normalize(self) * b`. Places the result in `dest` and
238
+ * creates a new Vec3 if `dest` is omitted.
239
+ */
240
+ VALUE rb_cglm_vec3_resize(int argc, VALUE *argv, VALUE self) {
241
+ VALUE b, dest;
242
+ rb_scan_args(argc, argv, "11", &b, &dest);
243
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
244
+ glm_vec_scale_as(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(dest));
245
+ return dest;
246
+ }
247
+
248
+ /* call-seq: resize!(b) => self
249
+ *
250
+ * Same as `normalize(self) * b`. Modifies `self` in-place and returns `self`.
251
+ */
252
+ VALUE rb_cglm_vec3_resize_self(VALUE self, VALUE b) {
253
+ glm_vec_scale_as(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(self));
254
+ return self;
255
+ }
256
+
257
+ /* call-seq: div_vec3(b[, dest]) => dest | new Vec3
258
+ *
259
+ * Divides two vectors (component-wise division). Places the result
260
+ * in `dest` and returns `dest`. If `dest` is omitted, a new Vec3 is used
261
+ * instead.
262
+ */
263
+ VALUE rb_cglm_vec3_div_vec3(int argc, VALUE *argv, VALUE self) {
264
+ VALUE b, dest;
265
+ rb_scan_args(argc, argv, "11", &b, &dest);
266
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
267
+ glm_vec_div(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
268
+ return dest;
269
+ }
270
+
271
+ /* call-seq: div_vec3!(b) => self
272
+ *
273
+ * Divides two vectors (component-wise division). Modifies `self`
274
+ * in-place and returns `self`.
275
+ */
276
+ VALUE rb_cglm_vec3_div_vec3_self(VALUE self, VALUE b) {
277
+ glm_vec_div(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(self));
278
+ return self;
279
+ }
280
+
281
+ /* call-seq: div_scalar(b[, dest]) => dest | new Vec3
282
+ *
283
+ * Divides each component in `self` by the scalar `b` and places the
284
+ * result into `dest`. If `dest` is omitted, a new Vec3 is used
285
+ * instead. Returns `dest`.
286
+ */
287
+ VALUE rb_cglm_vec3_div_scalar(int argc, VALUE *argv, VALUE self) {
288
+ VALUE b, dest;
289
+ rb_scan_args(argc, argv, "11", &b, &dest);
290
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
291
+ glm_vec_divs(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(dest));
292
+ return dest;
293
+ }
294
+
295
+ /* call-seq: div_scalar!(b) => self
296
+ *
297
+ * Divides each component in `self` by the scalar `b`. Modifies `self`
298
+ * in-place and returns `self`.
299
+ */
300
+ VALUE rb_cglm_vec3_div_scalar_self(VALUE self, VALUE b) {
301
+ glm_vec_divs(VAL2VEC3(self), NUM2FLT(b), VAL2VEC3(self));
302
+ return self;
303
+ }
304
+
305
+ /* call-seq: addadd_vec3(other, dest) => dest
306
+ *
307
+ * Adds `self` to `other` and adds that result to `dest`. Equivalent to
308
+ * `dest += (self + other)`. Returns `dest`.
309
+ *
310
+ * * `dest` is not optional for this method, as it is for most others.
311
+ */
312
+ VALUE rb_cglm_vec3_addadd_vec3(VALUE self, VALUE other, VALUE dest) {
313
+ glm_vec_addadd(VAL2VEC3(self), VAL2VEC3(other), VAL2VEC3(dest));
314
+ return dest;
315
+ }
316
+
317
+ /* call-seq: subadd_vec3(other, dest) => dest
318
+ *
319
+ * Subtracts `other` from `self` and adds that result to `dest`. Equivalent to
320
+ * `dest += (self - other)`. Returns `dest`.
321
+ *
322
+ * * `dest` is not optional for this method, as it is for most others.
323
+ */
324
+ VALUE rb_cglm_vec3_subadd_vec3(VALUE self, VALUE other, VALUE dest) {
325
+ glm_vec_subadd(VAL2VEC3(self), VAL2VEC3(other), VAL2VEC3(dest));
326
+ return dest;
327
+ }
328
+
329
+ /* call-seq: muladd_vec3(other, dest) => dest
330
+ *
331
+ * Multiplies `self` with `other` and adds that result to `dest`. Equivalent to
332
+ * `dest += (self * other)`. Returns `dest`.
333
+ *
334
+ * * `dest` is not optional for this method, as it is for most others.
335
+ */
336
+ VALUE rb_cglm_vec3_muladd_vec3(VALUE self, VALUE other, VALUE dest) {
337
+ glm_vec_muladd(VAL2VEC3(self), VAL2VEC3(other), VAL2VEC3(dest));
338
+ return dest;
339
+ }
340
+
341
+ /* call-seq: muladd_scalar(other, dest) => dest
342
+ *
343
+ * Multiplies `self` with `other` and adds that result to `dest`. Equivalent to
344
+ * `dest += (self * other)`. Returns `dest`.
345
+ *
346
+ * * `other` is a Numeric, not a vector type.
347
+ *
348
+ * * `dest` is not optional for this method, as it is for most others.
349
+ */
350
+ VALUE rb_cglm_vec3_muladd_scalar(VALUE self, VALUE other, VALUE dest) {
351
+ glm_vec_muladds(VAL2VEC3(self), NUM2FLT(other), VAL2VEC3(dest));
352
+ return dest;
353
+ }
354
+
355
+ /* call-seq: flip_signs([dest]) => dest | new Vec3
356
+ *
357
+ * Flips the sign of each component and places the result into `dest`. Returns
358
+ * `dest`. If `dest` is omitted, a new Vec3 is allocated.
359
+ */
360
+ VALUE rb_cglm_vec3_flip_signs(int argc, VALUE *argv, VALUE self) {
361
+ VALUE dest;
362
+ rb_scan_args(argc, argv, "01", &dest);
363
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
364
+ glm_vec_flipsign_to(VAL2VEC3(self), VAL2VEC3(dest));
365
+ return dest;
366
+ }
367
+
368
+ /* call-seq: flip_signs! => self
369
+ *
370
+ * Flips the sign of each component, modifying `self` in-place. Returns `self`.
371
+ */
372
+ VALUE rb_cglm_vec3_flip_signs_self(VALUE self) {
373
+ glm_vec_flipsign(VAL2VEC3(self));
374
+ return self;
375
+ }
376
+
377
+ /* call-seq: normalize([dest]) => dest | new Vec3
378
+ *
379
+ * Normalizes `self` and places the result into `dest`. If `dest` is omitted,
380
+ * a new Vec3 is allocated. Returns `dest`.
381
+ */
382
+ VALUE rb_cglm_vec3_normalize(int argc, VALUE *argv, VALUE self) {
383
+ VALUE dest;
384
+ rb_scan_args(argc, argv, "01", &dest);
385
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
386
+ glm_vec_normalize_to(VAL2VEC3(self), VAL2VEC3(dest));
387
+ return dest;
388
+ }
389
+
390
+ /* call-seq: normalize! => self
391
+ *
392
+ * Normalizes `self` in-place, and returns `self`.
393
+ */
394
+ VALUE rb_cglm_vec3_normalize_self(VALUE self) {
395
+ glm_vec_normalize(VAL2VEC3(self));
396
+ return self;
397
+ }
398
+
399
+ /* call-seq: angle(other) => Numeric
400
+ *
401
+ * Returns the angle between `self` and `other`, in radians.
402
+ */
403
+ VALUE rb_cglm_vec3_angle(VALUE self, VALUE other) {
404
+ return DBL2NUM(glm_vec_angle(VAL2VEC3(self), VAL2VEC3(other)));
405
+ }
406
+
407
+ /* call-seq: rotate_axis_angle(axis, angle[, dest]) => dest | new Vec3
408
+ *
409
+ * Rotates `self` around `axis` (a Vec3) by the specified `angle` (in radians)
410
+ * using Rodrigues' rotation formula. Places the result into `dest` and
411
+ * returns `dest`. Allocates a new Vec3 if `dest` is omitted.
412
+ */
413
+ VALUE rb_cglm_vec3_rotate_axis_angle(int argc, VALUE *argv, VALUE self) {
414
+ VALUE axis, angle, dest;
415
+ rb_scan_args(argc, argv, "21", &axis, &angle, &dest);
416
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
417
+ memcpy(&VAL2VEC3(dest), &VAL2VEC3(self), sizeof(vec3));
418
+ glm_vec_rotate(VAL2VEC3(dest), NUM2FLT(angle), VAL2VEC3(axis));
419
+ return dest;
420
+ }
421
+
422
+ /* call-seq: rotate_axis_angle!(axis, angle) => self
423
+ *
424
+ * Rotates `self` around `axis` (a Vec3) by the specified `angle` (in radians)
425
+ * using Rodrigues' rotation formula. Places the result into `self` and
426
+ * returns `self`.
427
+ */
428
+ VALUE rb_cglm_vec3_rotate_axis_angle_self(VALUE self, VALUE axis, VALUE angle) {
429
+ glm_vec_rotate(VAL2VEC3(self), NUM2FLT(angle), VAL2VEC3(axis));
430
+ return self;
431
+ }
432
+
433
+ /* call-seq: rotate_mat4(mat[, dest]) => dest | new Vec3
434
+ *
435
+ * Rotate `self` by the given rotation or affine matrix. Places the result in
436
+ * `dest` and returns `dest`. Creates and returns a new Vec3 if `dest` is
437
+ * omitted.
438
+ *
439
+ * * `mat` format should be (no perspective):
440
+ *
441
+ * a b c x
442
+ * e f g y
443
+ * i j k z
444
+ * 0 0 0 w
445
+ */
446
+ VALUE rb_cglm_vec3_rotate_mat4(int argc, VALUE *argv, VALUE self) {
447
+ VALUE matrix, dest;
448
+ rb_scan_args(argc, argv, "11", &matrix, &dest);
449
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
450
+ glm_vec_rotate_m4(VAL2MAT4(matrix), VAL2VEC3(self), VAL2VEC3(dest));
451
+ return dest;
452
+ }
453
+
454
+ /* call-seq: rotate_mat4!(mat) => self
455
+ *
456
+ * Rotate `self` by the given rotation or affine matrix. Places the result in
457
+ * `self` and returns `self`.
458
+ *
459
+ * * `mat` format should be (no perspective):
460
+ *
461
+ * a b c x
462
+ * e f g y
463
+ * i j k z
464
+ * 0 0 0 w
465
+ */
466
+ VALUE rb_cglm_vec3_rotate_mat4_self(VALUE self, VALUE matrix) {
467
+ glm_vec_rotate_m4(VAL2MAT4(matrix), VAL2VEC3(self), VAL2VEC3(self));
468
+ return self;
469
+ }
470
+
471
+ /* call-seq: rotate_mat3(mat[, dest]) => dest | new Vec3
472
+ *
473
+ * Rotate `self` by the given rotation matrix. Places the result in
474
+ * `dest` and returns `dest`. Creates and returns a new Vec3 if `dest` is
475
+ * omitted.
476
+ */
477
+ VALUE rb_cglm_vec3_rotate_mat3(int argc, VALUE *argv, VALUE self) {
478
+ VALUE matrix, dest;
479
+ rb_scan_args(argc, argv, "11", &matrix, &dest);
480
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
481
+ glm_vec_rotate_m3(VAL2MAT3(matrix), VAL2VEC3(self), VAL2VEC3(dest));
482
+ return dest;
483
+ }
484
+
485
+ /* call-seq: rotate_mat3!(mat) => self
486
+ *
487
+ * Rotate `self` by the given rotation matrix. Places the result in
488
+ * `self` and returns `self`.
489
+ */
490
+ VALUE rb_cglm_vec3_rotate_mat3_self(VALUE self, VALUE matrix) {
491
+ glm_vec_rotate_m3(VAL2MAT3(matrix), VAL2VEC3(self), VAL2VEC3(self));
492
+ return self;
493
+ }
494
+
495
+ /* call-seq: project(vec[, dest]) => dest | new Vec3
496
+ *
497
+ * Projects `self` onto the given Vec3. Places the result into `dest` and
498
+ * returns `dest`. Creates and returns a new Vec3 if `dest` is omitted.
499
+ */
500
+ VALUE rb_cglm_vec3_project(int argc, VALUE *argv, VALUE self) {
501
+ VALUE b, dest;
502
+ rb_scan_args(argc, argv, "11", &b, &dest);
503
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
504
+ glm_vec_proj(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
505
+ return dest;
506
+ }
507
+
508
+ /* call-seq: project!(vec) => self
509
+ *
510
+ * Projects `self` onto the given Vec3. Places the result into `self` and
511
+ * returns `self`.
512
+ */
513
+ VALUE rb_cglm_vec3_project_self(VALUE self, VALUE b) {
514
+ glm_vec_proj(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(self));
515
+ return self;
516
+ }
517
+
518
+ /* call-seq: center(vec[, dest]) => dest | new Vec3
519
+ *
520
+ * Finds the center point between `self` and `vec`. Places the result into
521
+ * `dest` and returns `dest`. Creates and returns a new Vec3 if `dest` is
522
+ * omitted.
523
+ */
524
+ VALUE rb_cglm_vec3_center(int argc, VALUE *argv, VALUE self) {
525
+ VALUE b, dest;
526
+ rb_scan_args(argc, argv, "11", &b, &dest);
527
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
528
+ glm_vec_center(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
529
+ return dest;
530
+ }
531
+
532
+ /* call-seq: distance2(vec) => Numeric
533
+ *
534
+ * Returns the squared distance between this vector and the specified one.
535
+ */
536
+ VALUE rb_cglm_vec3_distance2(VALUE self, VALUE b) {
537
+ return DBL2NUM(glm_vec_distance2(VAL2VEC3(self), VAL2VEC3(b)));
538
+ }
539
+
540
+ /* call-seq: distance(vec) => Numeric
541
+ *
542
+ * Returns the distance between this vector and the specified one.
543
+ */
544
+ VALUE rb_cglm_vec3_distance(VALUE self, VALUE b) {
545
+ return DBL2NUM(glm_vec_distance(VAL2VEC3(self), VAL2VEC3(b)));
546
+ }
547
+
548
+ /* call-seq: max(vec[, dest]) => dest | new Vec3
549
+ *
550
+ * Finds the higher of each component (x, y, z) between `self` and `vec`.
551
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
552
+ * Vec3 if `dest` is omitted.
553
+ */
554
+ VALUE rb_cglm_vec3_max(int argc, VALUE *argv, VALUE self) {
555
+ VALUE b, dest;
556
+ rb_scan_args(argc, argv, "11", &b, &dest);
557
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
558
+ glm_vec_maxv(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
559
+ return dest;
560
+ }
561
+
562
+ /* call-seq: min(vec[, dest]) => dest | new Vec3
563
+ *
564
+ * Finds the lower of each component (x, y, z) between `self` and `vec`.
565
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
566
+ * Vec3 if `dest` is omitted.
567
+ */
568
+ VALUE rb_cglm_vec3_min(int argc, VALUE *argv, VALUE self) {
569
+ VALUE b, dest;
570
+ rb_scan_args(argc, argv, "11", &b, &dest);
571
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
572
+ glm_vec_minv(VAL2VEC3(self), VAL2VEC3(b), VAL2VEC3(dest));
573
+ return dest;
574
+ }
575
+
576
+ /* call-seq: ortho(vec[, dest]) => dest | new Vec3
577
+ *
578
+ * Finds an orthogonal/perpendicular vector to `self`.
579
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
580
+ * Vec3 if `dest` is omitted.
581
+ */
582
+ VALUE rb_cglm_vec3_ortho(int argc, VALUE *argv, VALUE self) {
583
+ VALUE dest;
584
+ rb_scan_args(argc, argv, "01", &dest);
585
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
586
+ glm_vec_ortho(VAL2VEC3(self), VAL2VEC3(dest));
587
+ return dest;
588
+ }
589
+
590
+ /* call-seq: clamp_scalar(min, max[, dest]) => dest | new Vec3
591
+ *
592
+ * Clamps each component in `self` to the range given by `min` and `max`.
593
+ * Places the result into `dest` and returns `dest`. Creates and returns a new
594
+ * Vec3 if `dest` is omitted.
595
+ */
596
+ VALUE rb_cglm_vec3_clamp_scalar(int argc, VALUE *argv, VALUE self) {
597
+ VALUE a, b, dest;
598
+ rb_scan_args(argc, argv, "21", &a, &b, &dest);
599
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
600
+ memcpy(&VAL2VEC3(dest), &VAL2VEC3(self), sizeof(vec3));
601
+ glm_vec_clamp(VAL2VEC3(dest), NUM2FLT(a), NUM2FLT(b));
602
+ return dest;
603
+ }
604
+
605
+ /* call-seq: clamp_scalar!(min, max) => self
606
+ *
607
+ * Clamps each component in `self` to the range given by `min` and `max`.
608
+ * Places the result into `self` and returns `self`.
609
+ */
610
+ VALUE rb_cglm_vec3_clamp_scalar_self(VALUE self, VALUE a, VALUE b) {
611
+ glm_vec_clamp(VAL2VEC3(self), NUM2FLT(a), NUM2FLT(b));
612
+ return self;
613
+ }
614
+
615
+ /* call-seq: lerp!(from, to, amount) => self
616
+ *
617
+ * Performs linear interpolation between `from` and `to`, both of which should
618
+ * be Vec3's, by the specified `amount` which should be a number. Modifies
619
+ * `self` in-place and returns `self`.
620
+ */
621
+ VALUE rb_cglm_vec3_lerp_self(VALUE self, VALUE from, VALUE to, VALUE amount) {
622
+ glm_vec_lerp(VAL2VEC3(from), VAL2VEC3(to), NUM2FLT(amount), VAL2VEC3(self));
623
+ return self;
624
+ }
625
+
626
+ /* call-seq: broadcast!(val) => self
627
+ *
628
+ * Sets each member of `self` to the specified Numeric value and returns
629
+ * `self`.
630
+ */
631
+ VALUE rb_cglm_vec3_broadcast_self(VALUE self, VALUE val) {
632
+ glm_vec_broadcast(NUM2FLT(val), VAL2VEC3(self));
633
+ return self;
634
+ }
635
+
636
+ /* call-seq: equals_scalar(val) => true|false
637
+ *
638
+ * Returns true if the given scalar value exactly equals each component of
639
+ * this Vec3, false otherwise.
640
+ */
641
+ VALUE rb_cglm_vec3_equals_scalar(VALUE self, VALUE val) {
642
+ return glm_vec_eq(VAL2VEC3(self), NUM2FLT(val)) ? Qtrue : Qfalse;
643
+ }
644
+
645
+ /* call-seq: equalish_scalar(val[, epsilon]) => true|false
646
+ *
647
+ * Returns true if the given scalar value is very close to each component of
648
+ * this Vec3, false otherwise. Useful for dealing with the loss of precision
649
+ * during floating point arithmetic.
650
+ */
651
+ VALUE rb_cglm_vec3_equalish_scalar(int argc, VALUE *argv, VALUE self) {
652
+ VALUE val, eps;
653
+ float epsil = FLT_EPSILON;
654
+ rb_scan_args(argc, argv, "11", &val, &eps);
655
+ if (!NIL_P(eps)) epsil = NUM2FLT(eps);
656
+ float s = NUM2FLT(val);
657
+ vec3 *v = &VAL2VEC3(self);
658
+ return fabsf((*v)[0] - s) <= eps &&
659
+ fabsf((*v)[1] - s) <= eps &&
660
+ fabsf((*v)[2] - s) <= eps ? Qtrue : Qfalse;
661
+ }
662
+
663
+ /* call-seq: equals_all => true|false
664
+ *
665
+ * Returns true if each component in this Vec3 has the same exact value.
666
+ */
667
+ VALUE rb_cglm_vec3_equals_all(VALUE self) {
668
+ return glm_vec_eq_all(VAL2VEC3(self)) ? Qtrue : Qfalse;
669
+ }
670
+
671
+ /* call-seq: equals_vec3(other) => true|false
672
+ *
673
+ * Returns true if this vector exactly matches the given one.
674
+ */
675
+ VALUE rb_cglm_vec3_equals_vec3(VALUE self, VALUE other) {
676
+ return glm_vec_eqv(VAL2VEC3(self), VAL2VEC3(other)) ? Qtrue : Qfalse;
677
+ }
678
+
679
+ /* call-seq: equalish_vec3(other[, epsilon]) => true|false
680
+ *
681
+ * Returns true if this vector is very close to equal to the given one. Useful
682
+ * for dealing with the loss of precision during floating point arithmetic.
683
+ */
684
+ VALUE rb_cglm_vec3_equalish_vec3(int argc, VALUE *argv, VALUE self) {
685
+ VALUE val, eps;
686
+ float epsil = FLT_EPSILON;
687
+ rb_scan_args(argc, argv, "11", &val, &eps);
688
+ if (!NIL_P(eps)) epsil = NUM2FLT(eps);
689
+ vec3 *s = &VAL2VEC3(val);
690
+ vec3 *v = &VAL2VEC3(self);
691
+ return fabsf((*v)[0] - (*s)[0]) <= eps &&
692
+ fabsf((*v)[1] - (*s)[1]) <= eps &&
693
+ fabsf((*v)[2] - (*s)[2]) <= eps ? Qtrue : Qfalse;
694
+ }
695
+
696
+ /* call-seq: highest => Numeric
697
+ *
698
+ * Returns the value of the highest component in this Vec3.
699
+ */
700
+ VALUE rb_cglm_vec3_highest(VALUE self) {
701
+ return DBL2NUM(glm_vec_max(VAL2VEC3(self)));
702
+ }
703
+
704
+ /* call-seq: lowest => Numeric
705
+ *
706
+ * Returns the value of the lowest component in this Vec3.
707
+ */
708
+ VALUE rb_cglm_vec3_lowest(VALUE self) {
709
+ return DBL2NUM(glm_vec_min(VAL2VEC3(self)));
710
+ }
711
+
712
+ /* call-seq: nan? => true|false
713
+ *
714
+ * Returns true if any component in this vector is nan, false otherwise.
715
+ * You should only use this in DEBUG mode or very critical asserts.
716
+ */
717
+ VALUE rb_cglm_vec3_is_nan(VALUE self) {
718
+ return glm_vec_isnan(VAL2VEC3(self)) ? Qtrue : Qfalse;
719
+ }
720
+
721
+ /* call-seq: inf? => true|false
722
+ *
723
+ * Returns true if any component in this vector is inf, false otherwise.
724
+ * You should only use this in DEBUG mode or very critical asserts.
725
+ */
726
+ VALUE rb_cglm_vec3_is_inf(VALUE self) {
727
+ return glm_vec_isinf(VAL2VEC3(self)) ? Qtrue : Qfalse;
728
+ }
729
+
730
+ /* call-seq: valid? => true|false
731
+ *
732
+ * Returns true if no component in this vector is NaN or infinite, false
733
+ * otherwise. You should only use this in DEBUG mode or very critical asserts.
734
+ */
735
+ VALUE rb_cglm_vec3_is_valid(VALUE self) {
736
+ return glm_vec_isvalid(VAL2VEC3(self)) ? Qtrue : Qfalse;
737
+ }
738
+
739
+ /* call-seq: signs([dest]) => dest | new Vec3
740
+ *
741
+ * Places `+1`, `0` or `-1` into each component of `dest` based on whether the
742
+ * corresponding component of this Vec3 is positive, `0`/`NaN`, or negative.
743
+ * If `dest` is omitted, a new Vec3 is created and returned.
744
+ */
745
+ VALUE rb_cglm_vec3_signs(int argc, VALUE *argv, VALUE self) {
746
+ VALUE dest;
747
+ rb_scan_args(argc, argv, "01", &dest);
748
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
749
+ glm_vec_sign(VAL2VEC3(self), VAL2VEC3(dest));
750
+ return dest;
751
+ }
752
+
753
+ /* call-seq: sqrt([dest]) => dest | new Vec3
754
+ *
755
+ * For each component of this Vec3, places the square root of that component
756
+ * into `dest`. If `dest` is omitted, a new Vec3 is created. Returns `dest`.
757
+ */
758
+ VALUE rb_cglm_vec3_sqrt(int argc, VALUE *argv, VALUE self) {
759
+ VALUE dest;
760
+ rb_scan_args(argc, argv, "01", &dest);
761
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
762
+ glm_vec_sqrt(VAL2VEC3(self), VAL2VEC3(dest));
763
+ return dest;
764
+ }
765
+
766
+ /* call-seq: to_vec4([last, dest]) => dest | new Vec4
767
+ *
768
+ * Places the 3 components of this Vec3 into the first 3 components of the
769
+ * `dest` Vec4. Sets the final component to the value of `last`, which
770
+ * defaults to `1`. If `dest` is omitted, a new Vec4 is created.
771
+ */
772
+ VALUE rb_cglm_vec3_to_vec4(int argc, VALUE *argv, VALUE self) {
773
+ VALUE last, dest;
774
+ rb_scan_args(argc, argv, "02", &last, &dest);
775
+ if (NIL_P(last)) last = INT2NUM(1);
776
+ if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
777
+ glm_vec4(VAL2VEC3(self), NUM2FLT(last), VAL2VEC4(dest));
778
+ return dest;
779
+ }
780
+
781
+ /* call-seq: random([dest]) => dest | new Vec3
782
+ *
783
+ * Fills `dest` or a new Vec3 with random values, and returns it.
784
+ */
785
+ VALUE rb_cglm_vec3_new_random(int argc, VALUE *argv, VALUE self) {
786
+ VALUE dest;
787
+ rb_scan_args(argc, argv, "01", &dest);
788
+ if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
789
+
790
+ VAL2VEC3(dest)[0] = drand48();
791
+ VAL2VEC3(dest)[1] = drand48();
792
+ VAL2VEC3(dest)[2] = drand48();
793
+
794
+ return dest;
795
+ }
796
+
797
+ void Init_cglm_vec3() {
798
+ rb_define_method(rb_cVec3, "-@", rb_cglm_vec3_flip_signs, -1);
799
+ rb_define_method(rb_cVec3, "[]", rb_cglm_vec3_aref, 1);
800
+ rb_define_method(rb_cVec3, "[]=", rb_cglm_vec3_aset, 2);
801
+ rb_define_method(rb_cVec3, "zero!", rb_cglm_vec3_zero_self, 0);
802
+ rb_define_method(rb_cVec3, "one!", rb_cglm_vec3_one_self, 0);
803
+ rb_define_method(rb_cVec3, "dot", rb_cglm_vec3_dot, 1);
804
+ rb_define_method(rb_cVec3, "cross", rb_cglm_vec3_cross, -1);
805
+ rb_define_method(rb_cVec3, "norm2", rb_cglm_vec3_norm2, 0);
806
+ rb_define_method(rb_cVec3, "norm", rb_cglm_vec3_norm, 0);
807
+ rb_define_method(rb_cVec3, "add_vec3", rb_cglm_vec3_add_vec3, -1);
808
+ rb_define_method(rb_cVec3, "add_scalar", rb_cglm_vec3_add_scalar, -1);
809
+ rb_define_method(rb_cVec3, "sub_vec3", rb_cglm_vec3_sub_vec3, -1);
810
+ rb_define_method(rb_cVec3, "sub_scalar", rb_cglm_vec3_sub_scalar, -1);
811
+ rb_define_method(rb_cVec3, "add_vec3!", rb_cglm_vec3_add_vec3_self, 1);
812
+ rb_define_method(rb_cVec3, "add_scalar!", rb_cglm_vec3_add_scalar_self, 1);
813
+ rb_define_method(rb_cVec3, "sub_vec3!", rb_cglm_vec3_sub_vec3_self, 1);
814
+ rb_define_method(rb_cVec3, "sub_scalar!", rb_cglm_vec3_sub_scalar_self, 1);
815
+ rb_define_method(rb_cVec3, "mul_vec3", rb_cglm_vec3_mul_vec3, -1);
816
+ rb_define_method(rb_cVec3, "mul_vec3!", rb_cglm_vec3_mul_vec3_self, 1);
817
+ rb_define_method(rb_cVec3, "mul_scalar", rb_cglm_vec3_mul_scalar, -1);
818
+ rb_define_method(rb_cVec3, "mul_scalar!", rb_cglm_vec3_mul_scalar_self, 1);
819
+ rb_define_method(rb_cVec3, "div_vec3", rb_cglm_vec3_div_vec3, -1);
820
+ rb_define_method(rb_cVec3, "div_vec3!", rb_cglm_vec3_div_vec3_self, 1);
821
+ rb_define_method(rb_cVec3, "div_scalar", rb_cglm_vec3_div_scalar, -1);
822
+ rb_define_method(rb_cVec3, "div_scalar!", rb_cglm_vec3_div_scalar_self, 1);
823
+ rb_define_method(rb_cVec3, "resize", rb_cglm_vec3_resize, -1);
824
+ rb_define_method(rb_cVec3, "resize!", rb_cglm_vec3_resize_self, 1);
825
+ rb_define_method(rb_cVec3, "addadd_vec3", rb_cglm_vec3_addadd_vec3, 2);
826
+ rb_define_method(rb_cVec3, "subadd_vec3", rb_cglm_vec3_subadd_vec3, 2);
827
+ rb_define_method(rb_cVec3, "muladd_scalar", rb_cglm_vec3_muladd_scalar, 2);
828
+ rb_define_method(rb_cVec3, "muladd_vec3", rb_cglm_vec3_muladd_vec3, 2);
829
+ rb_define_method(rb_cVec3, "flip_signs", rb_cglm_vec3_flip_signs, -1);
830
+ rb_define_method(rb_cVec3, "flip_signs!", rb_cglm_vec3_flip_signs_self, 0);
831
+ rb_define_method(rb_cVec3, "normalize", rb_cglm_vec3_normalize, -1);
832
+ rb_define_method(rb_cVec3, "normalize!", rb_cglm_vec3_normalize_self, 0);
833
+ rb_define_method(rb_cVec3, "angle", rb_cglm_vec3_angle, 1);
834
+ rb_define_method(rb_cVec3, "rotate_axis_angle", rb_cglm_vec3_rotate_axis_angle, -1);
835
+ rb_define_method(rb_cVec3, "rotate_axis_angle!", rb_cglm_vec3_rotate_axis_angle_self, 2);
836
+ rb_define_method(rb_cVec3, "rotate_mat4", rb_cglm_vec3_rotate_mat4, -1);
837
+ rb_define_method(rb_cVec3, "rotate_mat4!", rb_cglm_vec3_rotate_mat4_self, 1);
838
+ rb_define_method(rb_cVec3, "rotate_mat3", rb_cglm_vec3_rotate_mat3, -1);
839
+ rb_define_method(rb_cVec3, "rotate_mat3!", rb_cglm_vec3_rotate_mat3_self, 1);
840
+ rb_define_method(rb_cVec3, "project", rb_cglm_vec3_project, -1);
841
+ rb_define_method(rb_cVec3, "project!", rb_cglm_vec3_project_self, 1);
842
+ rb_define_method(rb_cVec3, "center", rb_cglm_vec3_center, -1);
843
+ rb_define_method(rb_cVec3, "distance2", rb_cglm_vec3_distance2, 1);
844
+ rb_define_method(rb_cVec3, "distance", rb_cglm_vec3_distance, 1);
845
+ rb_define_method(rb_cVec3, "max", rb_cglm_vec3_max, -1);
846
+ rb_define_method(rb_cVec3, "min", rb_cglm_vec3_min, -1);
847
+ rb_define_method(rb_cVec3, "ortho", rb_cglm_vec3_ortho, -1);
848
+ rb_define_method(rb_cVec3, "clamp_scalar", rb_cglm_vec3_clamp_scalar, -1);
849
+ rb_define_method(rb_cVec3, "clamp_scalar!", rb_cglm_vec3_clamp_scalar_self, 2);
850
+ rb_define_method(rb_cVec3, "lerp!", rb_cglm_vec3_lerp_self, 3);
851
+ rb_define_method(rb_cVec3, "broadcast!", rb_cglm_vec3_broadcast_self, 1);
852
+ rb_define_method(rb_cVec3, "equals_scalar", rb_cglm_vec3_equals_scalar, 1);
853
+ rb_define_method(rb_cVec3, "equalish_scalar", rb_cglm_vec3_equalish_scalar, -1);
854
+ rb_define_method(rb_cVec3, "equals_all", rb_cglm_vec3_equals_all, 0);
855
+ rb_define_method(rb_cVec3, "equals_vec3", rb_cglm_vec3_equals_vec3, 1);
856
+ rb_define_method(rb_cVec3, "equalish_vec3", rb_cglm_vec3_equalish_vec3, -1);
857
+ rb_define_method(rb_cVec3, "highest", rb_cglm_vec3_highest, 0);
858
+ rb_define_method(rb_cVec3, "lowest", rb_cglm_vec3_lowest, 0);
859
+ rb_define_method(rb_cVec3, "nan?", rb_cglm_vec3_is_nan, 0);
860
+ rb_define_method(rb_cVec3, "inf?", rb_cglm_vec3_is_inf, 0);
861
+ rb_define_method(rb_cVec3, "valid?", rb_cglm_vec3_is_valid, 0);
862
+ rb_define_method(rb_cVec3, "signs", rb_cglm_vec3_signs, -1);
863
+ rb_define_method(rb_cVec3, "sqrt", rb_cglm_vec3_sqrt, -1);
864
+ rb_define_method(rb_cVec3, "to_vec4", rb_cglm_vec3_to_vec4, -1);
865
+
866
+ rb_define_alias(rb_cVec3, "invert", "flip_signs");
867
+ rb_define_alias(rb_cVec3, "invert!", "flip_signs!");
868
+ rb_define_alias(rb_cVec3, "magnitude", "norm");
869
+ rb_define_alias(rb_cVec3, "mag", "norm");
870
+ rb_define_alias(rb_cVec3, "magnitude2", "norm2");
871
+ rb_define_alias(rb_cVec3, "mag2", "norm2");
872
+
873
+ rb_define_singleton_method(rb_cVec3, "random", rb_cglm_vec3_new_random, -1);
874
+ rb_define_singleton_method(rb_cVec3, "rand", rb_cglm_vec3_new_random, -1);
875
+ rb_define_singleton_method(rb_cVec3, "size", rb_cglm_vec3_size_bytes, 0);
876
+ rb_define_singleton_method(rb_cVec3, "alignment", rb_cglm_vec3_alignment_bytes, 0);
877
+ rb_define_singleton_method(rb_cVec3, "one", rb_cglm_vec3_one, 0);
878
+ rb_define_singleton_method(rb_cVec3, "zero", rb_cglm_vec3_zero, 0);
879
+ rb_define_singleton_method(rb_cVec3, "xup", rb_cglm_vec3_xup, 0);
880
+ rb_define_singleton_method(rb_cVec3, "yup", rb_cglm_vec3_yup, 0);
881
+ rb_define_singleton_method(rb_cVec3, "zup", rb_cglm_vec3_zup, 0);
882
+ }