numerix 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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/.yardopts +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +66 -0
- data/Rakefile +18 -0
- data/TODO.txt +25 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/numerix/common.h +107 -0
- data/ext/numerix/extconf.rb +3 -0
- data/ext/numerix/matrix3x2.c +638 -0
- data/ext/numerix/matrix3x2.h +52 -0
- data/ext/numerix/matrix4x4.c +1807 -0
- data/ext/numerix/matrix4x4.h +90 -0
- data/ext/numerix/matrix_base.c +307 -0
- data/ext/numerix/matrix_base.h +70 -0
- data/ext/numerix/numerix.c +33 -0
- data/ext/numerix/numerix.h +19 -0
- data/ext/numerix/plane.c +311 -0
- data/ext/numerix/plane.h +34 -0
- data/ext/numerix/quaternion.c +712 -0
- data/ext/numerix/quaternion.h +53 -0
- data/ext/numerix/structure.c +154 -0
- data/ext/numerix/structure.h +24 -0
- data/ext/numerix/vector.c +326 -0
- data/ext/numerix/vector.h +57 -0
- data/ext/numerix/vector2.c +641 -0
- data/ext/numerix/vector2.h +64 -0
- data/ext/numerix/vector3.c +805 -0
- data/ext/numerix/vector3.h +68 -0
- data/ext/numerix/vector4.c +727 -0
- data/ext/numerix/vector4.h +63 -0
- data/ext/numerix/vector_base.c +94 -0
- data/ext/numerix/vector_base.h +30 -0
- data/extra/numerix128.png +0 -0
- data/extra/numerix24.png +0 -0
- data/extra/numerix32.png +0 -0
- data/extra/numerix320.png +0 -0
- data/extra/numerix48.png +0 -0
- data/extra/numerix96.png +0 -0
- data/lib/numerix/error.rb +36 -0
- data/lib/numerix/matrix3x2.rb +420 -0
- data/lib/numerix/matrix4x4.rb +676 -0
- data/lib/numerix/matrix_base.rb +14 -0
- data/lib/numerix/plane.rb +154 -0
- data/lib/numerix/quaternion.rb +355 -0
- data/lib/numerix/structure.rb +124 -0
- data/lib/numerix/vector.rb +13 -0
- data/lib/numerix/vector2.rb +534 -0
- data/lib/numerix/vector3.rb +572 -0
- data/lib/numerix/vector4.rb +551 -0
- data/lib/numerix/vector_base.rb +14 -0
- data/lib/numerix/version.rb +6 -0
- data/lib/numerix.rb +10 -0
- data/numerix.gemspec +30 -0
- metadata +167 -0
@@ -0,0 +1,727 @@
|
|
1
|
+
|
2
|
+
#include "vector4.h"
|
3
|
+
|
4
|
+
void Init_vector4(VALUE outer) {
|
5
|
+
rb_define_alloc_func(rb_cVector4, rb_vector4_alloc);
|
6
|
+
|
7
|
+
// Instance Methods
|
8
|
+
rb_define_method(rb_cVector4, "initialize", rb_vector4_initialize, -1);
|
9
|
+
rb_define_method(rb_cVector4, "length", rb_vector4_length, 0);
|
10
|
+
rb_define_method(rb_cVector4, "length_squared", rb_vector4_length_squared, 0);
|
11
|
+
rb_define_method(rb_cVector4, "one?", rb_vector4_one_p, 0);
|
12
|
+
rb_define_method(rb_cVector4, "zero?", rb_vector4_zero_p, 0);
|
13
|
+
rb_define_method(rb_cVector4, "min_value", rb_vector4_min_value, 0);
|
14
|
+
rb_define_method(rb_cVector4, "max_value", rb_vector4_max_value, 0);
|
15
|
+
rb_define_method(rb_cVector4, "distance", rb_vector4_distance, 1);
|
16
|
+
rb_define_method(rb_cVector4, "distance_squared", rb_vector4_distance_squared, 1);
|
17
|
+
rb_define_method(rb_cVector4, "normalize", rb_vector4_normalize, 0);
|
18
|
+
rb_define_method(rb_cVector4, "normalize!", rb_vector4_normalize_bang, 0);
|
19
|
+
rb_define_method(rb_cVector4, "lerp", rb_vector4_lerp, 2);
|
20
|
+
rb_define_method(rb_cVector4, "lerp!", rb_vector4_lerp_bang, 2);
|
21
|
+
rb_define_method(rb_cVector4, "transform", rb_vector4_transform, 1);
|
22
|
+
rb_define_method(rb_cVector4, "transform!", rb_vector4_transform_bang, 1);
|
23
|
+
rb_define_method(rb_cVector4, "abs", rb_vector4_abs, 0);
|
24
|
+
rb_define_method(rb_cVector4, "sqrt", rb_vector4_sqrt, 0);
|
25
|
+
rb_define_method(rb_cVector4, "dot", rb_vector4_dot, 1);
|
26
|
+
rb_define_method(rb_cVector4, "clamp", rb_vector4_clamp, 2);
|
27
|
+
rb_define_method(rb_cVector4, "clamp!", rb_vector4_clamp_bang, 2);
|
28
|
+
rb_define_method(rb_cVector4, "map", rb_vector4_map, 0);
|
29
|
+
rb_define_method(rb_cVector4, "map!", rb_vector4_map_bang, 0);
|
30
|
+
|
31
|
+
// Conversion
|
32
|
+
rb_define_method(rb_cVector4, "to_s", rb_vector4_to_s, 0);
|
33
|
+
rb_define_method(rb_cVector4, "to_a", rb_vector4_to_a, 0);
|
34
|
+
rb_define_method(rb_cVector4, "to_h", rb_vector4_to_h, 0);
|
35
|
+
rb_define_method(rb_cVector4, "to_quaternion", rb_vector4_to_quaternion, 0);
|
36
|
+
rb_define_method(rb_cVector4, "to_plane", rb_vector4_to_plane, 0);
|
37
|
+
rb_define_method(rb_cVector4, "to_vec2", rb_vector4_to_vec2, 0);
|
38
|
+
rb_define_method(rb_cVector4, "to_vec3", rb_vector4_to_vec3, 0);
|
39
|
+
|
40
|
+
// Operators
|
41
|
+
rb_define_method(rb_cVector4, "+", rb_vector4_add, 1);
|
42
|
+
rb_define_method(rb_cVector4, "-", rb_vector4_subtract, 1);
|
43
|
+
rb_define_method(rb_cVector4, "*", rb_vector4_multiply, 1);
|
44
|
+
rb_define_method(rb_cVector4, "/", rb_vector4_divide, 1);
|
45
|
+
rb_define_method(rb_cVector4, "==", rb_vector4_equal, 1);
|
46
|
+
rb_define_method(rb_cVector4, "-@", rb_vector4_negate, 0);
|
47
|
+
rb_define_method(rb_cVector4, "**", rb_vector4_pow, 1);
|
48
|
+
|
49
|
+
// Alias
|
50
|
+
rb_define_alias(rb_cVector4, "magnitude", "length");
|
51
|
+
rb_define_alias(rb_cVector4, "elements", "to_a");
|
52
|
+
rb_define_alias(rb_cVector4, "collect", "map");
|
53
|
+
rb_define_alias(rb_cVector4, "collect!", "map!");
|
54
|
+
|
55
|
+
// Singleton Methods
|
56
|
+
rb_define_singleton_method(rb_cVector4, "zero", rb_vector4_alloc, 0);
|
57
|
+
rb_define_singleton_method(rb_cVector4, "one", rb_vector4_one, 0);
|
58
|
+
rb_define_singleton_method(rb_cVector4, "unit_x", rb_vector4_unit_x, 0);
|
59
|
+
rb_define_singleton_method(rb_cVector4, "unit_y", rb_vector4_unit_y, 0);
|
60
|
+
rb_define_singleton_method(rb_cVector4, "unit_z", rb_vector4_unit_z, 0);
|
61
|
+
rb_define_singleton_method(rb_cVector4, "unit_w", rb_vector4_unit_w, 0);
|
62
|
+
rb_define_singleton_method(rb_cVector4, "create_norm", rb_vector4_create_norm, 4);
|
63
|
+
rb_define_singleton_method(rb_cVector4, "clamp", rb_vector4_clamp_s, 3);
|
64
|
+
rb_define_singleton_method(rb_cVector4, "lerp", rb_vector4_lerp_s, 3);
|
65
|
+
rb_define_singleton_method(rb_cVector4, "transform", rb_vector4_transform_s, 2);
|
66
|
+
rb_define_singleton_method(rb_cVector4, "min", rb_vector4_min_s, 2);
|
67
|
+
rb_define_singleton_method(rb_cVector4, "max", rb_vector4_max_s, 2);
|
68
|
+
}
|
69
|
+
|
70
|
+
static VALUE rb_vector4_alloc(VALUE klass) {
|
71
|
+
void *v = ALLOC(Vector4);
|
72
|
+
memset(v, 0, sizeof(Vector4));
|
73
|
+
return NUMERIX_WRAP(klass, v);
|
74
|
+
}
|
75
|
+
|
76
|
+
VALUE rb_vector4_initialize(int argc, VALUE *argv, VALUE self) {
|
77
|
+
VECTOR4();
|
78
|
+
switch (argc) {
|
79
|
+
case 0:
|
80
|
+
break;
|
81
|
+
case 1: {
|
82
|
+
float value = NUM2FLT(argv[0]);
|
83
|
+
v->x = value;
|
84
|
+
v->y = value;
|
85
|
+
v->z = value;
|
86
|
+
v->w = value;
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
case 2: {
|
90
|
+
if (NUMERIX_TYPE_P(argv[0], rb_cVector3)) {
|
91
|
+
Vector3 *vec3;
|
92
|
+
Data_Get_Struct(argv[0], Vector3, vec3);
|
93
|
+
v->x = vec3->x;
|
94
|
+
v->y = vec3->y;
|
95
|
+
v->z = vec3->z;
|
96
|
+
v->w = NUM2FLT(argv[1]);
|
97
|
+
} else {
|
98
|
+
Vector2 *v1, *v2;
|
99
|
+
Data_Get_Struct(argv[0], Vector2, v1);
|
100
|
+
Data_Get_Struct(argv[1], Vector2, v2);
|
101
|
+
v->x = v1->x;
|
102
|
+
v->y = v1->y;
|
103
|
+
v->z = v2->x;
|
104
|
+
v->w = v2->y;
|
105
|
+
}
|
106
|
+
break;
|
107
|
+
}
|
108
|
+
case 3: {
|
109
|
+
Vector2 *vec2;
|
110
|
+
Data_Get_Struct(argv[0], Vector2, vec2);
|
111
|
+
v->x = vec2->x;
|
112
|
+
v->y = vec2->y;
|
113
|
+
v->z = NUM2FLT(argv[1]);
|
114
|
+
v->w = NUM2FLT(argv[2]);
|
115
|
+
break;
|
116
|
+
}
|
117
|
+
case 4: {
|
118
|
+
v->x = NUM2FLT(argv[0]);
|
119
|
+
v->y = NUM2FLT(argv[1]);
|
120
|
+
v->z = NUM2FLT(argv[2]);
|
121
|
+
v->w = NUM2FLT(argv[3]);
|
122
|
+
break;
|
123
|
+
}
|
124
|
+
default:
|
125
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0, 1, 2, 3, 4)", argc);
|
126
|
+
break;
|
127
|
+
}
|
128
|
+
return Qnil;
|
129
|
+
}
|
130
|
+
|
131
|
+
VALUE rb_vector4_one(VALUE klass) {
|
132
|
+
Vector4 *v = ALLOC(Vector4);
|
133
|
+
v->x = 1.0f;
|
134
|
+
v->y = 1.0f;
|
135
|
+
v->z = 1.0f;
|
136
|
+
v->w = 1.0f;
|
137
|
+
return NUMERIX_WRAP(klass, v);
|
138
|
+
}
|
139
|
+
|
140
|
+
VALUE rb_vector4_unit_x(VALUE klass) {
|
141
|
+
Vector4 *v = ALLOC(Vector4);
|
142
|
+
v->x = 1.0f;
|
143
|
+
v->y = 0.0f;
|
144
|
+
v->z = 0.0f;
|
145
|
+
v->w = 0.0f;
|
146
|
+
return NUMERIX_WRAP(klass, v);
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE rb_vector4_unit_y(VALUE klass) {
|
150
|
+
Vector4 *v = ALLOC(Vector4);
|
151
|
+
v->x = 0.0f;
|
152
|
+
v->y = 1.0f;
|
153
|
+
v->z = 0.0f;
|
154
|
+
v->w = 0.0f;
|
155
|
+
return NUMERIX_WRAP(klass, v);
|
156
|
+
}
|
157
|
+
|
158
|
+
VALUE rb_vector4_unit_z(VALUE klass) {
|
159
|
+
Vector4 *v = ALLOC(Vector4);
|
160
|
+
v->x = 0.0f;
|
161
|
+
v->y = 0.0f;
|
162
|
+
v->z = 1.0f;
|
163
|
+
v->w = 0.0f;
|
164
|
+
return NUMERIX_WRAP(klass, v);
|
165
|
+
}
|
166
|
+
|
167
|
+
VALUE rb_vector4_unit_w(VALUE klass) {
|
168
|
+
Vector4 *v = ALLOC(Vector4);
|
169
|
+
v->x = 0.0f;
|
170
|
+
v->y = 0.0f;
|
171
|
+
v->z = 0.0f;
|
172
|
+
v->w = 1.0f;
|
173
|
+
return NUMERIX_WRAP(klass, v);
|
174
|
+
}
|
175
|
+
|
176
|
+
VALUE rb_vector4_length(VALUE self) {
|
177
|
+
VECTOR4();
|
178
|
+
return DBL2NUM(sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w));
|
179
|
+
}
|
180
|
+
|
181
|
+
VALUE rb_vector4_length_squared(VALUE self) {
|
182
|
+
VECTOR4();
|
183
|
+
return DBL2NUM(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
|
184
|
+
}
|
185
|
+
|
186
|
+
VALUE rb_vector4_one_p(VALUE self) {
|
187
|
+
VECTOR4();
|
188
|
+
return v->x == 1.0f && v->y == 1.0f && v->z == 1.0f && v->w == 1.0f ? Qtrue : Qfalse;
|
189
|
+
}
|
190
|
+
|
191
|
+
VALUE rb_vector4_zero_p(VALUE self) {
|
192
|
+
VECTOR4();
|
193
|
+
return v->x == 0.0f && v->y == 0.0f && v->z == 0.0f && v->w == 0.0f ? Qtrue : Qfalse;
|
194
|
+
}
|
195
|
+
|
196
|
+
VALUE rb_vector4_add(VALUE self, VALUE other) {
|
197
|
+
VECTOR4();
|
198
|
+
Vector4 *result = ALLOC(Vector4);
|
199
|
+
Vector4 *v2;
|
200
|
+
Data_Get_Struct(other, Vector4, v2);
|
201
|
+
|
202
|
+
result->x = v->x + v2->x;
|
203
|
+
result->y = v->y + v2->y;
|
204
|
+
result->z = v->z + v2->z;
|
205
|
+
result->w = v->w + v2->w;
|
206
|
+
|
207
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
208
|
+
}
|
209
|
+
|
210
|
+
VALUE rb_vector4_subtract(VALUE self, VALUE other) {
|
211
|
+
VECTOR4();
|
212
|
+
Vector4 *result = ALLOC(Vector4);
|
213
|
+
Vector4 *v2;
|
214
|
+
Data_Get_Struct(other, Vector4, v2);
|
215
|
+
|
216
|
+
result->x = v->x - v2->x;
|
217
|
+
result->y = v->y - v2->y;
|
218
|
+
result->z = v->z - v2->z;
|
219
|
+
result->w = v->w - v2->w;
|
220
|
+
|
221
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
222
|
+
}
|
223
|
+
|
224
|
+
VALUE rb_vector4_multiply(VALUE self, VALUE other) {
|
225
|
+
VECTOR4();
|
226
|
+
Vector4 *result = ALLOC(Vector4);
|
227
|
+
|
228
|
+
if (NUMERIX_TYPE_P(other, rb_cVector4)) {
|
229
|
+
Vector4 *v2;
|
230
|
+
Data_Get_Struct(other, Vector4, v2);
|
231
|
+
result->x = v->x * v2->x;
|
232
|
+
result->y = v->x * v2->y;
|
233
|
+
result->z = v->z * v2->z;
|
234
|
+
result->w = v->w * v2->w;
|
235
|
+
} else {
|
236
|
+
float scalar = NUM2FLT(other);
|
237
|
+
result->x = v->x * scalar;
|
238
|
+
result->y = v->y * scalar;
|
239
|
+
result->z = v->z * scalar;
|
240
|
+
result->w = v->w * scalar;
|
241
|
+
}
|
242
|
+
|
243
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
244
|
+
}
|
245
|
+
|
246
|
+
VALUE rb_vector4_divide(VALUE self, VALUE other) {
|
247
|
+
VECTOR4();
|
248
|
+
Vector4 *result = ALLOC(Vector4);
|
249
|
+
|
250
|
+
if (NUMERIX_TYPE_P(other, rb_cVector4)) {
|
251
|
+
Vector4 *v2;
|
252
|
+
Data_Get_Struct(other, Vector4, v2);
|
253
|
+
result->x = v->x / v2->x;
|
254
|
+
result->y = v->y / v2->y;
|
255
|
+
result->z = v->z / v2->z;
|
256
|
+
result->w = v->w / v2->w;
|
257
|
+
} else {
|
258
|
+
float scalar = 1.0f / NUM2FLT(other);
|
259
|
+
result->x = v->x * scalar;
|
260
|
+
result->y = v->y * scalar;
|
261
|
+
result->z = v->z * scalar;
|
262
|
+
result->w = v->w * scalar;
|
263
|
+
}
|
264
|
+
|
265
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
266
|
+
}
|
267
|
+
|
268
|
+
VALUE rb_vector4_equal(VALUE self, VALUE other) {
|
269
|
+
if (CLASS_OF(other) != CLASS_OF(self))
|
270
|
+
return Qfalse;
|
271
|
+
Vector4 *v1, *v2;
|
272
|
+
Data_Get_Struct(self, Vector4, v1);
|
273
|
+
Data_Get_Struct(other, Vector4, v2);
|
274
|
+
return FLT_EQUAL(v1->x, v2->x) && FLT_EQUAL(v1->y, v2->y) && FLT_EQUAL(v1->z, v2->z) && FLT_EQUAL(v1->w, v2->w) ? Qtrue : Qfalse;
|
275
|
+
}
|
276
|
+
|
277
|
+
VALUE rb_vector4_negate(VALUE self) {
|
278
|
+
VECTOR4();
|
279
|
+
Vector4 *result = ALLOC(Vector4);
|
280
|
+
|
281
|
+
result->x = -v->x;
|
282
|
+
result->y = -v->y;
|
283
|
+
result->z = -v->z;
|
284
|
+
result->w = -v->w;
|
285
|
+
|
286
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
287
|
+
}
|
288
|
+
|
289
|
+
VALUE rb_vector4_map(VALUE self) {
|
290
|
+
VECTOR4();
|
291
|
+
Vector4 *result = ALLOC(Vector4);
|
292
|
+
|
293
|
+
result->x = NUM2FLT(rb_yield(DBL2NUM(v->x)));
|
294
|
+
result->y = NUM2FLT(rb_yield(DBL2NUM(v->y)));
|
295
|
+
result->z = NUM2FLT(rb_yield(DBL2NUM(v->z)));
|
296
|
+
result->w = NUM2FLT(rb_yield(DBL2NUM(v->w)));
|
297
|
+
|
298
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
299
|
+
}
|
300
|
+
|
301
|
+
VALUE rb_vector4_map_bang(VALUE self) {
|
302
|
+
VECTOR4();
|
303
|
+
|
304
|
+
v->x = NUM2FLT(rb_yield(DBL2NUM(v->x)));
|
305
|
+
v->y = NUM2FLT(rb_yield(DBL2NUM(v->y)));
|
306
|
+
v->z = NUM2FLT(rb_yield(DBL2NUM(v->z)));
|
307
|
+
v->w = NUM2FLT(rb_yield(DBL2NUM(v->w)));
|
308
|
+
|
309
|
+
return self;
|
310
|
+
}
|
311
|
+
|
312
|
+
VALUE rb_vector4_to_s(VALUE self) {
|
313
|
+
VECTOR4();
|
314
|
+
return rb_sprintf("<%f, %f, %f, %f>", v->x, v->y, v->z, v->w);
|
315
|
+
}
|
316
|
+
|
317
|
+
VALUE rb_vector4_to_a(VALUE self) {
|
318
|
+
VECTOR4();
|
319
|
+
VALUE ary = rb_ary_new_capa(4);
|
320
|
+
rb_ary_store(ary, 0, DBL2NUM(v->x));
|
321
|
+
rb_ary_store(ary, 1, DBL2NUM(v->y));
|
322
|
+
rb_ary_store(ary, 2, DBL2NUM(v->z));
|
323
|
+
rb_ary_store(ary, 3, DBL2NUM(v->w));
|
324
|
+
return ary;
|
325
|
+
}
|
326
|
+
|
327
|
+
VALUE rb_vector4_to_h(VALUE self) {
|
328
|
+
VECTOR4();
|
329
|
+
VALUE hash = rb_hash_new();
|
330
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("x")), DBL2NUM(v->x));
|
331
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("y")), DBL2NUM(v->y));
|
332
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("z")), DBL2NUM(v->z));
|
333
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("w")), DBL2NUM(v->w));
|
334
|
+
return hash;
|
335
|
+
}
|
336
|
+
|
337
|
+
VALUE rb_vector4_to_vec2(VALUE self) {
|
338
|
+
VECTOR4();
|
339
|
+
Vector2 *vec = ALLOC(Vector2);
|
340
|
+
vec->x = v->x;
|
341
|
+
vec->y = v->y;
|
342
|
+
return NUMERIX_WRAP(rb_cVector2, vec);
|
343
|
+
}
|
344
|
+
|
345
|
+
VALUE rb_vector4_to_vec3(VALUE self) {
|
346
|
+
VECTOR4();
|
347
|
+
Vector3 *vec = ALLOC(Vector3);
|
348
|
+
vec->x = v->x;
|
349
|
+
vec->y = v->y;
|
350
|
+
vec->z = v->z;
|
351
|
+
return NUMERIX_WRAP(rb_cVector3, vec);
|
352
|
+
}
|
353
|
+
|
354
|
+
VALUE rb_vector4_to_quaternion(VALUE self) {
|
355
|
+
VECTOR4();
|
356
|
+
Quaternion *q = ALLOC(Quaternion);
|
357
|
+
memcpy(q, v, sizeof(Vector4));
|
358
|
+
return NUMERIX_WRAP(rb_cQuaternion, q);
|
359
|
+
}
|
360
|
+
|
361
|
+
VALUE rb_vector4_to_plane(VALUE self) {
|
362
|
+
VECTOR4();
|
363
|
+
Plane *p = ALLOC(Plane);
|
364
|
+
memcpy(p, v, sizeof(Vector4));
|
365
|
+
return NUMERIX_WRAP(rb_cPlane, p);
|
366
|
+
}
|
367
|
+
|
368
|
+
VALUE rb_vector4_min_value(VALUE self) {
|
369
|
+
VECTOR4();
|
370
|
+
float m = NUMERIX_MIN(v->x, NUMERIX_MIN(v->y, NUMERIX_MIN(v->z, v->w)));
|
371
|
+
return DBL2NUM(m);
|
372
|
+
}
|
373
|
+
|
374
|
+
VALUE rb_vector4_max_value(VALUE self) {
|
375
|
+
VECTOR4();
|
376
|
+
float m = NUMERIX_MAX(v->x, NUMERIX_MAX(v->y, NUMERIX_MAX(v->z, v->w)));
|
377
|
+
return DBL2NUM(m);
|
378
|
+
}
|
379
|
+
|
380
|
+
VALUE rb_vector4_distance(VALUE self, VALUE other) {
|
381
|
+
Vector4 *v1, *v2;
|
382
|
+
Data_Get_Struct(self, Vector4, v1);
|
383
|
+
Data_Get_Struct(other, Vector4, v2);
|
384
|
+
|
385
|
+
float dx = v1->x - v2->x;
|
386
|
+
float dy = v1->y - v2->y;
|
387
|
+
float dz = v1->z - v2->z;
|
388
|
+
float dw = v1->w - v2->w;
|
389
|
+
|
390
|
+
return DBL2NUM(sqrtf(dx * dx + dy * dy + dz * dz + dw * dw));
|
391
|
+
}
|
392
|
+
|
393
|
+
VALUE rb_vector4_distance_squared(VALUE self, VALUE other) {
|
394
|
+
Vector4 *v1, *v2;
|
395
|
+
Data_Get_Struct(self, Vector4, v1);
|
396
|
+
Data_Get_Struct(other, Vector4, v2);
|
397
|
+
|
398
|
+
float dx = v1->x - v2->x;
|
399
|
+
float dy = v1->y - v2->y;
|
400
|
+
float dz = v1->z - v2->z;
|
401
|
+
float dw = v1->w - v2->w;
|
402
|
+
|
403
|
+
return DBL2NUM(dx * dx + dy * dy + dz * dz + dw * dw);
|
404
|
+
}
|
405
|
+
|
406
|
+
VALUE rb_vector4_normalize(VALUE self) {
|
407
|
+
VECTOR4();
|
408
|
+
Vector4 *result = ALLOC(Vector4);
|
409
|
+
|
410
|
+
float inv = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
|
411
|
+
result->x = v->x * inv;
|
412
|
+
result->y = v->y * inv;
|
413
|
+
result->z = v->z * inv;
|
414
|
+
result->w = v->w * inv;
|
415
|
+
|
416
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
417
|
+
}
|
418
|
+
|
419
|
+
VALUE rb_vector4_lerp(VALUE self, VALUE other, VALUE amount) {
|
420
|
+
return rb_vector4_lerp_s(CLASS_OF(self), self, other, amount);
|
421
|
+
}
|
422
|
+
|
423
|
+
VALUE rb_vector4_transform(VALUE self, VALUE other) {
|
424
|
+
return rb_vector4_transform_s(CLASS_OF(self), self, other);
|
425
|
+
}
|
426
|
+
|
427
|
+
VALUE rb_vector4_abs(VALUE self) {
|
428
|
+
VECTOR4();
|
429
|
+
Vector4 *result = ALLOC(Vector4);
|
430
|
+
|
431
|
+
result->x = fabsf(v->x);
|
432
|
+
result->y = fabsf(v->y);
|
433
|
+
result->z = fabsf(v->z);
|
434
|
+
result->w = fabsf(v->w);
|
435
|
+
|
436
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
437
|
+
}
|
438
|
+
|
439
|
+
VALUE rb_vector4_sqrt(VALUE self) {
|
440
|
+
VECTOR4();
|
441
|
+
Vector4 *result = ALLOC(Vector4);
|
442
|
+
|
443
|
+
result->x = sqrtf(v->x);
|
444
|
+
result->y = sqrtf(v->y);
|
445
|
+
result->z = sqrtf(v->z);
|
446
|
+
result->w = sqrtf(v->w);
|
447
|
+
|
448
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
449
|
+
}
|
450
|
+
|
451
|
+
VALUE rb_vector4_pow(VALUE self, VALUE exponent) {
|
452
|
+
VECTOR4();
|
453
|
+
Vector4 *result = ALLOC(Vector4);
|
454
|
+
float e = fabsf(NUM2FLT(exponent));
|
455
|
+
|
456
|
+
result->x = powf(fabsf(v->x), e);
|
457
|
+
result->y = powf(fabsf(v->y), e);
|
458
|
+
result->z = powf(fabsf(v->z), e);
|
459
|
+
result->w = powf(fabsf(v->w), e);
|
460
|
+
|
461
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
462
|
+
}
|
463
|
+
|
464
|
+
VALUE rb_vector4_dot(VALUE self, VALUE other) {
|
465
|
+
Vector4 *v1, *v2;
|
466
|
+
Data_Get_Struct(self, Vector4, v1);
|
467
|
+
Data_Get_Struct(other, Vector4, v2);
|
468
|
+
|
469
|
+
return DBL2NUM(v1->x * v2->x + v1->y * v2->y + v1->z * v2->z + v1->w * v2->w);
|
470
|
+
}
|
471
|
+
|
472
|
+
VALUE rb_vector4_clamp(VALUE self, VALUE min, VALUE max) {
|
473
|
+
return rb_vector4_clamp_s(CLASS_OF(self), self, min, max);
|
474
|
+
}
|
475
|
+
|
476
|
+
VALUE rb_vector4_normalize_bang(VALUE self) {
|
477
|
+
VECTOR4();
|
478
|
+
float inv = 1.0f / sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
|
479
|
+
v->x = v->x * inv;
|
480
|
+
v->y = v->y * inv;
|
481
|
+
v->z = v->z * inv;
|
482
|
+
v->w = v->w * inv;
|
483
|
+
|
484
|
+
return self;
|
485
|
+
}
|
486
|
+
|
487
|
+
VALUE rb_vector4_lerp_bang(VALUE self, VALUE other, VALUE amount) {
|
488
|
+
Vector4 *v1, *v2;
|
489
|
+
Data_Get_Struct(self, Vector4, v1);
|
490
|
+
Data_Get_Struct(other, Vector4, v2);
|
491
|
+
float w = NUMERIX_CLAMP(NUM2FLT(amount), 0.0f, 1.0f);
|
492
|
+
|
493
|
+
v1->x = v1->x + (v2->x - v1->x) * w;
|
494
|
+
v1->y = v1->y + (v2->y - v1->y) * w;
|
495
|
+
v1->z = v1->z + (v2->z - v1->z) * w;
|
496
|
+
v1->w = v1->w + (v2->w - v1->w) * w;
|
497
|
+
|
498
|
+
return self;
|
499
|
+
}
|
500
|
+
|
501
|
+
VALUE rb_vector4_transform_bang(VALUE self, VALUE other) {
|
502
|
+
struct RData *rdata = RDATA(self);
|
503
|
+
VALUE result = rb_vector4_transform_s(rdata->basic.klass, self, other);
|
504
|
+
Vector4 *src;
|
505
|
+
Data_Get_Struct(result, Vector4, src);
|
506
|
+
memcpy(rdata->data, src, sizeof(Vector4));
|
507
|
+
return self;
|
508
|
+
}
|
509
|
+
|
510
|
+
VALUE rb_vector4_clamp_bang(VALUE self, VALUE min, VALUE max) {
|
511
|
+
struct RData *rdata = RDATA(self);
|
512
|
+
VALUE result = rb_vector4_clamp_s(rdata->basic.klass, self, min, max);
|
513
|
+
Vector4 *src;
|
514
|
+
Data_Get_Struct(result, Vector4, src);
|
515
|
+
memcpy(rdata->data, src, sizeof(Vector4));
|
516
|
+
return self;
|
517
|
+
}
|
518
|
+
|
519
|
+
static inline VALUE rb_vector4_clamp_s(VALUE klass, VALUE vector, VALUE minimum, VALUE maximum) {
|
520
|
+
Vector4 *v, *result;
|
521
|
+
Data_Get_Struct(vector, Vector4, v);
|
522
|
+
result = ALLOC(Vector4);
|
523
|
+
float x = v->x, y = v->y, z = v->z, w = v->w;
|
524
|
+
|
525
|
+
// This compare order is very important!!!
|
526
|
+
// We must follow HLSL behavior in the case user specified min value is bigger than max value.
|
527
|
+
if (NUMERIX_TYPE_P(minimum, rb_cVector4) && NUMERIX_TYPE_P(maximum, rb_cVector4)) {
|
528
|
+
Vector4 *min, *max;
|
529
|
+
Data_Get_Struct(minimum, Vector4, min);
|
530
|
+
Data_Get_Struct(maximum, Vector4, max);
|
531
|
+
|
532
|
+
x = NUMERIX_MIN(x, max->x);
|
533
|
+
x = NUMERIX_MAX(x, min->x);
|
534
|
+
|
535
|
+
y = NUMERIX_MIN(y, max->y);
|
536
|
+
y = NUMERIX_MAX(y, min->y);
|
537
|
+
|
538
|
+
z = NUMERIX_MIN(z, max->z);
|
539
|
+
z = NUMERIX_MAX(z, min->z);
|
540
|
+
|
541
|
+
w = NUMERIX_MIN(w, max->w);
|
542
|
+
w = NUMERIX_MAX(w, min->w);
|
543
|
+
} else {
|
544
|
+
float minf = NUM2FLT(minimum);
|
545
|
+
float maxf = NUM2FLT(maximum);
|
546
|
+
|
547
|
+
x = NUMERIX_MIN(x, maxf);
|
548
|
+
x = NUMERIX_MAX(x, minf);
|
549
|
+
|
550
|
+
y = NUMERIX_MIN(y, maxf);
|
551
|
+
y = NUMERIX_MAX(y, minf);
|
552
|
+
|
553
|
+
z = NUMERIX_MIN(z, maxf);
|
554
|
+
z = NUMERIX_MAX(z, minf);
|
555
|
+
|
556
|
+
w = NUMERIX_MIN(w, maxf);
|
557
|
+
w = NUMERIX_MAX(w, minf);
|
558
|
+
}
|
559
|
+
|
560
|
+
result->x = x;
|
561
|
+
result->y = y;
|
562
|
+
result->z = z;
|
563
|
+
result->w = w;
|
564
|
+
return NUMERIX_WRAP(klass, result);
|
565
|
+
}
|
566
|
+
|
567
|
+
static inline VALUE rb_vector4_lerp_s(VALUE klass, VALUE vec1, VALUE vec2, VALUE amount) {
|
568
|
+
Vector4 *v1, *v2, *result;
|
569
|
+
Data_Get_Struct(vec1, Vector4, v1);
|
570
|
+
Data_Get_Struct(vec2, Vector4, v2);
|
571
|
+
result = ALLOC(Vector4);
|
572
|
+
|
573
|
+
float w = NUMERIX_CLAMP(NUM2FLT(amount), 0.0f, 1.0f);
|
574
|
+
|
575
|
+
result->x = v1->x + (v2->x - v1->x) * w;
|
576
|
+
result->y = v1->y + (v2->y - v1->y) * w;
|
577
|
+
result->z = v1->z + (v2->z - v1->z) * w;
|
578
|
+
result->w = v1->w + (v2->w - v1->w) * w;
|
579
|
+
|
580
|
+
return NUMERIX_WRAP(klass, result);
|
581
|
+
}
|
582
|
+
|
583
|
+
static inline VALUE rb_vector4_transform_s(VALUE klass, VALUE vector, VALUE matrix) {
|
584
|
+
Vector4 *v, *result;
|
585
|
+
result = ALLOC(Vector4);
|
586
|
+
|
587
|
+
if (NUMERIX_TYPE_P(matrix, rb_cMatrix4x4)) {
|
588
|
+
Matrix4x4 *m;
|
589
|
+
Data_Get_Struct(matrix, Matrix4x4, m);
|
590
|
+
if (NUMERIX_TYPE_P(vector, rb_cVector2)) {
|
591
|
+
result->x = v->x * m->m11 + v->y * m->m21 + m->m41;
|
592
|
+
result->y = v->x * m->m12 + v->y * m->m22 + m->m42;
|
593
|
+
result->z = v->x * m->m13 + v->y * m->m23 + m->m43;
|
594
|
+
result->w = v->x * m->m14 + v->y * m->m24 + m->m44;
|
595
|
+
} else if (NUMERIX_TYPE_P(vector, rb_cVector3)) {
|
596
|
+
result->x = v->x * m->m11 + v->y * m->m21 + v->z * m->m31 + m->m41;
|
597
|
+
result->y = v->x * m->m12 + v->y * m->m22 + v->z * m->m32 + m->m42;
|
598
|
+
result->z = v->x * m->m13 + v->y * m->m23 + v->z * m->m33 + m->m43;
|
599
|
+
result->w = v->x * m->m14 + v->y * m->m24 + v->z * m->m34 + m->m44;
|
600
|
+
} else if (NUMERIX_TYPE_P(vector, rb_cVector4)) {
|
601
|
+
result->x = v->x * m->m11 + v->y * m->m21 + v->z * m->m31 + v->w * m->m41;
|
602
|
+
result->y = v->x * m->m12 + v->y * m->m22 + v->z * m->m32 + v->w * m->m42;
|
603
|
+
result->z = v->x * m->m13 + v->y * m->m23 + v->z * m->m33 + v->w * m->m43;
|
604
|
+
result->w = v->x * m->m14 + v->y * m->m24 + v->z * m->m34 + v->w * m->m44;
|
605
|
+
} else
|
606
|
+
rb_raise(rb_eTypeError, "%s is not a valid Vector type", CLASS_NAME(vector));
|
607
|
+
} else if (NUMERIX_TYPE_P(matrix, rb_cQuaternion)) {
|
608
|
+
Quaternion *q;
|
609
|
+
Data_Get_Struct(matrix, Quaternion, q);
|
610
|
+
float x2, y2, z2, wx2, wy2, wz2, xx2, xy2, xz2, yy2, yz2, zz2;
|
611
|
+
if (NUMERIX_TYPE_P(vector, rb_cVector2)) {
|
612
|
+
Vector2 *v2;
|
613
|
+
Data_Get_Struct(vector, Vector2, v2);
|
614
|
+
x2 = q->x + q->x;
|
615
|
+
y2 = q->y + q->y;
|
616
|
+
z2 = q->z + q->z;
|
617
|
+
|
618
|
+
wx2 = q->w * x2;
|
619
|
+
wy2 = q->w * y2;
|
620
|
+
wz2 = q->w * z2;
|
621
|
+
xx2 = q->x * x2;
|
622
|
+
xy2 = q->x * y2;
|
623
|
+
xz2 = q->x * z2;
|
624
|
+
yy2 = q->y * y2;
|
625
|
+
yz2 = q->y * z2;
|
626
|
+
zz2 = q->z * z2;
|
627
|
+
|
628
|
+
result->x = v2->x * (1.0f - yy2 - zz2) + v2->y * (xy2 - wz2);
|
629
|
+
result->y = v2->x * (xy2 + wz2) + v2->y * (1.0f - xx2 - zz2);
|
630
|
+
result->z = v2->x * (xz2 - wy2) + v2->y * (yz2 + wx2);
|
631
|
+
result->w = 1.0f;
|
632
|
+
} else if (NUMERIX_TYPE_P(vector, rb_cVector3)) {
|
633
|
+
Vector3 *v3;
|
634
|
+
Data_Get_Struct(vector, Vector3, v3);
|
635
|
+
x2 = q->x + q->x;
|
636
|
+
y2 = q->y + q->y;
|
637
|
+
z2 = q->z + q->z;
|
638
|
+
|
639
|
+
wx2 = q->w * x2;
|
640
|
+
wy2 = q->w * y2;
|
641
|
+
wz2 = q->w * z2;
|
642
|
+
xx2 = q->x * x2;
|
643
|
+
xy2 = q->x * y2;
|
644
|
+
xz2 = q->x * z2;
|
645
|
+
yy2 = q->y * y2;
|
646
|
+
yz2 = q->y * z2;
|
647
|
+
zz2 = q->z * z2;
|
648
|
+
|
649
|
+
result->x = v3->x * (1.0f - yy2 - zz2) + v3->y * (xy2 - wz2) + v3->z * (xz2 + wy2);
|
650
|
+
result->y = v3->x * (xy2 + wz2) + v3->y * (1.0f - xx2 - zz2) + v3->z * (yz2 - wx2);
|
651
|
+
result->z = v3->x * (xz2 - wy2) + v3->y * (yz2 + wx2) + v3->z * (1.0f - xx2 - yy2);
|
652
|
+
result->w = 1.0f;
|
653
|
+
} else if (NUMERIX_TYPE_P(vector, rb_cVector4)) {
|
654
|
+
Vector4 *v4;
|
655
|
+
Data_Get_Struct(vector, Vector4, v4);
|
656
|
+
x2 = q->x + q->x;
|
657
|
+
y2 = q->y + q->y;
|
658
|
+
z2 = q->z + q->z;
|
659
|
+
|
660
|
+
wx2 = q->w * x2;
|
661
|
+
wy2 = q->w * y2;
|
662
|
+
wz2 = q->w * z2;
|
663
|
+
xx2 = q->x * x2;
|
664
|
+
xy2 = q->x * y2;
|
665
|
+
xz2 = q->x * z2;
|
666
|
+
yy2 = q->y * y2;
|
667
|
+
yz2 = q->y * z2;
|
668
|
+
zz2 = q->z * z2;
|
669
|
+
|
670
|
+
result->x = v4->x * (1.0f - yy2 - zz2) + v4->y * (xy2 - wz2) + v4->z * (xz2 + wy2);
|
671
|
+
result->y = v4->x * (xy2 + wz2) + v4->y * (1.0f - xx2 - zz2) + v4->z * (yz2 - wx2);
|
672
|
+
result->z = v4->x * (xz2 - wy2) + v4->y * (yz2 + wx2) + v4->z * (1.0f - xx2 - yy2);
|
673
|
+
result->w = v4->w;
|
674
|
+
} else
|
675
|
+
rb_raise(rb_eTypeError, "%s is not a valid Vector type", CLASS_NAME(vector));
|
676
|
+
|
677
|
+
} else {
|
678
|
+
rb_raise(rb_eTypeError, "%s is not a valid Matrix4x4 or Quaternion", CLASS_NAME(matrix));
|
679
|
+
return Qnil;
|
680
|
+
}
|
681
|
+
|
682
|
+
return NUMERIX_WRAP(klass, result);
|
683
|
+
}
|
684
|
+
|
685
|
+
static inline VALUE rb_vector4_min_s(VALUE klass, VALUE vec1, VALUE vec2) {
|
686
|
+
Vector4 *v1, *v2, *result;
|
687
|
+
Data_Get_Struct(vec1, Vector4, v1);
|
688
|
+
Data_Get_Struct(vec2, Vector4, v2);
|
689
|
+
result = ALLOC(Vector4);
|
690
|
+
|
691
|
+
result->x = NUMERIX_MIN(v1->x, v2->x);
|
692
|
+
result->y = NUMERIX_MIN(v1->y, v2->y);
|
693
|
+
result->z = NUMERIX_MIN(v1->z, v2->z);
|
694
|
+
result->w = NUMERIX_MIN(v1->w, v2->w);
|
695
|
+
|
696
|
+
return NUMERIX_WRAP(klass, result);
|
697
|
+
}
|
698
|
+
|
699
|
+
static inline VALUE rb_vector4_max_s(VALUE klass, VALUE vec1, VALUE vec2) {
|
700
|
+
Vector4 *v1, *v2, *result;
|
701
|
+
Data_Get_Struct(vec1, Vector4, v1);
|
702
|
+
Data_Get_Struct(vec2, Vector4, v2);
|
703
|
+
result = ALLOC(Vector4);
|
704
|
+
|
705
|
+
result->x = NUMERIX_MAX(v1->x, v2->x);
|
706
|
+
result->y = NUMERIX_MAX(v1->y, v2->y);
|
707
|
+
result->z = NUMERIX_MAX(v1->z, v2->z);
|
708
|
+
result->w = NUMERIX_MAX(v1->w, v2->w);
|
709
|
+
|
710
|
+
return NUMERIX_WRAP(klass, result);
|
711
|
+
}
|
712
|
+
|
713
|
+
VALUE rb_vector4_create_norm(VALUE klass, VALUE x, VALUE y, VALUE z, VALUE w) {
|
714
|
+
Vector4 *v = ALLOC(Vector4);
|
715
|
+
float vx = NUM2FLT(x);
|
716
|
+
float vy = NUM2FLT(y);
|
717
|
+
float vz = NUM2FLT(z);
|
718
|
+
float vw = NUM2FLT(w);
|
719
|
+
|
720
|
+
float inv = 1.0f / sqrtf(vx * vx + vy * vy + vz * vz + vw * vw);
|
721
|
+
v->x = vx * inv;
|
722
|
+
v->y = vy * inv;
|
723
|
+
v->z = vz * inv;
|
724
|
+
v->w = vw * inv;
|
725
|
+
|
726
|
+
return NUMERIX_WRAP(klass, v);
|
727
|
+
}
|