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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ca6912c8989e8917738c9965540ee392fce8e3c5bcfb95960b1e36d39a84b56
4
- data.tar.gz: c38e9ab279c3e9ede439d90ff7e9153a523e189e7f5bf18867811c0356b21866
3
+ metadata.gz: 2b1d77ff0ad9a72005f26e788711b7a6de60fecf47f9e7232009bc2f27c797ec
4
+ data.tar.gz: 409a982d4e663ea572852deead61d9bd94f87aead91276322c03bbfb3d79b906
5
5
  SHA512:
6
- metadata.gz: f3499157dd5c279ba8afac41e9d245742cfd7d6a31bdf83e683ee42d9c448e6b67666b1c28b15becf18640393486658e2825e44b10ded335a37a5eb37858c722
7
- data.tar.gz: 381dce0add3519b5b0c2661a443d34aa2cc14dfcbb1225c5b507c744b2fa9cd31d89e7fdfac5a776abf6b924e28aeb08afa66ade9e87b19d7268f0946988b7a9
6
+ metadata.gz: 4ce1d13c4eff9c79b54d49619182e61f56a7a00cd7e1b37119e168d3491e114e3ecbd76c26428d9e57a39acc4c7ed8e21472d302d46da01fe34dce8e8a5b1689
7
+ data.tar.gz: 82ca7ec6c30c6ac3080ed5ef7070afefddcbdc2455a1bc36045673d1492d4c9b34f3a1fc94310edca0cbf6f4bee544c65d22ae8b6bf23b9b1f142ae9a6d80950
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 1.0.0 - 2026-01-10
6
+
7
+ - Reimplemented in C for better performance.
8
+
5
9
  ## 0.1.0 - 2026-01-02
6
10
 
7
11
  - Initial release.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Larb
1
+ # Larb [![Gem Version](https://badge.fury.io/rb/larb.svg)](https://badge.fury.io/rb/larb) [![CI](https://github.com/ydah/larb/actions/workflows/ci.yml/badge.svg)](https://github.com/ydah/larb/actions/workflows/ci.yml)
2
2
 
3
3
  Linear algebra library for 2D/3D graphics in Ruby.
4
4
 
@@ -58,6 +58,19 @@ custom = Larb::Color.new(0.5, 0.3, 0.8, 1.0)
58
58
  hex_color = Larb::Color.from_hex("#ff8800")
59
59
  ```
60
60
 
61
+ ## Development
62
+
63
+ ```bash
64
+ # Install dependencies
65
+ bundle install
66
+
67
+ # Compile native extension
68
+ bundle exec rake compile
69
+
70
+ # Run tests
71
+ bundle exec rake test
72
+ ```
73
+
61
74
  ## License
62
75
 
63
76
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/ext/larb/color.c ADDED
@@ -0,0 +1,446 @@
1
+ #include "color.h"
2
+
3
+ #include <math.h>
4
+
5
+ static void color_free(void *ptr) {
6
+ xfree(ptr);
7
+ }
8
+
9
+ static size_t color_memsize(const void *ptr) {
10
+ return sizeof(ColorData);
11
+ }
12
+
13
+ static const rb_data_type_t color_type = {
14
+ "Color",
15
+ {0, color_free, color_memsize},
16
+ 0,
17
+ 0,
18
+ RUBY_TYPED_FREE_IMMEDIATELY,
19
+ };
20
+
21
+ static VALUE cColor = Qnil;
22
+ static VALUE cVec3 = Qnil;
23
+ static VALUE cVec4 = Qnil;
24
+
25
+ static double value_to_double(VALUE value) {
26
+ VALUE coerced = rb_funcall(value, rb_intern("to_f"), 0);
27
+ return NUM2DBL(coerced);
28
+ }
29
+
30
+ static ColorData *color_get(VALUE obj) {
31
+ ColorData *data = NULL;
32
+ TypedData_Get_Struct(obj, ColorData, &color_type, data);
33
+ return data;
34
+ }
35
+
36
+ static VALUE color_build(VALUE klass, double r, double g, double b, double a) {
37
+ VALUE obj = color_alloc(klass);
38
+ ColorData *data = color_get(obj);
39
+ data->r = r;
40
+ data->g = g;
41
+ data->b = b;
42
+ data->a = a;
43
+ return obj;
44
+ }
45
+
46
+ static double clamp_double(double value, double min, double max) {
47
+ if (value < min) {
48
+ return min;
49
+ }
50
+ if (value > max) {
51
+ return max;
52
+ }
53
+ return value;
54
+ }
55
+
56
+ static int clamp_int(int value, int min, int max) {
57
+ if (value < min) {
58
+ return min;
59
+ }
60
+ if (value > max) {
61
+ return max;
62
+ }
63
+ return value;
64
+ }
65
+
66
+ static VALUE color_get_r(VALUE self) {
67
+ ColorData *data = color_get(self);
68
+ return DBL2NUM(data->r);
69
+ }
70
+
71
+ static VALUE color_set_r(VALUE self, VALUE value) {
72
+ ColorData *data = color_get(self);
73
+ data->r = value_to_double(value);
74
+ return value;
75
+ }
76
+
77
+ static VALUE color_get_g(VALUE self) {
78
+ ColorData *data = color_get(self);
79
+ return DBL2NUM(data->g);
80
+ }
81
+
82
+ static VALUE color_set_g(VALUE self, VALUE value) {
83
+ ColorData *data = color_get(self);
84
+ data->g = value_to_double(value);
85
+ return value;
86
+ }
87
+
88
+ static VALUE color_get_b(VALUE self) {
89
+ ColorData *data = color_get(self);
90
+ return DBL2NUM(data->b);
91
+ }
92
+
93
+ static VALUE color_set_b(VALUE self, VALUE value) {
94
+ ColorData *data = color_get(self);
95
+ data->b = value_to_double(value);
96
+ return value;
97
+ }
98
+
99
+ static VALUE color_get_a(VALUE self) {
100
+ ColorData *data = color_get(self);
101
+ return DBL2NUM(data->a);
102
+ }
103
+
104
+ static VALUE color_set_a(VALUE self, VALUE value) {
105
+ ColorData *data = color_get(self);
106
+ data->a = value_to_double(value);
107
+ return value;
108
+ }
109
+
110
+ VALUE color_alloc(VALUE klass) {
111
+ ColorData *data = ALLOC(ColorData);
112
+ data->r = 0.0;
113
+ data->g = 0.0;
114
+ data->b = 0.0;
115
+ data->a = 1.0;
116
+ return TypedData_Wrap_Struct(klass, &color_type, data);
117
+ }
118
+
119
+ VALUE color_initialize(int argc, VALUE *argv, VALUE self) {
120
+ VALUE vr = Qnil;
121
+ VALUE vg = Qnil;
122
+ VALUE vb = Qnil;
123
+ VALUE va = Qnil;
124
+ ColorData *data = color_get(self);
125
+
126
+ rb_scan_args(argc, argv, "04", &vr, &vg, &vb, &va);
127
+ data->r = NIL_P(vr) ? 0.0 : value_to_double(vr);
128
+ data->g = NIL_P(vg) ? 0.0 : value_to_double(vg);
129
+ data->b = NIL_P(vb) ? 0.0 : value_to_double(vb);
130
+ data->a = NIL_P(va) ? 1.0 : value_to_double(va);
131
+
132
+ return self;
133
+ }
134
+
135
+ static VALUE color_class_bracket(int argc, VALUE *argv, VALUE klass) {
136
+ VALUE vr = Qnil;
137
+ VALUE vg = Qnil;
138
+ VALUE vb = Qnil;
139
+ VALUE va = Qnil;
140
+
141
+ rb_scan_args(argc, argv, "31", &vr, &vg, &vb, &va);
142
+ return color_build(klass, value_to_double(vr), value_to_double(vg),
143
+ value_to_double(vb), NIL_P(va) ? 1.0 : value_to_double(va));
144
+ }
145
+
146
+ static VALUE color_class_rgb(VALUE klass, VALUE r, VALUE g, VALUE b) {
147
+ return color_build(klass, value_to_double(r), value_to_double(g),
148
+ value_to_double(b), 1.0);
149
+ }
150
+
151
+ static VALUE color_class_rgba(VALUE klass, VALUE r, VALUE g, VALUE b, VALUE a) {
152
+ return color_build(klass, value_to_double(r), value_to_double(g),
153
+ value_to_double(b), value_to_double(a));
154
+ }
155
+
156
+ static VALUE color_class_from_bytes(int argc, VALUE *argv, VALUE klass) {
157
+ VALUE vr = Qnil;
158
+ VALUE vg = Qnil;
159
+ VALUE vb = Qnil;
160
+ VALUE va = Qnil;
161
+
162
+ rb_scan_args(argc, argv, "31", &vr, &vg, &vb, &va);
163
+ double r = value_to_double(vr) / 255.0;
164
+ double g = value_to_double(vg) / 255.0;
165
+ double b = value_to_double(vb) / 255.0;
166
+ double a = NIL_P(va) ? 1.0 : value_to_double(va) / 255.0;
167
+ return color_build(klass, r, g, b, a);
168
+ }
169
+
170
+ static VALUE color_class_from_hex(VALUE klass, VALUE hex_value) {
171
+ VALUE hex = rb_funcall(hex_value, rb_intern("to_s"), 0);
172
+ VALUE cleaned = rb_funcall(hex, rb_intern("delete"), 1, rb_str_new_cstr("#"));
173
+ VALUE len_val = rb_funcall(cleaned, rb_intern("length"), 0);
174
+ long len = NUM2LONG(len_val);
175
+
176
+ VALUE r_str = rb_funcall(cleaned, rb_intern("[]"), 2, INT2NUM(0), INT2NUM(2));
177
+ VALUE g_str = rb_funcall(cleaned, rb_intern("[]"), 2, INT2NUM(2), INT2NUM(2));
178
+ VALUE b_str = rb_funcall(cleaned, rb_intern("[]"), 2, INT2NUM(4), INT2NUM(2));
179
+ double r = value_to_double(rb_funcall(r_str, rb_intern("to_i"), 1,
180
+ INT2NUM(16))) /
181
+ 255.0;
182
+ double g = value_to_double(rb_funcall(g_str, rb_intern("to_i"), 1,
183
+ INT2NUM(16))) /
184
+ 255.0;
185
+ double b = value_to_double(rb_funcall(b_str, rb_intern("to_i"), 1,
186
+ INT2NUM(16))) /
187
+ 255.0;
188
+ double a = 1.0;
189
+ if (len > 6) {
190
+ VALUE a_str =
191
+ rb_funcall(cleaned, rb_intern("[]"), 2, INT2NUM(6), INT2NUM(2));
192
+ a = value_to_double(
193
+ rb_funcall(a_str, rb_intern("to_i"), 1, INT2NUM(16))) /
194
+ 255.0;
195
+ }
196
+
197
+ return color_build(klass, r, g, b, a);
198
+ }
199
+
200
+ static VALUE color_class_black(VALUE klass) {
201
+ return color_build(klass, 0.0, 0.0, 0.0, 1.0);
202
+ }
203
+
204
+ static VALUE color_class_white(VALUE klass) {
205
+ return color_build(klass, 1.0, 1.0, 1.0, 1.0);
206
+ }
207
+
208
+ static VALUE color_class_red(VALUE klass) {
209
+ return color_build(klass, 1.0, 0.0, 0.0, 1.0);
210
+ }
211
+
212
+ static VALUE color_class_green(VALUE klass) {
213
+ return color_build(klass, 0.0, 1.0, 0.0, 1.0);
214
+ }
215
+
216
+ static VALUE color_class_blue(VALUE klass) {
217
+ return color_build(klass, 0.0, 0.0, 1.0, 1.0);
218
+ }
219
+
220
+ static VALUE color_class_yellow(VALUE klass) {
221
+ return color_build(klass, 1.0, 1.0, 0.0, 1.0);
222
+ }
223
+
224
+ static VALUE color_class_cyan(VALUE klass) {
225
+ return color_build(klass, 0.0, 1.0, 1.0, 1.0);
226
+ }
227
+
228
+ static VALUE color_class_magenta(VALUE klass) {
229
+ return color_build(klass, 1.0, 0.0, 1.0, 1.0);
230
+ }
231
+
232
+ static VALUE color_class_transparent(VALUE klass) {
233
+ return color_build(klass, 0.0, 0.0, 0.0, 0.0);
234
+ }
235
+
236
+ VALUE color_class_from_vec4(VALUE klass, VALUE vec4) {
237
+ double r = value_to_double(rb_funcall(vec4, rb_intern("x"), 0));
238
+ double g = value_to_double(rb_funcall(vec4, rb_intern("y"), 0));
239
+ double b = value_to_double(rb_funcall(vec4, rb_intern("z"), 0));
240
+ double a = value_to_double(rb_funcall(vec4, rb_intern("w"), 0));
241
+ return color_build(klass, r, g, b, a);
242
+ }
243
+
244
+ VALUE color_class_from_vec3(int argc, VALUE *argv, VALUE klass) {
245
+ VALUE vec3 = Qnil;
246
+ VALUE alpha = Qnil;
247
+ rb_scan_args(argc, argv, "11", &vec3, &alpha);
248
+ double r = value_to_double(rb_funcall(vec3, rb_intern("x"), 0));
249
+ double g = value_to_double(rb_funcall(vec3, rb_intern("y"), 0));
250
+ double b = value_to_double(rb_funcall(vec3, rb_intern("z"), 0));
251
+ double a = NIL_P(alpha) ? 1.0 : value_to_double(alpha);
252
+ return color_build(klass, r, g, b, a);
253
+ }
254
+
255
+ VALUE color_add(VALUE self, VALUE other) {
256
+ ColorData *a = color_get(self);
257
+ ColorData *b = color_get(other);
258
+ return color_build(rb_obj_class(self), a->r + b->r, a->g + b->g, a->b + b->b,
259
+ a->a + b->a);
260
+ }
261
+
262
+ VALUE color_sub(VALUE self, VALUE other) {
263
+ ColorData *a = color_get(self);
264
+ ColorData *b = color_get(other);
265
+ return color_build(rb_obj_class(self), a->r - b->r, a->g - b->g, a->b - b->b,
266
+ a->a - b->a);
267
+ }
268
+
269
+ VALUE color_mul(VALUE self, VALUE scalar) {
270
+ ColorData *a = color_get(self);
271
+ if (rb_obj_is_kind_of(scalar, cColor)) {
272
+ ColorData *b = color_get(scalar);
273
+ return color_build(rb_obj_class(self), a->r * b->r, a->g * b->g,
274
+ a->b * b->b, a->a * b->a);
275
+ }
276
+ if (rb_obj_is_kind_of(scalar, rb_cNumeric)) {
277
+ double s = value_to_double(scalar);
278
+ return color_build(rb_obj_class(self), a->r * s, a->g * s, a->b * s,
279
+ a->a * s);
280
+ }
281
+ return Qnil;
282
+ }
283
+
284
+ VALUE color_lerp(VALUE self, VALUE other, VALUE t) {
285
+ ColorData *a = color_get(self);
286
+ ColorData *b = color_get(other);
287
+ double s = value_to_double(t);
288
+ return color_build(rb_obj_class(self), a->r + (b->r - a->r) * s,
289
+ a->g + (b->g - a->g) * s, a->b + (b->b - a->b) * s,
290
+ a->a + (b->a - a->a) * s);
291
+ }
292
+
293
+ VALUE color_clamp(VALUE self) {
294
+ ColorData *a = color_get(self);
295
+ return color_build(rb_obj_class(self), clamp_double(a->r, 0.0, 1.0),
296
+ clamp_double(a->g, 0.0, 1.0),
297
+ clamp_double(a->b, 0.0, 1.0),
298
+ clamp_double(a->a, 0.0, 1.0));
299
+ }
300
+
301
+ VALUE color_to_bytes(VALUE self) {
302
+ ColorData *a = color_get(self);
303
+ int r = (int)lround(a->r * 255.0);
304
+ int g = (int)lround(a->g * 255.0);
305
+ int b = (int)lround(a->b * 255.0);
306
+ int alpha = (int)lround(a->a * 255.0);
307
+ VALUE ary = rb_ary_new_capa(4);
308
+ rb_ary_push(ary, INT2NUM(clamp_int(r, 0, 255)));
309
+ rb_ary_push(ary, INT2NUM(clamp_int(g, 0, 255)));
310
+ rb_ary_push(ary, INT2NUM(clamp_int(b, 0, 255)));
311
+ rb_ary_push(ary, INT2NUM(clamp_int(alpha, 0, 255)));
312
+ return ary;
313
+ }
314
+
315
+ VALUE color_to_hex(VALUE self) {
316
+ VALUE bytes = color_to_bytes(self);
317
+ VALUE r = rb_ary_entry(bytes, 0);
318
+ VALUE g = rb_ary_entry(bytes, 1);
319
+ VALUE b = rb_ary_entry(bytes, 2);
320
+ VALUE a = rb_ary_entry(bytes, 3);
321
+ return rb_funcall(rb_mKernel, rb_intern("format"), 5,
322
+ rb_str_new_cstr("#%02x%02x%02x%02x"), r, g, b, a);
323
+ }
324
+
325
+ VALUE color_to_vec3(VALUE self) {
326
+ ColorData *a = color_get(self);
327
+ return rb_funcall(cVec3, rb_intern("new"), 3, DBL2NUM(a->r), DBL2NUM(a->g),
328
+ DBL2NUM(a->b));
329
+ }
330
+
331
+ VALUE color_to_vec4(VALUE self) {
332
+ ColorData *a = color_get(self);
333
+ return rb_funcall(cVec4, rb_intern("new"), 4, DBL2NUM(a->r), DBL2NUM(a->g),
334
+ DBL2NUM(a->b), DBL2NUM(a->a));
335
+ }
336
+
337
+ VALUE color_to_a(VALUE self) {
338
+ ColorData *a = color_get(self);
339
+ VALUE ary = rb_ary_new_capa(4);
340
+ rb_ary_push(ary, DBL2NUM(a->r));
341
+ rb_ary_push(ary, DBL2NUM(a->g));
342
+ rb_ary_push(ary, DBL2NUM(a->b));
343
+ rb_ary_push(ary, DBL2NUM(a->a));
344
+ return ary;
345
+ }
346
+
347
+ VALUE color_aref(VALUE self, VALUE index) {
348
+ VALUE ary = color_to_a(self);
349
+ return rb_ary_entry(ary, NUM2LONG(index));
350
+ }
351
+
352
+ VALUE color_equal(VALUE self, VALUE other) {
353
+ if (!rb_obj_is_kind_of(other, cColor)) {
354
+ return Qfalse;
355
+ }
356
+ ColorData *a = color_get(self);
357
+ ColorData *b = color_get(other);
358
+ return (a->r == b->r && a->g == b->g && a->b == b->b && a->a == b->a)
359
+ ? Qtrue
360
+ : Qfalse;
361
+ }
362
+
363
+ VALUE color_near(int argc, VALUE *argv, VALUE self) {
364
+ VALUE other = Qnil;
365
+ VALUE epsilon = Qnil;
366
+
367
+ rb_scan_args(argc, argv, "11", &other, &epsilon);
368
+ ColorData *a = color_get(self);
369
+ ColorData *b = color_get(other);
370
+ double eps = NIL_P(epsilon) ? 1e-6 : value_to_double(epsilon);
371
+
372
+ if (fabs(a->r - b->r) < eps && fabs(a->g - b->g) < eps &&
373
+ fabs(a->b - b->b) < eps && fabs(a->a - b->a) < eps) {
374
+ return Qtrue;
375
+ }
376
+ return Qfalse;
377
+ }
378
+
379
+ VALUE color_inspect(VALUE self) {
380
+ ColorData *a = color_get(self);
381
+ VALUE sr = rb_funcall(DBL2NUM(a->r), rb_intern("to_s"), 0);
382
+ VALUE sg = rb_funcall(DBL2NUM(a->g), rb_intern("to_s"), 0);
383
+ VALUE sb = rb_funcall(DBL2NUM(a->b), rb_intern("to_s"), 0);
384
+ VALUE sa = rb_funcall(DBL2NUM(a->a), rb_intern("to_s"), 0);
385
+ VALUE str = rb_str_new_cstr("Color[");
386
+ rb_str_concat(str, sr);
387
+ rb_str_cat_cstr(str, ", ");
388
+ rb_str_concat(str, sg);
389
+ rb_str_cat_cstr(str, ", ");
390
+ rb_str_concat(str, sb);
391
+ rb_str_cat_cstr(str, ", ");
392
+ rb_str_concat(str, sa);
393
+ rb_str_cat_cstr(str, "]");
394
+ return str;
395
+ }
396
+
397
+ void Init_color(VALUE module) {
398
+ cColor = rb_define_class_under(module, "Color", rb_cObject);
399
+ cVec3 = rb_const_get(mLarb, rb_intern("Vec3"));
400
+ cVec4 = rb_const_get(mLarb, rb_intern("Vec4"));
401
+
402
+ rb_define_alloc_func(cColor, color_alloc);
403
+ rb_define_method(cColor, "initialize", color_initialize, -1);
404
+
405
+ rb_define_singleton_method(cColor, "[]", color_class_bracket, -1);
406
+ rb_define_singleton_method(cColor, "rgb", color_class_rgb, 3);
407
+ rb_define_singleton_method(cColor, "rgba", color_class_rgba, 4);
408
+ rb_define_singleton_method(cColor, "from_bytes", color_class_from_bytes, -1);
409
+ rb_define_singleton_method(cColor, "from_hex", color_class_from_hex, 1);
410
+ rb_define_singleton_method(cColor, "black", color_class_black, 0);
411
+ rb_define_singleton_method(cColor, "white", color_class_white, 0);
412
+ rb_define_singleton_method(cColor, "red", color_class_red, 0);
413
+ rb_define_singleton_method(cColor, "green", color_class_green, 0);
414
+ rb_define_singleton_method(cColor, "blue", color_class_blue, 0);
415
+ rb_define_singleton_method(cColor, "yellow", color_class_yellow, 0);
416
+ rb_define_singleton_method(cColor, "cyan", color_class_cyan, 0);
417
+ rb_define_singleton_method(cColor, "magenta", color_class_magenta, 0);
418
+ rb_define_singleton_method(cColor, "transparent", color_class_transparent, 0);
419
+ rb_define_singleton_method(cColor, "from_vec4", color_class_from_vec4, 1);
420
+ rb_define_singleton_method(cColor, "from_vec3", color_class_from_vec3, -1);
421
+
422
+ rb_define_method(cColor, "r", color_get_r, 0);
423
+ rb_define_method(cColor, "r=", color_set_r, 1);
424
+ rb_define_method(cColor, "g", color_get_g, 0);
425
+ rb_define_method(cColor, "g=", color_set_g, 1);
426
+ rb_define_method(cColor, "b", color_get_b, 0);
427
+ rb_define_method(cColor, "b=", color_set_b, 1);
428
+ rb_define_method(cColor, "a", color_get_a, 0);
429
+ rb_define_method(cColor, "a=", color_set_a, 1);
430
+
431
+ rb_define_method(cColor, "+", color_add, 1);
432
+ rb_define_method(cColor, "-", color_sub, 1);
433
+ rb_define_method(cColor, "*", color_mul, 1);
434
+ rb_define_method(cColor, "lerp", color_lerp, 2);
435
+ rb_define_method(cColor, "clamp", color_clamp, 0);
436
+ rb_define_method(cColor, "to_bytes", color_to_bytes, 0);
437
+ rb_define_method(cColor, "to_hex", color_to_hex, 0);
438
+ rb_define_method(cColor, "to_vec3", color_to_vec3, 0);
439
+ rb_define_method(cColor, "to_vec4", color_to_vec4, 0);
440
+ rb_define_method(cColor, "to_a", color_to_a, 0);
441
+ rb_define_method(cColor, "[]", color_aref, 1);
442
+ rb_define_method(cColor, "==", color_equal, 1);
443
+ rb_define_method(cColor, "near?", color_near, -1);
444
+ rb_define_method(cColor, "inspect", color_inspect, 0);
445
+ rb_define_alias(cColor, "to_s", "inspect");
446
+ }
data/ext/larb/color.h ADDED
@@ -0,0 +1,35 @@
1
+ #ifndef COLOR_H
2
+ #define COLOR_H
3
+
4
+ #include "larb.h"
5
+
6
+ typedef struct {
7
+ double r;
8
+ double g;
9
+ double b;
10
+ double a;
11
+ } ColorData;
12
+
13
+ void Init_color(VALUE module);
14
+ VALUE color_alloc(VALUE klass);
15
+ VALUE color_initialize(int argc, VALUE *argv, VALUE self);
16
+
17
+ VALUE color_class_from_vec4(VALUE klass, VALUE vec4);
18
+ VALUE color_class_from_vec3(int argc, VALUE *argv, VALUE klass);
19
+
20
+ VALUE color_add(VALUE self, VALUE other);
21
+ VALUE color_sub(VALUE self, VALUE other);
22
+ VALUE color_mul(VALUE self, VALUE scalar);
23
+ VALUE color_lerp(VALUE self, VALUE other, VALUE t);
24
+ VALUE color_clamp(VALUE self);
25
+ VALUE color_to_bytes(VALUE self);
26
+ VALUE color_to_hex(VALUE self);
27
+ VALUE color_to_vec3(VALUE self);
28
+ VALUE color_to_vec4(VALUE self);
29
+ VALUE color_to_a(VALUE self);
30
+ VALUE color_aref(VALUE self, VALUE index);
31
+ VALUE color_equal(VALUE self, VALUE other);
32
+ VALUE color_near(int argc, VALUE *argv, VALUE self);
33
+ VALUE color_inspect(VALUE self);
34
+
35
+ #endif
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+
5
+ # mathライブラリの確認
6
+ have_library("m", "sin")
7
+
8
+ # 最適化フラグ
9
+ $CFLAGS << " -O3 -march=native -ffast-math -funroll-loops"
10
+
11
+ create_makefile("larb/larb")
data/ext/larb/larb.c ADDED
@@ -0,0 +1,27 @@
1
+ #include "larb.h"
2
+ #include "vec2.h"
3
+ #include "vec3.h"
4
+ #include "vec4.h"
5
+ #include "mat2.h"
6
+ #include "mat3.h"
7
+ #include "mat4.h"
8
+ #include "quat.h"
9
+ #include "mat2d.h"
10
+ #include "color.h"
11
+ #include "quat2.h"
12
+
13
+ VALUE mLarb = Qnil;
14
+
15
+ void Init_larb(void) {
16
+ mLarb = rb_define_module("Larb");
17
+ Init_vec2(mLarb);
18
+ Init_vec3(mLarb);
19
+ Init_vec4(mLarb);
20
+ Init_mat2(mLarb);
21
+ Init_mat3(mLarb);
22
+ Init_quat(mLarb);
23
+ Init_mat4(mLarb);
24
+ Init_mat2d(mLarb);
25
+ Init_color(mLarb);
26
+ Init_quat2(mLarb);
27
+ }
data/ext/larb/larb.h ADDED
@@ -0,0 +1,8 @@
1
+ #ifndef LARB_H
2
+ #define LARB_H
3
+
4
+ #include <ruby.h>
5
+
6
+ extern VALUE mLarb;
7
+
8
+ #endif