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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +14 -1
- data/ext/larb/color.c +446 -0
- data/ext/larb/color.h +35 -0
- data/ext/larb/extconf.rb +11 -0
- data/ext/larb/larb.c +27 -0
- data/ext/larb/larb.h +8 -0
- data/ext/larb/mat2.c +300 -0
- data/ext/larb/mat2.h +30 -0
- data/ext/larb/mat2d.c +380 -0
- data/ext/larb/mat2d.h +35 -0
- data/ext/larb/mat3.c +469 -0
- data/ext/larb/mat3.h +33 -0
- data/ext/larb/mat4.c +671 -0
- data/ext/larb/mat4.h +31 -0
- data/ext/larb/quat.c +523 -0
- data/ext/larb/quat.h +39 -0
- data/ext/larb/quat2.c +473 -0
- data/ext/larb/quat2.h +39 -0
- data/ext/larb/vec2.c +342 -0
- data/ext/larb/vec2.h +43 -0
- data/ext/larb/vec3.c +503 -0
- data/ext/larb/vec3.h +52 -0
- data/ext/larb/vec4.c +340 -0
- data/ext/larb/vec4.h +38 -0
- data/lib/larb/version.rb +5 -0
- data/lib/larb.rb +2 -14
- data/test/larb/color_test.rb +278 -0
- data/test/larb/mat2_test.rb +144 -0
- data/test/larb/mat2d_test.rb +172 -0
- data/test/larb/mat3_test.rb +147 -0
- data/test/larb/mat4_test.rb +270 -0
- data/test/larb/quat2_test.rb +161 -0
- data/test/larb/quat_test.rb +224 -0
- data/test/larb/vec2_test.rb +251 -0
- data/test/larb/vec3_test.rb +310 -0
- data/test/larb/vec4_test.rb +189 -0
- data/test/test_helper.rb +4 -0
- metadata +53 -14
- data/Rakefile +0 -11
- data/lib/larb/color.rb +0 -148
- data/lib/larb/mat2.rb +0 -119
- data/lib/larb/mat2d.rb +0 -180
- data/lib/larb/mat3.rb +0 -238
- data/lib/larb/mat4.rb +0 -329
- data/lib/larb/quat.rb +0 -238
- data/lib/larb/quat2.rb +0 -193
- data/lib/larb/vec2.rb +0 -150
- data/lib/larb/vec3.rb +0 -218
- data/lib/larb/vec4.rb +0 -125
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2b1d77ff0ad9a72005f26e788711b7a6de60fecf47f9e7232009bc2f27c797ec
|
|
4
|
+
data.tar.gz: 409a982d4e663ea572852deead61d9bd94f87aead91276322c03bbfb3d79b906
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ce1d13c4eff9c79b54d49619182e61f56a7a00cd7e1b37119e168d3491e114e3ecbd76c26428d9e57a39acc4c7ed8e21472d302d46da01fe34dce8e8a5b1689
|
|
7
|
+
data.tar.gz: 82ca7ec6c30c6ac3080ed5ef7070afefddcbdc2455a1bc36045673d1492d4c9b34f3a1fc94310edca0cbf6f4bee544c65d22ae8b6bf23b9b1f142ae9a6d80950
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Larb
|
|
1
|
+
# Larb [](https://badge.fury.io/rb/larb) [](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
|
data/ext/larb/extconf.rb
ADDED
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
|
+
}
|