react-x11 0.0.1 → 1.2.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.
package/src/mat4.js ADDED
@@ -0,0 +1,235 @@
1
+ // 4x4 matrices in OpenGL's column-major order, as Float32Array(16) — the
2
+ // layout MultMatrixf/LoadMatrixf expect on the wire, so nothing is
3
+ // transposed on the way out.
4
+
5
+ export function identity() {
6
+ // prettier-ignore
7
+ return new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
8
+ }
9
+
10
+ /** out = a * b (apply b first, then a — same convention as GL). */
11
+ export function multiply(a, b, out = new Float32Array(16)) {
12
+ for (let col = 0; col < 4; col++) {
13
+ const b0 = b[col * 4];
14
+ const b1 = b[col * 4 + 1];
15
+ const b2 = b[col * 4 + 2];
16
+ const b3 = b[col * 4 + 3];
17
+ for (let row = 0; row < 4; row++) {
18
+ out[col * 4 + row] =
19
+ a[row] * b0 + a[4 + row] * b1 + a[8 + row] * b2 + a[12 + row] * b3;
20
+ }
21
+ }
22
+ return out;
23
+ }
24
+
25
+ /**
26
+ * Compose position / euler rotation (XYZ order, radians) / scale into a
27
+ * transform, the same order three.js uses: T * Rx * Ry * Rz * S.
28
+ */
29
+ export function compose(position, rotation, scale, out = new Float32Array(16)) {
30
+ const [px, py, pz] = position;
31
+ const [rx, ry, rz] = rotation;
32
+ const [sx, sy, sz] = scale;
33
+ const cx = Math.cos(rx);
34
+ const sxr = Math.sin(rx);
35
+ const cy = Math.cos(ry);
36
+ const syr = Math.sin(ry);
37
+ const cz = Math.cos(rz);
38
+ const szr = Math.sin(rz);
39
+
40
+ // rotation matrix for the XYZ euler order
41
+ const r00 = cy * cz;
42
+ const r01 = -cy * szr;
43
+ const r02 = syr;
44
+ const r10 = sxr * syr * cz + cx * szr;
45
+ const r11 = -sxr * syr * szr + cx * cz;
46
+ const r12 = -sxr * cy;
47
+ const r20 = -cx * syr * cz + sxr * szr;
48
+ const r21 = cx * syr * szr + sxr * cz;
49
+ const r22 = cx * cy;
50
+
51
+ out[0] = r00 * sx;
52
+ out[1] = r10 * sx;
53
+ out[2] = r20 * sx;
54
+ out[3] = 0;
55
+ out[4] = r01 * sy;
56
+ out[5] = r11 * sy;
57
+ out[6] = r21 * sy;
58
+ out[7] = 0;
59
+ out[8] = r02 * sz;
60
+ out[9] = r12 * sz;
61
+ out[10] = r22 * sz;
62
+ out[11] = 0;
63
+ out[12] = px;
64
+ out[13] = py;
65
+ out[14] = pz;
66
+ out[15] = 1;
67
+ return out;
68
+ }
69
+
70
+ /** Perspective projection; `fov` is the vertical field of view in degrees. */
71
+ export function perspective(
72
+ fov,
73
+ aspect,
74
+ near,
75
+ far,
76
+ out = new Float32Array(16),
77
+ ) {
78
+ const f = 1 / Math.tan((fov * Math.PI) / 360);
79
+ out.fill(0);
80
+ out[0] = f / aspect;
81
+ out[5] = f;
82
+ out[10] = (far + near) / (near - far);
83
+ out[11] = -1;
84
+ out[14] = (2 * far * near) / (near - far);
85
+ return out;
86
+ }
87
+
88
+ export function orthographic(
89
+ left,
90
+ right,
91
+ bottom,
92
+ top,
93
+ near,
94
+ far,
95
+ out = new Float32Array(16),
96
+ ) {
97
+ out.fill(0);
98
+ out[0] = 2 / (right - left);
99
+ out[5] = 2 / (top - bottom);
100
+ out[10] = -2 / (far - near);
101
+ out[12] = -(right + left) / (right - left);
102
+ out[13] = -(top + bottom) / (top - bottom);
103
+ out[14] = -(far + near) / (far - near);
104
+ out[15] = 1;
105
+ return out;
106
+ }
107
+
108
+ function normalize(v) {
109
+ const len = Math.hypot(v[0], v[1], v[2]) || 1;
110
+ return [v[0] / len, v[1] / len, v[2] / len];
111
+ }
112
+
113
+ function cross(a, b) {
114
+ return [
115
+ a[1] * b[2] - a[2] * b[1],
116
+ a[2] * b[0] - a[0] * b[2],
117
+ a[0] * b[1] - a[1] * b[0],
118
+ ];
119
+ }
120
+
121
+ /** View matrix for a camera at `eye` looking at `target`. */
122
+ export function lookAt(
123
+ eye,
124
+ target,
125
+ up = [0, 1, 0],
126
+ out = new Float32Array(16),
127
+ ) {
128
+ const z = normalize([
129
+ eye[0] - target[0],
130
+ eye[1] - target[1],
131
+ eye[2] - target[2],
132
+ ]);
133
+ let x = cross(up, z);
134
+ if (Math.hypot(x[0], x[1], x[2]) < 1e-6) {
135
+ // up is parallel to the view direction: nudge it so the basis stays sane
136
+ x = cross([up[0] + 1e-4, up[1], up[2] + 1e-4], z);
137
+ }
138
+ x = normalize(x);
139
+ const y = cross(z, x);
140
+
141
+ out[0] = x[0];
142
+ out[1] = y[0];
143
+ out[2] = z[0];
144
+ out[3] = 0;
145
+ out[4] = x[1];
146
+ out[5] = y[1];
147
+ out[6] = z[1];
148
+ out[7] = 0;
149
+ out[8] = x[2];
150
+ out[9] = y[2];
151
+ out[10] = z[2];
152
+ out[11] = 0;
153
+ out[12] = -(x[0] * eye[0] + x[1] * eye[1] + x[2] * eye[2]);
154
+ out[13] = -(y[0] * eye[0] + y[1] * eye[1] + y[2] * eye[2]);
155
+ out[14] = -(z[0] * eye[0] + z[1] * eye[1] + z[2] * eye[2]);
156
+ out[15] = 1;
157
+ return out;
158
+ }
159
+
160
+ /** Inverse of an affine or projective 4x4; null when singular. */
161
+ export function invert(m, out = new Float32Array(16)) {
162
+ const [
163
+ a00,
164
+ a01,
165
+ a02,
166
+ a03,
167
+ a10,
168
+ a11,
169
+ a12,
170
+ a13,
171
+ a20,
172
+ a21,
173
+ a22,
174
+ a23,
175
+ a30,
176
+ a31,
177
+ a32,
178
+ a33,
179
+ ] = m;
180
+
181
+ const b00 = a00 * a11 - a01 * a10;
182
+ const b01 = a00 * a12 - a02 * a10;
183
+ const b02 = a00 * a13 - a03 * a10;
184
+ const b03 = a01 * a12 - a02 * a11;
185
+ const b04 = a01 * a13 - a03 * a11;
186
+ const b05 = a02 * a13 - a03 * a12;
187
+ const b06 = a20 * a31 - a21 * a30;
188
+ const b07 = a20 * a32 - a22 * a30;
189
+ const b08 = a20 * a33 - a23 * a30;
190
+ const b09 = a21 * a32 - a22 * a31;
191
+ const b10 = a21 * a33 - a23 * a31;
192
+ const b11 = a22 * a33 - a23 * a32;
193
+
194
+ const det =
195
+ b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
196
+ if (!det) return null;
197
+ const d = 1 / det;
198
+
199
+ out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * d;
200
+ out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * d;
201
+ out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * d;
202
+ out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * d;
203
+ out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * d;
204
+ out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * d;
205
+ out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * d;
206
+ out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * d;
207
+ out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * d;
208
+ out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * d;
209
+ out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * d;
210
+ out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * d;
211
+ out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * d;
212
+ out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * d;
213
+ out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * d;
214
+ out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * d;
215
+ return out;
216
+ }
217
+
218
+ /** Apply a matrix to a point, dividing through by w. */
219
+ export function transformPoint(m, [x, y, z]) {
220
+ const w = m[3] * x + m[7] * y + m[11] * z + m[15] || 1;
221
+ return [
222
+ (m[0] * x + m[4] * y + m[8] * z + m[12]) / w,
223
+ (m[1] * x + m[5] * y + m[9] * z + m[13]) / w,
224
+ (m[2] * x + m[6] * y + m[10] * z + m[14]) / w,
225
+ ];
226
+ }
227
+
228
+ /** Apply a matrix to a direction (no translation, no w divide). */
229
+ export function transformDirection(m, [x, y, z]) {
230
+ return [
231
+ m[0] * x + m[4] * y + m[8] * z,
232
+ m[1] * x + m[5] * y + m[9] * z,
233
+ m[2] * x + m[6] * y + m[10] * z,
234
+ ];
235
+ }