larb 0.1.0 → 1.0.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +14 -1
  4. data/ext/larb/color.c +446 -0
  5. data/ext/larb/color.h +35 -0
  6. data/ext/larb/extconf.rb +11 -0
  7. data/ext/larb/larb.c +27 -0
  8. data/ext/larb/larb.h +8 -0
  9. data/ext/larb/mat2.c +300 -0
  10. data/ext/larb/mat2.h +30 -0
  11. data/ext/larb/mat2d.c +380 -0
  12. data/ext/larb/mat2d.h +35 -0
  13. data/ext/larb/mat3.c +469 -0
  14. data/ext/larb/mat3.h +33 -0
  15. data/ext/larb/mat4.c +671 -0
  16. data/ext/larb/mat4.h +31 -0
  17. data/ext/larb/quat.c +523 -0
  18. data/ext/larb/quat.h +39 -0
  19. data/ext/larb/quat2.c +473 -0
  20. data/ext/larb/quat2.h +39 -0
  21. data/ext/larb/vec2.c +342 -0
  22. data/ext/larb/vec2.h +43 -0
  23. data/ext/larb/vec3.c +503 -0
  24. data/ext/larb/vec3.h +52 -0
  25. data/ext/larb/vec4.c +340 -0
  26. data/ext/larb/vec4.h +38 -0
  27. data/lib/larb/version.rb +5 -0
  28. data/lib/larb.rb +2 -14
  29. data/test/larb/color_test.rb +278 -0
  30. data/test/larb/mat2_test.rb +144 -0
  31. data/test/larb/mat2d_test.rb +172 -0
  32. data/test/larb/mat3_test.rb +147 -0
  33. data/test/larb/mat4_test.rb +270 -0
  34. data/test/larb/quat2_test.rb +161 -0
  35. data/test/larb/quat_test.rb +224 -0
  36. data/test/larb/vec2_test.rb +251 -0
  37. data/test/larb/vec3_test.rb +310 -0
  38. data/test/larb/vec4_test.rb +189 -0
  39. data/test/test_helper.rb +4 -0
  40. metadata +53 -14
  41. data/Rakefile +0 -11
  42. data/lib/larb/color.rb +0 -148
  43. data/lib/larb/mat2.rb +0 -119
  44. data/lib/larb/mat2d.rb +0 -180
  45. data/lib/larb/mat3.rb +0 -238
  46. data/lib/larb/mat4.rb +0 -329
  47. data/lib/larb/quat.rb +0 -238
  48. data/lib/larb/quat2.rb +0 -193
  49. data/lib/larb/vec2.rb +0 -150
  50. data/lib/larb/vec3.rb +0 -218
  51. data/lib/larb/vec4.rb +0 -125
data/ext/larb/quat2.c ADDED
@@ -0,0 +1,473 @@
1
+ #include "quat2.h"
2
+
3
+ #include <math.h>
4
+
5
+ static void quat2_free(void *ptr) {
6
+ xfree(ptr);
7
+ }
8
+
9
+ static size_t quat2_memsize(const void *ptr) {
10
+ return sizeof(Quat2Data);
11
+ }
12
+
13
+ static const rb_data_type_t quat2_type = {
14
+ "Quat2",
15
+ {0, quat2_free, quat2_memsize},
16
+ 0,
17
+ 0,
18
+ RUBY_TYPED_FREE_IMMEDIATELY,
19
+ };
20
+
21
+ static VALUE cQuat2 = Qnil;
22
+ static VALUE cQuat = Qnil;
23
+ static VALUE cVec3 = Qnil;
24
+ static VALUE cMat4 = Qnil;
25
+
26
+ static double value_to_double(VALUE value) {
27
+ VALUE coerced = rb_funcall(value, rb_intern("to_f"), 0);
28
+ return NUM2DBL(coerced);
29
+ }
30
+
31
+ static Quat2Data *quat2_get(VALUE obj) {
32
+ Quat2Data *data = NULL;
33
+ TypedData_Get_Struct(obj, Quat2Data, &quat2_type, data);
34
+ return data;
35
+ }
36
+
37
+ static VALUE quat2_build(VALUE klass, const double *values) {
38
+ VALUE obj = quat2_alloc(klass);
39
+ Quat2Data *data = quat2_get(obj);
40
+ for (int i = 0; i < 8; i++) {
41
+ data->data[i] = values[i];
42
+ }
43
+ return obj;
44
+ }
45
+
46
+ static VALUE quat2_build8(VALUE klass, double v0, double v1, double v2,
47
+ double v3, double v4, double v5, double v6,
48
+ double v7) {
49
+ double values[8] = {v0, v1, v2, v3, v4, v5, v6, v7};
50
+ return quat2_build(klass, values);
51
+ }
52
+
53
+ static VALUE quat2_class_identity(VALUE klass) {
54
+ return quat2_build8(klass, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0);
55
+ }
56
+
57
+ static VALUE quat2_class_from_rotation_translation(VALUE klass, VALUE rotation,
58
+ VALUE translation) {
59
+ double rx = value_to_double(rb_funcall(rotation, rb_intern("x"), 0));
60
+ double ry = value_to_double(rb_funcall(rotation, rb_intern("y"), 0));
61
+ double rz = value_to_double(rb_funcall(rotation, rb_intern("z"), 0));
62
+ double rw = value_to_double(rb_funcall(rotation, rb_intern("w"), 0));
63
+ double tx = value_to_double(rb_funcall(translation, rb_intern("x"), 0));
64
+ double ty = value_to_double(rb_funcall(translation, rb_intern("y"), 0));
65
+ double tz = value_to_double(rb_funcall(translation, rb_intern("z"), 0));
66
+
67
+ return quat2_build8(
68
+ klass, rx, ry, rz, rw, (tx * rw + ty * rz - tz * ry) * 0.5,
69
+ (ty * rw + tz * rx - tx * rz) * 0.5,
70
+ (tz * rw + tx * ry - ty * rx) * 0.5,
71
+ (-tx * rx - ty * ry - tz * rz) * 0.5);
72
+ }
73
+
74
+ static VALUE quat2_class_from_translation(VALUE klass, VALUE translation) {
75
+ VALUE identity = rb_funcall(cQuat, rb_intern("identity"), 0);
76
+ return quat2_class_from_rotation_translation(klass, identity, translation);
77
+ }
78
+
79
+ static VALUE quat2_class_from_rotation(VALUE klass, VALUE rotation) {
80
+ double rx = value_to_double(rb_funcall(rotation, rb_intern("x"), 0));
81
+ double ry = value_to_double(rb_funcall(rotation, rb_intern("y"), 0));
82
+ double rz = value_to_double(rb_funcall(rotation, rb_intern("z"), 0));
83
+ double rw = value_to_double(rb_funcall(rotation, rb_intern("w"), 0));
84
+ return quat2_build8(klass, rx, ry, rz, rw, 0.0, 0.0, 0.0, 0.0);
85
+ }
86
+
87
+ static VALUE quat2_class_from_mat4(VALUE klass, VALUE mat4) {
88
+ VALUE rotation = rb_funcall(mat4, rb_intern("extract_rotation"), 0);
89
+ VALUE translation = rb_funcall(mat4, rb_intern("extract_translation"), 0);
90
+ return quat2_class_from_rotation_translation(klass, rotation, translation);
91
+ }
92
+
93
+ VALUE quat2_alloc(VALUE klass) {
94
+ Quat2Data *data = ALLOC(Quat2Data);
95
+ data->data[0] = 0.0;
96
+ data->data[1] = 0.0;
97
+ data->data[2] = 0.0;
98
+ data->data[3] = 1.0;
99
+ data->data[4] = 0.0;
100
+ data->data[5] = 0.0;
101
+ data->data[6] = 0.0;
102
+ data->data[7] = 0.0;
103
+ return TypedData_Wrap_Struct(klass, &quat2_type, data);
104
+ }
105
+
106
+ VALUE quat2_initialize(int argc, VALUE *argv, VALUE self) {
107
+ VALUE data_arg = Qnil;
108
+ Quat2Data *data = quat2_get(self);
109
+
110
+ rb_scan_args(argc, argv, "01", &data_arg);
111
+ if (NIL_P(data_arg)) {
112
+ data->data[0] = 0.0;
113
+ data->data[1] = 0.0;
114
+ data->data[2] = 0.0;
115
+ data->data[3] = 1.0;
116
+ data->data[4] = 0.0;
117
+ data->data[5] = 0.0;
118
+ data->data[6] = 0.0;
119
+ data->data[7] = 0.0;
120
+ return self;
121
+ }
122
+
123
+ VALUE ary = rb_check_array_type(data_arg);
124
+ if (NIL_P(ary)) {
125
+ rb_raise(rb_eTypeError, "expected Array");
126
+ }
127
+
128
+ for (int i = 0; i < 8; i++) {
129
+ data->data[i] = value_to_double(rb_ary_entry(ary, i));
130
+ }
131
+
132
+ return self;
133
+ }
134
+
135
+ VALUE quat2_real(VALUE self) {
136
+ Quat2Data *a = quat2_get(self);
137
+ return rb_funcall(cQuat, rb_intern("new"), 4, DBL2NUM(a->data[0]),
138
+ DBL2NUM(a->data[1]), DBL2NUM(a->data[2]),
139
+ DBL2NUM(a->data[3]));
140
+ }
141
+
142
+ VALUE quat2_dual(VALUE self) {
143
+ Quat2Data *a = quat2_get(self);
144
+ return rb_funcall(cQuat, rb_intern("new"), 4, DBL2NUM(a->data[4]),
145
+ DBL2NUM(a->data[5]), DBL2NUM(a->data[6]),
146
+ DBL2NUM(a->data[7]));
147
+ }
148
+
149
+ VALUE quat2_aref(VALUE self, VALUE index) {
150
+ Quat2Data *data = quat2_get(self);
151
+ long idx = NUM2LONG(index);
152
+ if (idx < 0 || idx > 7) {
153
+ return Qnil;
154
+ }
155
+ return DBL2NUM(data->data[idx]);
156
+ }
157
+
158
+ VALUE quat2_aset(VALUE self, VALUE index, VALUE value) {
159
+ Quat2Data *data = quat2_get(self);
160
+ long idx = NUM2LONG(index);
161
+ if (idx < 0 || idx > 7) {
162
+ rb_raise(rb_eIndexError, "index %ld out of range", idx);
163
+ }
164
+ data->data[idx] = value_to_double(value);
165
+ return value;
166
+ }
167
+
168
+ VALUE quat2_mul(VALUE self, VALUE other) {
169
+ Quat2Data *a = quat2_get(self);
170
+
171
+ if (rb_obj_is_kind_of(other, cQuat2)) {
172
+ Quat2Data *b = quat2_get(other);
173
+ double ax0 = a->data[0];
174
+ double ay0 = a->data[1];
175
+ double az0 = a->data[2];
176
+ double aw0 = a->data[3];
177
+ double bx1 = a->data[4];
178
+ double by1 = a->data[5];
179
+ double bz1 = a->data[6];
180
+ double bw1 = a->data[7];
181
+ double ax1 = b->data[0];
182
+ double ay1 = b->data[1];
183
+ double az1 = b->data[2];
184
+ double aw1 = b->data[3];
185
+ double bx0 = b->data[4];
186
+ double by0 = b->data[5];
187
+ double bz0 = b->data[6];
188
+ double bw0 = b->data[7];
189
+
190
+ return quat2_build8(
191
+ rb_obj_class(self),
192
+ ax0 * aw1 + aw0 * ax1 + ay0 * az1 - az0 * ay1,
193
+ ay0 * aw1 + aw0 * ay1 + az0 * ax1 - ax0 * az1,
194
+ az0 * aw1 + aw0 * az1 + ax0 * ay1 - ay0 * ax1,
195
+ aw0 * aw1 - ax0 * ax1 - ay0 * ay1 - az0 * az1,
196
+ ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0 +
197
+ bx1 * aw1 + bw1 * ax1 + by1 * az1 - bz1 * ay1,
198
+ ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0 +
199
+ by1 * aw1 + bw1 * ay1 + bz1 * ax1 - bx1 * az1,
200
+ az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0 +
201
+ bz1 * aw1 + bw1 * az1 + bx1 * ay1 - by1 * ax1,
202
+ aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0 +
203
+ bw1 * aw1 - bx1 * ax1 - by1 * ay1 - bz1 * az1);
204
+ }
205
+
206
+ if (rb_obj_is_kind_of(other, cVec3)) {
207
+ return quat2_transform_point(self, other);
208
+ }
209
+
210
+ if (rb_obj_is_kind_of(other, rb_cNumeric)) {
211
+ double s = value_to_double(other);
212
+ double values[8];
213
+ for (int i = 0; i < 8; i++) {
214
+ values[i] = a->data[i] * s;
215
+ }
216
+ return quat2_build(rb_obj_class(self), values);
217
+ }
218
+
219
+ return Qnil;
220
+ }
221
+
222
+ VALUE quat2_add(VALUE self, VALUE other) {
223
+ Quat2Data *a = quat2_get(self);
224
+ Quat2Data *b = quat2_get(other);
225
+ double values[8];
226
+ for (int i = 0; i < 8; i++) {
227
+ values[i] = a->data[i] + b->data[i];
228
+ }
229
+ return quat2_build(rb_obj_class(self), values);
230
+ }
231
+
232
+ VALUE quat2_sub(VALUE self, VALUE other) {
233
+ Quat2Data *a = quat2_get(self);
234
+ Quat2Data *b = quat2_get(other);
235
+ double values[8];
236
+ for (int i = 0; i < 8; i++) {
237
+ values[i] = a->data[i] - b->data[i];
238
+ }
239
+ return quat2_build(rb_obj_class(self), values);
240
+ }
241
+
242
+ VALUE quat2_dot(VALUE self, VALUE other) {
243
+ Quat2Data *a = quat2_get(self);
244
+ Quat2Data *b = quat2_get(other);
245
+ return DBL2NUM(a->data[0] * b->data[0] + a->data[1] * b->data[1] +
246
+ a->data[2] * b->data[2] + a->data[3] * b->data[3]);
247
+ }
248
+
249
+ VALUE quat2_length_squared(VALUE self) {
250
+ Quat2Data *a = quat2_get(self);
251
+ double sum = a->data[0] * a->data[0] + a->data[1] * a->data[1] +
252
+ a->data[2] * a->data[2] + a->data[3] * a->data[3];
253
+ return DBL2NUM(sum);
254
+ }
255
+
256
+ VALUE quat2_length(VALUE self) {
257
+ double len_sq = NUM2DBL(quat2_length_squared(self));
258
+ return DBL2NUM(sqrt(len_sq));
259
+ }
260
+
261
+ VALUE quat2_normalize(VALUE self) {
262
+ Quat2Data *a = quat2_get(self);
263
+ double len = sqrt(a->data[0] * a->data[0] + a->data[1] * a->data[1] +
264
+ a->data[2] * a->data[2] + a->data[3] * a->data[3]);
265
+ if (len < 1e-10) {
266
+ double values[8];
267
+ for (int i = 0; i < 8; i++) {
268
+ values[i] = a->data[i];
269
+ }
270
+ return quat2_build(rb_obj_class(self), values);
271
+ }
272
+ double inv_len = 1.0 / len;
273
+ double values[8];
274
+ for (int i = 0; i < 8; i++) {
275
+ values[i] = a->data[i] * inv_len;
276
+ }
277
+ return quat2_build(rb_obj_class(self), values);
278
+ }
279
+
280
+ VALUE quat2_normalize_bang(VALUE self) {
281
+ Quat2Data *a = quat2_get(self);
282
+ double len = sqrt(a->data[0] * a->data[0] + a->data[1] * a->data[1] +
283
+ a->data[2] * a->data[2] + a->data[3] * a->data[3]);
284
+ if (len < 1e-10) {
285
+ return self;
286
+ }
287
+ double inv_len = 1.0 / len;
288
+ for (int i = 0; i < 8; i++) {
289
+ a->data[i] *= inv_len;
290
+ }
291
+ return self;
292
+ }
293
+
294
+ VALUE quat2_conjugate(VALUE self) {
295
+ Quat2Data *a = quat2_get(self);
296
+ return quat2_build8(rb_obj_class(self), -a->data[0], -a->data[1],
297
+ -a->data[2], a->data[3], -a->data[4], -a->data[5],
298
+ -a->data[6], a->data[7]);
299
+ }
300
+
301
+ VALUE quat2_inverse(VALUE self) {
302
+ Quat2Data *a = quat2_get(self);
303
+ double len_sq = a->data[0] * a->data[0] + a->data[1] * a->data[1] +
304
+ a->data[2] * a->data[2] + a->data[3] * a->data[3];
305
+ if (len_sq < 1e-10) {
306
+ return quat2_conjugate(self);
307
+ }
308
+ VALUE conj = quat2_conjugate(self);
309
+ Quat2Data *c = quat2_get(conj);
310
+ double inv_len = 1.0 / len_sq;
311
+ double values[8];
312
+ for (int i = 0; i < 8; i++) {
313
+ values[i] = c->data[i] * inv_len;
314
+ }
315
+ return quat2_build(rb_obj_class(self), values);
316
+ }
317
+
318
+ VALUE quat2_translation(VALUE self) {
319
+ Quat2Data *a = quat2_get(self);
320
+ double ax = a->data[0];
321
+ double ay = a->data[1];
322
+ double az = a->data[2];
323
+ double aw = a->data[3];
324
+ double bx = a->data[4];
325
+ double by = a->data[5];
326
+ double bz = a->data[6];
327
+ double bw = a->data[7];
328
+
329
+ double tx = 2.0 * (-bw * ax + bx * aw - by * az + bz * ay);
330
+ double ty = 2.0 * (-bw * ay + by * aw - bz * ax + bx * az);
331
+ double tz = 2.0 * (-bw * az + bz * aw - bx * ay + by * ax);
332
+
333
+ return rb_funcall(cVec3, rb_intern("new"), 3, DBL2NUM(tx), DBL2NUM(ty),
334
+ DBL2NUM(tz));
335
+ }
336
+
337
+ VALUE quat2_rotation(VALUE self) {
338
+ VALUE real = quat2_real(self);
339
+ return rb_funcall(real, rb_intern("normalize"), 0);
340
+ }
341
+
342
+ VALUE quat2_transform_point(VALUE self, VALUE point) {
343
+ VALUE rot = quat2_rotation(self);
344
+ VALUE rotated = rb_funcall(rot, rb_intern("*"), 1, point);
345
+ VALUE trans = quat2_translation(self);
346
+ return rb_funcall(rotated, rb_intern("+"), 1, trans);
347
+ }
348
+
349
+ VALUE quat2_lerp(VALUE self, VALUE other, VALUE t) {
350
+ Quat2Data *a = quat2_get(self);
351
+ Quat2Data *b = quat2_get(other);
352
+ double s = value_to_double(t);
353
+ double values[8];
354
+ for (int i = 0; i < 8; i++) {
355
+ values[i] = a->data[i] + (b->data[i] - a->data[i]) * s;
356
+ }
357
+ VALUE out = quat2_build(rb_obj_class(self), values);
358
+ return quat2_normalize(out);
359
+ }
360
+
361
+ VALUE quat2_to_mat4(VALUE self) {
362
+ VALUE rot = quat2_rotation(self);
363
+ VALUE trans = quat2_translation(self);
364
+ VALUE rot_m = rb_funcall(cMat4, rb_intern("from_quaternion"), 1, rot);
365
+ VALUE trans_m =
366
+ rb_funcall(cMat4, rb_intern("translation"), 3,
367
+ rb_funcall(trans, rb_intern("x"), 0),
368
+ rb_funcall(trans, rb_intern("y"), 0),
369
+ rb_funcall(trans, rb_intern("z"), 0));
370
+ return rb_funcall(rot_m, rb_intern("*"), 1, trans_m);
371
+ }
372
+
373
+ VALUE quat2_to_a(VALUE self) {
374
+ Quat2Data *a = quat2_get(self);
375
+ VALUE ary = rb_ary_new_capa(8);
376
+ for (int i = 0; i < 8; i++) {
377
+ rb_ary_push(ary, DBL2NUM(a->data[i]));
378
+ }
379
+ return ary;
380
+ }
381
+
382
+ VALUE quat2_data(VALUE self) {
383
+ return quat2_to_a(self);
384
+ }
385
+
386
+ VALUE quat2_equal(VALUE self, VALUE other) {
387
+ if (!rb_obj_is_kind_of(other, cQuat2)) {
388
+ return Qfalse;
389
+ }
390
+ Quat2Data *a = quat2_get(self);
391
+ Quat2Data *b = quat2_get(other);
392
+ for (int i = 0; i < 8; i++) {
393
+ if (a->data[i] != b->data[i]) {
394
+ return Qfalse;
395
+ }
396
+ }
397
+ return Qtrue;
398
+ }
399
+
400
+ VALUE quat2_near(int argc, VALUE *argv, VALUE self) {
401
+ VALUE other = Qnil;
402
+ VALUE epsilon = Qnil;
403
+
404
+ rb_scan_args(argc, argv, "11", &other, &epsilon);
405
+ Quat2Data *a = quat2_get(self);
406
+ Quat2Data *b = quat2_get(other);
407
+ double eps = NIL_P(epsilon) ? 1e-6 : value_to_double(epsilon);
408
+
409
+ for (int i = 0; i < 8; i++) {
410
+ if (fabs(a->data[i] - b->data[i]) >= eps) {
411
+ return Qfalse;
412
+ }
413
+ }
414
+ return Qtrue;
415
+ }
416
+
417
+ VALUE quat2_inspect(VALUE self) {
418
+ VALUE real = quat2_real(self);
419
+ VALUE dual = quat2_dual(self);
420
+ VALUE real_str = rb_funcall(real, rb_intern("inspect"), 0);
421
+ VALUE dual_str = rb_funcall(dual, rb_intern("inspect"), 0);
422
+ VALUE str = rb_str_new_cstr("Quat2[real: ");
423
+ rb_str_concat(str, real_str);
424
+ rb_str_cat_cstr(str, ", dual: ");
425
+ rb_str_concat(str, dual_str);
426
+ rb_str_cat_cstr(str, "]");
427
+ return str;
428
+ }
429
+
430
+ void Init_quat2(VALUE module) {
431
+ cQuat2 = rb_define_class_under(module, "Quat2", rb_cObject);
432
+ cQuat = rb_const_get(mLarb, rb_intern("Quat"));
433
+ cVec3 = rb_const_get(mLarb, rb_intern("Vec3"));
434
+ cMat4 = rb_const_get(mLarb, rb_intern("Mat4"));
435
+
436
+ rb_define_alloc_func(cQuat2, quat2_alloc);
437
+ rb_define_method(cQuat2, "initialize", quat2_initialize, -1);
438
+
439
+ rb_define_singleton_method(cQuat2, "identity", quat2_class_identity, 0);
440
+ rb_define_singleton_method(cQuat2, "from_rotation_translation",
441
+ quat2_class_from_rotation_translation, 2);
442
+ rb_define_singleton_method(cQuat2, "from_translation",
443
+ quat2_class_from_translation, 1);
444
+ rb_define_singleton_method(cQuat2, "from_rotation",
445
+ quat2_class_from_rotation, 1);
446
+ rb_define_singleton_method(cQuat2, "from_mat4", quat2_class_from_mat4, 1);
447
+
448
+ rb_define_method(cQuat2, "data", quat2_data, 0);
449
+ rb_define_method(cQuat2, "real", quat2_real, 0);
450
+ rb_define_method(cQuat2, "dual", quat2_dual, 0);
451
+ rb_define_method(cQuat2, "[]", quat2_aref, 1);
452
+ rb_define_method(cQuat2, "[]=", quat2_aset, 2);
453
+ rb_define_method(cQuat2, "*", quat2_mul, 1);
454
+ rb_define_method(cQuat2, "+", quat2_add, 1);
455
+ rb_define_method(cQuat2, "-", quat2_sub, 1);
456
+ rb_define_method(cQuat2, "dot", quat2_dot, 1);
457
+ rb_define_method(cQuat2, "length", quat2_length, 0);
458
+ rb_define_method(cQuat2, "length_squared", quat2_length_squared, 0);
459
+ rb_define_method(cQuat2, "normalize", quat2_normalize, 0);
460
+ rb_define_method(cQuat2, "normalize!", quat2_normalize_bang, 0);
461
+ rb_define_method(cQuat2, "conjugate", quat2_conjugate, 0);
462
+ rb_define_method(cQuat2, "inverse", quat2_inverse, 0);
463
+ rb_define_method(cQuat2, "translation", quat2_translation, 0);
464
+ rb_define_method(cQuat2, "rotation", quat2_rotation, 0);
465
+ rb_define_method(cQuat2, "transform_point", quat2_transform_point, 1);
466
+ rb_define_method(cQuat2, "lerp", quat2_lerp, 2);
467
+ rb_define_method(cQuat2, "to_mat4", quat2_to_mat4, 0);
468
+ rb_define_method(cQuat2, "to_a", quat2_to_a, 0);
469
+ rb_define_method(cQuat2, "==", quat2_equal, 1);
470
+ rb_define_method(cQuat2, "near?", quat2_near, -1);
471
+ rb_define_method(cQuat2, "inspect", quat2_inspect, 0);
472
+ rb_define_alias(cQuat2, "to_s", "inspect");
473
+ }
data/ext/larb/quat2.h ADDED
@@ -0,0 +1,39 @@
1
+ #ifndef QUAT2_H
2
+ #define QUAT2_H
3
+
4
+ #include "larb.h"
5
+
6
+ typedef struct {
7
+ double data[8];
8
+ } Quat2Data;
9
+
10
+ void Init_quat2(VALUE module);
11
+ VALUE quat2_alloc(VALUE klass);
12
+ VALUE quat2_initialize(int argc, VALUE *argv, VALUE self);
13
+
14
+ VALUE quat2_real(VALUE self);
15
+ VALUE quat2_dual(VALUE self);
16
+ VALUE quat2_aref(VALUE self, VALUE index);
17
+ VALUE quat2_aset(VALUE self, VALUE index, VALUE value);
18
+ VALUE quat2_mul(VALUE self, VALUE other);
19
+ VALUE quat2_add(VALUE self, VALUE other);
20
+ VALUE quat2_sub(VALUE self, VALUE other);
21
+ VALUE quat2_dot(VALUE self, VALUE other);
22
+ VALUE quat2_length(VALUE self);
23
+ VALUE quat2_length_squared(VALUE self);
24
+ VALUE quat2_normalize(VALUE self);
25
+ VALUE quat2_normalize_bang(VALUE self);
26
+ VALUE quat2_conjugate(VALUE self);
27
+ VALUE quat2_inverse(VALUE self);
28
+ VALUE quat2_translation(VALUE self);
29
+ VALUE quat2_rotation(VALUE self);
30
+ VALUE quat2_transform_point(VALUE self, VALUE point);
31
+ VALUE quat2_lerp(VALUE self, VALUE other, VALUE t);
32
+ VALUE quat2_to_mat4(VALUE self);
33
+ VALUE quat2_to_a(VALUE self);
34
+ VALUE quat2_equal(VALUE self, VALUE other);
35
+ VALUE quat2_near(int argc, VALUE *argv, VALUE self);
36
+ VALUE quat2_inspect(VALUE self);
37
+ VALUE quat2_data(VALUE self);
38
+
39
+ #endif