numerix 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/ext/numerix/plane.c
ADDED
@@ -0,0 +1,311 @@
|
|
1
|
+
|
2
|
+
#include "plane.h"
|
3
|
+
|
4
|
+
VALUE rb_cPlane;
|
5
|
+
|
6
|
+
void Init_plane(VALUE outer) {
|
7
|
+
rb_cPlane = rb_define_class_under(outer, "Plane", rb_cNumerixStruct);
|
8
|
+
rb_define_alloc_func(rb_cPlane, rb_plane_alloc);
|
9
|
+
rb_define_method(rb_cPlane, "initialize", rb_plane_initialize, -1);
|
10
|
+
|
11
|
+
// Instance
|
12
|
+
rb_define_method(rb_cPlane, "normal", rb_plane_normal, 0);
|
13
|
+
rb_define_method(rb_cPlane, "distance", rb_plane_distance, 0);
|
14
|
+
rb_define_method(rb_cPlane, "normal=", rb_plane_normal_set, 1);
|
15
|
+
rb_define_method(rb_cPlane, "distance=", rb_plane_distance_set, 1);
|
16
|
+
rb_define_method(rb_cPlane, "==", rb_plane_equal, 1);
|
17
|
+
rb_define_method(rb_cPlane, "transform", rb_plane_transform, 1);
|
18
|
+
rb_define_method(rb_cPlane, "transform!", rb_plane_transform_bang, 1);
|
19
|
+
rb_define_method(rb_cPlane, "dot", rb_plane_dot, 1);
|
20
|
+
rb_define_method(rb_cPlane, "dot_coord", rb_plane_dot_coord, 1);
|
21
|
+
rb_define_method(rb_cPlane, "dot_normal", rb_plane_dot_normal, 1);
|
22
|
+
rb_define_method(rb_cPlane, "normalize", rb_plane_normalize, 0);
|
23
|
+
rb_define_method(rb_cPlane, "normalize!", rb_plane_normalize_bang, 0);
|
24
|
+
|
25
|
+
// Conversion
|
26
|
+
rb_define_method(rb_cPlane, "to_s", rb_plane_to_s, 0);
|
27
|
+
|
28
|
+
// Class
|
29
|
+
rb_define_singleton_method(rb_cPlane, "from_vertices", rb_plane_from_vertices_s, 3);
|
30
|
+
}
|
31
|
+
|
32
|
+
static VALUE rb_plane_alloc(VALUE klass) {
|
33
|
+
Plane *p = ALLOC(Plane);
|
34
|
+
memset(p, 0, sizeof(Plane));
|
35
|
+
return NUMERIX_WRAP(klass, p);
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE rb_plane_initialize(int argc, VALUE *argv, VALUE self) {
|
39
|
+
PLANE();
|
40
|
+
switch (argc) {
|
41
|
+
case 0:
|
42
|
+
break;
|
43
|
+
case 1: {
|
44
|
+
Vector4 *vec4;
|
45
|
+
Data_Get_Struct(argv[0], Vector4, vec4);
|
46
|
+
memcpy(p, vec4, sizeof(Vector4));
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
case 2: {
|
50
|
+
Vector3 *vec3;
|
51
|
+
Data_Get_Struct(argv[0], Vector3, vec3);
|
52
|
+
memcpy(p, vec3, sizeof(Vector3));
|
53
|
+
p->distance = NUM2FLT(argv[1]);
|
54
|
+
break;
|
55
|
+
}
|
56
|
+
case 4: {
|
57
|
+
p->normal.x = NUM2FLT(argv[0]);
|
58
|
+
p->normal.y = NUM2FLT(argv[1]);
|
59
|
+
p->normal.z = NUM2FLT(argv[2]);
|
60
|
+
p->distance = NUM2FLT(argv[3]);
|
61
|
+
break;
|
62
|
+
}
|
63
|
+
default:
|
64
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0, 1, 2, 4)", argc);
|
65
|
+
break;
|
66
|
+
}
|
67
|
+
return Qnil;
|
68
|
+
}
|
69
|
+
|
70
|
+
VALUE rb_plane_normal(VALUE self) {
|
71
|
+
PLANE();
|
72
|
+
return NUMERIX_WRAP(rb_cVector3, &(p->normal));
|
73
|
+
}
|
74
|
+
|
75
|
+
VALUE rb_plane_distance(VALUE self) {
|
76
|
+
PLANE();
|
77
|
+
return DBL2NUM(p->distance);
|
78
|
+
}
|
79
|
+
|
80
|
+
VALUE rb_plane_normal_set(VALUE self, VALUE value) {
|
81
|
+
PLANE();
|
82
|
+
Vector3 *v3;
|
83
|
+
Data_Get_Struct(value, Vector3, v3);
|
84
|
+
memcpy(p, v3, sizeof(Vector3));
|
85
|
+
return value;
|
86
|
+
}
|
87
|
+
|
88
|
+
VALUE rb_plane_distance_set(VALUE self, VALUE value) {
|
89
|
+
PLANE();
|
90
|
+
p->distance = NUM2FLT(value);
|
91
|
+
return value;
|
92
|
+
}
|
93
|
+
|
94
|
+
VALUE rb_plane_equal(VALUE self, VALUE other) {
|
95
|
+
if (CLASS_OF(other) != CLASS_OF(self))
|
96
|
+
return Qfalse;
|
97
|
+
Plane *p1, *p2;
|
98
|
+
Data_Get_Struct(self, Plane, p1);
|
99
|
+
Data_Get_Struct(other, Plane, p2);
|
100
|
+
return FLT_EQUAL(p1->normal.x, p2->normal.x) && FLT_EQUAL(p1->normal.y, p2->normal.y) &&
|
101
|
+
FLT_EQUAL(p1->normal.z, p2->normal.z) && FLT_EQUAL(p1->distance, p2->distance)
|
102
|
+
? Qtrue
|
103
|
+
: Qfalse;
|
104
|
+
}
|
105
|
+
|
106
|
+
VALUE rb_plane_to_s(VALUE self) {
|
107
|
+
PLANE();
|
108
|
+
return rb_sprintf("{<%f, %f, %f>, %f}", p->normal.x, p->normal.y, p->normal.z, p->distance);
|
109
|
+
}
|
110
|
+
|
111
|
+
VALUE rb_plane_transform(VALUE self, VALUE matrix) {
|
112
|
+
PLANE();
|
113
|
+
Plane *result = ALLOC(Plane);
|
114
|
+
|
115
|
+
if (NUMERIX_TYPE_P(matrix, rb_cMatrix4x4)) {
|
116
|
+
VALUE inverted = rb_matrix4x4_invert(matrix);
|
117
|
+
Matrix4x4 *m;
|
118
|
+
Data_Get_Struct(inverted, Matrix4x4, m);
|
119
|
+
|
120
|
+
float x = p->normal.x, y = p->normal.y, z = p->normal.z, w = p->distance;
|
121
|
+
|
122
|
+
result->normal.x = x * m->m11 + y * m->m12 + z * m->m13 + w * m->m14;
|
123
|
+
result->normal.y = x * m->m21 + y * m->m22 + z * m->m23 + w * m->m24;
|
124
|
+
result->normal.z = x * m->m31 + y * m->m32 + z * m->m33 + w * m->m34;
|
125
|
+
result->distance = x * m->m41 + y * m->m42 + z * m->m43 + w * m->m44;
|
126
|
+
} else {
|
127
|
+
Quaternion *q;
|
128
|
+
Data_Get_Struct(matrix, Quaternion, q);
|
129
|
+
|
130
|
+
// Compute rotation matrix.
|
131
|
+
float x2 = q->x + q->x;
|
132
|
+
float y2 = q->y + q->y;
|
133
|
+
float z2 = q->z + q->z;
|
134
|
+
|
135
|
+
float wx2 = q->w * x2;
|
136
|
+
float wy2 = q->w * y2;
|
137
|
+
float wz2 = q->w * z2;
|
138
|
+
float xx2 = q->x * x2;
|
139
|
+
float xy2 = q->x * y2;
|
140
|
+
float xz2 = q->x * z2;
|
141
|
+
float yy2 = q->y * y2;
|
142
|
+
float yz2 = q->y * z2;
|
143
|
+
float zz2 = q->z * z2;
|
144
|
+
|
145
|
+
float m11 = 1.0f - yy2 - zz2;
|
146
|
+
float m21 = xy2 - wz2;
|
147
|
+
float m31 = xz2 + wy2;
|
148
|
+
|
149
|
+
float m12 = xy2 + wz2;
|
150
|
+
float m22 = 1.0f - xx2 - zz2;
|
151
|
+
float m32 = yz2 - wx2;
|
152
|
+
|
153
|
+
float m13 = xz2 - wy2;
|
154
|
+
float m23 = yz2 + wx2;
|
155
|
+
float m33 = 1.0f - xx2 - yy2;
|
156
|
+
|
157
|
+
float x = p->normal.x, y = p->normal.y, z = p->normal.z;
|
158
|
+
|
159
|
+
result->normal.x = x * m11 + y * m21 + z * m31;
|
160
|
+
result->normal.y = x * m12 + y * m22 + z * m32;
|
161
|
+
result->normal.y = x * m13 + y * m23 + z * m33;
|
162
|
+
result->distance = p->distance;
|
163
|
+
}
|
164
|
+
|
165
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
166
|
+
}
|
167
|
+
|
168
|
+
VALUE rb_plane_transform_bang(VALUE self, VALUE matrix) {
|
169
|
+
PLANE();
|
170
|
+
|
171
|
+
if (NUMERIX_TYPE_P(matrix, rb_cMatrix4x4)) {
|
172
|
+
VALUE inverted = rb_matrix4x4_invert(matrix);
|
173
|
+
Matrix4x4 *m;
|
174
|
+
Data_Get_Struct(inverted, Matrix4x4, m);
|
175
|
+
|
176
|
+
float x = p->normal.x, y = p->normal.y, z = p->normal.z, w = p->distance;
|
177
|
+
|
178
|
+
p->normal.x = x * m->m11 + y * m->m12 + z * m->m13 + w * m->m14;
|
179
|
+
p->normal.y = x * m->m21 + y * m->m22 + z * m->m23 + w * m->m24;
|
180
|
+
p->normal.z = x * m->m31 + y * m->m32 + z * m->m33 + w * m->m34;
|
181
|
+
p->distance = x * m->m41 + y * m->m42 + z * m->m43 + w * m->m44;
|
182
|
+
} else {
|
183
|
+
Quaternion *q;
|
184
|
+
Data_Get_Struct(matrix, Quaternion, q);
|
185
|
+
|
186
|
+
// Compute rotation matrix.
|
187
|
+
float x2 = q->x + q->x;
|
188
|
+
float y2 = q->y + q->y;
|
189
|
+
float z2 = q->z + q->z;
|
190
|
+
|
191
|
+
float wx2 = q->w * x2;
|
192
|
+
float wy2 = q->w * y2;
|
193
|
+
float wz2 = q->w * z2;
|
194
|
+
float xx2 = q->x * x2;
|
195
|
+
float xy2 = q->x * y2;
|
196
|
+
float xz2 = q->x * z2;
|
197
|
+
float yy2 = q->y * y2;
|
198
|
+
float yz2 = q->y * z2;
|
199
|
+
float zz2 = q->z * z2;
|
200
|
+
|
201
|
+
float m11 = 1.0f - yy2 - zz2;
|
202
|
+
float m21 = xy2 - wz2;
|
203
|
+
float m31 = xz2 + wy2;
|
204
|
+
|
205
|
+
float m12 = xy2 + wz2;
|
206
|
+
float m22 = 1.0f - xx2 - zz2;
|
207
|
+
float m32 = yz2 - wx2;
|
208
|
+
|
209
|
+
float m13 = xz2 - wy2;
|
210
|
+
float m23 = yz2 + wx2;
|
211
|
+
float m33 = 1.0f - xx2 - yy2;
|
212
|
+
|
213
|
+
float x = p->normal.x, y = p->normal.y, z = p->normal.z;
|
214
|
+
|
215
|
+
p->normal.x = x * m11 + y * m21 + z * m31;
|
216
|
+
p->normal.y = x * m12 + y * m22 + z * m32;
|
217
|
+
p->normal.y = x * m13 + y * m23 + z * m33;
|
218
|
+
p->distance = p->distance;
|
219
|
+
}
|
220
|
+
|
221
|
+
return self;
|
222
|
+
}
|
223
|
+
|
224
|
+
VALUE rb_plane_dot(VALUE self, VALUE vec4) {
|
225
|
+
PLANE();
|
226
|
+
Vector4 *v;
|
227
|
+
Data_Get_Struct(vec4, Vector4, v);
|
228
|
+
|
229
|
+
return DBL2NUM(p->normal.x * v->x + p->normal.y * v->y + p->normal.z * v->z + p->distance * v->w);
|
230
|
+
}
|
231
|
+
|
232
|
+
VALUE rb_plane_dot_coord(VALUE self, VALUE vec3) {
|
233
|
+
PLANE();
|
234
|
+
Vector3 *v;
|
235
|
+
Data_Get_Struct(vec3, Vector3, v);
|
236
|
+
return DBL2NUM(p->normal.x * v->x + p->normal.y * v->y + p->normal.z * v->z + p->distance);
|
237
|
+
}
|
238
|
+
|
239
|
+
VALUE rb_plane_dot_normal(VALUE self, VALUE vec3) {
|
240
|
+
PLANE();
|
241
|
+
Vector3 *v;
|
242
|
+
Data_Get_Struct(vec3, Vector3, v);
|
243
|
+
|
244
|
+
return DBL2NUM(p->normal.x * v->x + p->normal.y * v->y + p->normal.z * v->z);
|
245
|
+
}
|
246
|
+
|
247
|
+
VALUE rb_plane_normalize(VALUE self) {
|
248
|
+
PLANE();
|
249
|
+
Plane *result = ALLOC(Plane);
|
250
|
+
|
251
|
+
float f = p->normal.x * p->normal.x + p->normal.y * p->normal.y + p->normal.z * p->normal.z;
|
252
|
+
|
253
|
+
if (fabsf(f - 1.0f) < FLT_EPSILON) {
|
254
|
+
// It already normalized, so we don't need to further process.
|
255
|
+
memcpy(result, p, sizeof(Plane));
|
256
|
+
} else {
|
257
|
+
float fInv = 1.0f / sqrtf(f);
|
258
|
+
result->normal.x = p->normal.x * fInv;
|
259
|
+
result->normal.y = p->normal.y * fInv;
|
260
|
+
result->normal.z = p->normal.z * fInv;
|
261
|
+
result->distance = p->distance * fInv;
|
262
|
+
}
|
263
|
+
|
264
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
265
|
+
}
|
266
|
+
|
267
|
+
VALUE rb_plane_normalize_bang(VALUE self) {
|
268
|
+
PLANE();
|
269
|
+
float f = p->normal.x * p->normal.x + p->normal.y * p->normal.y + p->normal.z * p->normal.z;
|
270
|
+
|
271
|
+
if (fabsf(f - 1.0f) >= FLT_EPSILON) {
|
272
|
+
float fInv = 1.0f / sqrtf(f);
|
273
|
+
p->normal.x = p->normal.x * fInv;
|
274
|
+
p->normal.y = p->normal.y * fInv;
|
275
|
+
p->normal.z = p->normal.z * fInv;
|
276
|
+
p->distance = p->distance * fInv;
|
277
|
+
}
|
278
|
+
|
279
|
+
return self;
|
280
|
+
}
|
281
|
+
|
282
|
+
VALUE rb_plane_from_vertices_s(VALUE klass, VALUE vert1, VALUE vert2, VALUE vert3) {
|
283
|
+
Vector3 *v1, *v2, *v3;
|
284
|
+
Data_Get_Struct(vert1, Vector3, v1);
|
285
|
+
Data_Get_Struct(vert2, Vector3, v2);
|
286
|
+
Data_Get_Struct(vert3, Vector3, v3);
|
287
|
+
|
288
|
+
float ax = v2->x - v1->x;
|
289
|
+
float ay = v2->y - v1->y;
|
290
|
+
float az = v2->z - v1->z;
|
291
|
+
|
292
|
+
float bx = v3->x - v1->x;
|
293
|
+
float by = v3->y - v1->y;
|
294
|
+
float bz = v3->z - v1->z;
|
295
|
+
|
296
|
+
// N=Cross(a,b)
|
297
|
+
float nx = ay * bz - az * by;
|
298
|
+
float ny = az * bx - ax * bz;
|
299
|
+
float nz = ax * by - ay * bx;
|
300
|
+
|
301
|
+
// Normalize(N)
|
302
|
+
float invNorm = 1.0f / sqrtf(nx * nx + ny * ny + nz * nz);
|
303
|
+
|
304
|
+
Plane *p = ALLOC(Plane);
|
305
|
+
p->normal.x = nx * invNorm;
|
306
|
+
p->normal.y = ny * invNorm;
|
307
|
+
p->normal.z = nz * invNorm;
|
308
|
+
p->distance = -(p->normal.x * v1->x + p->normal.y * v1->y + p->normal.z * v1->z);
|
309
|
+
|
310
|
+
return NUMERIX_WRAP(klass, p);
|
311
|
+
}
|
data/ext/numerix/plane.h
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#ifndef NUMERIX_PLANE_H
|
2
|
+
#define NUMERIX_PLANE_H 1
|
3
|
+
|
4
|
+
#include "common.h"
|
5
|
+
#include "matrix4x4.h"
|
6
|
+
|
7
|
+
#define PLANE() \
|
8
|
+
Plane *p; \
|
9
|
+
Data_Get_Struct(self, Plane, p)
|
10
|
+
|
11
|
+
void Init_plane(VALUE outer);
|
12
|
+
static VALUE rb_plane_alloc(VALUE klass);
|
13
|
+
VALUE rb_plane_initialize(int argc, VALUE *argv, VALUE self);
|
14
|
+
|
15
|
+
// Instance
|
16
|
+
VALUE rb_plane_normal(VALUE self);
|
17
|
+
VALUE rb_plane_distance(VALUE self);
|
18
|
+
VALUE rb_plane_normal_set(VALUE self, VALUE value);
|
19
|
+
VALUE rb_plane_distance_set(VALUE self, VALUE value);
|
20
|
+
VALUE rb_plane_equal(VALUE self, VALUE other);
|
21
|
+
VALUE rb_plane_to_s(VALUE self);
|
22
|
+
VALUE rb_plane_equal(VALUE self, VALUE other);
|
23
|
+
VALUE rb_plane_transform(VALUE self, VALUE matrix);
|
24
|
+
VALUE rb_plane_transform_bang(VALUE self, VALUE matrix);
|
25
|
+
VALUE rb_plane_dot(VALUE self, VALUE vec4);
|
26
|
+
VALUE rb_plane_dot_coord(VALUE self, VALUE vec3);
|
27
|
+
VALUE rb_plane_dot_normal(VALUE self, VALUE vec3);
|
28
|
+
VALUE rb_plane_normalize(VALUE self);
|
29
|
+
VALUE rb_plane_normalize_bang(VALUE self);
|
30
|
+
|
31
|
+
// Class
|
32
|
+
VALUE rb_plane_from_vertices_s(VALUE klass, VALUE vert1, VALUE vert2, VALUE vert3);
|
33
|
+
|
34
|
+
#endif /* NUMERIX_PLANE_H */
|