-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatrix.js
156 lines (138 loc) · 3.62 KB
/
matrix.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
export const mIdentity = () => [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
export const mInverse = (m) => {
let dst = [],
det = 0,
cofactor = (c, r) => {
let s = (i, j) => m[((c + i) & 3) | (((r + j) & 3) << 2)];
return (
((c + r) & 1 ? -1 : 1) *
(s(1, 1) * (s(2, 2) * s(3, 3) - s(3, 2) * s(2, 3)) -
s(2, 1) * (s(1, 2) * s(3, 3) - s(3, 2) * s(1, 3)) +
s(3, 1) * (s(1, 2) * s(2, 3) - s(2, 2) * s(1, 3)))
);
};
for (let n = 0; n < 16; n++) dst.push(cofactor(n >> 2, n & 3));
for (let n = 0; n < 4; n++) det += m[n] * dst[n << 2];
for (let n = 0; n < 16; n++) dst[n] /= det;
return dst;
};
export const m3Inverse = (m) => {
const [a, b, c, d, e, f, g, h, i] = m;
const det = m3Det(m);
return [
e * i - f * h,
-b * i + c * h,
b * f - c * e,
-d * i + f * g,
a * i - c * g,
-a * f + c * d,
d * h - e * g,
-a * h + b * g,
a * e - b * d,
].map((x) => x / det);
};
export const matrixMultiply = (a, b) => {
let dst = [];
for (let n = 0; n < 16; n++)
dst.push(
a[n & 3] * b[n & 12] +
a[(n & 3) | 4] * b[(n & 12) | 1] +
a[(n & 3) | 8] * b[(n & 12) | 2] +
a[(n & 3) | 12] * b[(n & 12) | 3]
);
return dst;
};
export const v3Cross = (a, b) => {
const [a1, a2, a3] = a,
[b1, b2, b3] = b;
return [a2 * b3 - a3 * b2, a3 * b1 - a1 * b3, a1 * b2 - a2 * b1];
};
export const vNormalize = (a) => {
const [x, y, z] = a;
const norm = Math.sqrt(x * x + y * y + z * z);
return a.map((x) => x * norm);
};
export const vColumnLeftMultiply = (m, v) => {
const [a, b, c, d, e, f, g, h, i] = m;
const [x, y, z] = v;
return [a * x + b * y + c * z, d * x + e * y + f * z, g * x + h * y + i * z];
};
export const mTranslate = (tx, ty, tz, m) => {
return matrixMultiply(m, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1]);
};
export const mInverseTranslate = (tx, ty, tz, m) => {
return matrixMultiply(
m,
mInverse([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1])
);
};
export const mRotateX = (theta, m) => {
let c = Math.cos(theta),
s = Math.sin(theta);
return matrixMultiply(m, [1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1]);
};
export const mInverseRotateX = (theta, m) => {
let c = Math.cos(theta),
s = Math.sin(theta);
return matrixMultiply(
mInverse([1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1]),
m
);
};
export const m3Augment = (m) => {
const [a,b,c,d,e,f,g,h,i] = m;
return [a,b,c,0,d,e,f,0,g,h,i,0,0,0,0,1];
}
export const m3Det = (m) => {
const [a1, b1, c1, a2, b2, c2, a3, b3, c3] = m;
return (
a1 * b2 * c3 +
b1 * c2 * a3 +
c1 * a2 * b3 -
a3 * b2 * c1 -
b3 * c2 * c1 -
c3 * a2 * b1
);
};
export const mRotateY = (theta, m) => {
let c = Math.cos(theta),
s = Math.sin(theta);
return matrixMultiply(m, [c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1]);
};
export const mInverseRotateY = (theta, m) => {
let c = Math.cos(theta),
s = Math.sin(theta);
return matrixMultiply(
mInverse([c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1]),
m
);
};
export const mRotateZ = (theta, m) => {
let c = Math.cos(theta),
s = Math.sin(theta);
return matrixMultiply(m, [c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
};
export const mScale = (sx, sy, sz, m) => {
return matrixMultiply(m, [sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1]);
};
export const mPerspective = (fl, m) => {
return matrixMultiply(m, [
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
-1 / fl,
0,
0,
0,
1,
]);
};
export const m3Identity = () => [1, 0, 0, 0, 1, 0, 0, 0, 1];