@multiplekex/shallot 0.1.2 → 0.1.3
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/package.json +4 -4
- package/src/core/math.ts +135 -55
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplekex/shallot",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@mapbox/tiny-sdf": "^2.0.7",
|
|
21
21
|
"bitecs": "^0.4.0",
|
|
22
|
-
"fast-xml-parser": "^5.3.3"
|
|
23
|
-
"wgpu-matrix": "^3.4.0"
|
|
22
|
+
"fast-xml-parser": "^5.3.3"
|
|
24
23
|
},
|
|
25
24
|
"devDependencies": {
|
|
26
25
|
"@napi-rs/canvas": "^0.1.88",
|
|
@@ -28,7 +27,8 @@
|
|
|
28
27
|
"@types/three": "^0.182.0",
|
|
29
28
|
"three": "^0.182.0",
|
|
30
29
|
"troika-three-text": "^0.52.4",
|
|
31
|
-
"webgpu": "^0.3.8"
|
|
30
|
+
"webgpu": "^0.3.8",
|
|
31
|
+
"wgpu-matrix": "^3.4.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"typescript": "^5"
|
package/src/core/math.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
const DEG_TO_RAD = Math.PI / 180;
|
|
2
|
+
const RAD_TO_DEG = 180 / Math.PI;
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const tempQuatOut = quat.create();
|
|
6
|
-
const tempMat4 = mat4.create();
|
|
7
|
-
const tempVec3A = new Float32Array(3);
|
|
8
|
-
const tempVec3B = new Float32Array(3);
|
|
9
|
-
const tempVec3C = new Float32Array(3);
|
|
4
|
+
const _quat = { x: 0, y: 0, z: 0, w: 1 };
|
|
5
|
+
const _euler = { x: 0, y: 0, z: 0 };
|
|
10
6
|
|
|
11
7
|
export function clamp(value: number, min: number, max: number): number {
|
|
12
|
-
return
|
|
8
|
+
return value < min ? min : value > max ? max : value;
|
|
13
9
|
}
|
|
14
10
|
|
|
15
11
|
export function lerp(a: number, b: number, t: number): number {
|
|
@@ -27,25 +23,65 @@ export function slerp(
|
|
|
27
23
|
toW: number,
|
|
28
24
|
t: number
|
|
29
25
|
): { x: number; y: number; z: number; w: number } {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
let dot = fromX * toX + fromY * toY + fromZ * toZ + fromW * toW;
|
|
27
|
+
|
|
28
|
+
if (dot < 0) {
|
|
29
|
+
dot = -dot;
|
|
30
|
+
toX = -toX;
|
|
31
|
+
toY = -toY;
|
|
32
|
+
toZ = -toZ;
|
|
33
|
+
toW = -toW;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let s0: number, s1: number;
|
|
37
|
+
if (dot > 0.9995) {
|
|
38
|
+
s0 = 1 - t;
|
|
39
|
+
s1 = t;
|
|
40
|
+
} else {
|
|
41
|
+
const theta0 = Math.acos(dot);
|
|
42
|
+
const sinTheta0 = Math.sqrt(1 - dot * dot);
|
|
43
|
+
const theta = theta0 * t;
|
|
44
|
+
const sinTheta = Math.sin(theta);
|
|
45
|
+
s0 = Math.cos(theta) - (dot * sinTheta) / sinTheta0;
|
|
46
|
+
s1 = sinTheta / sinTheta0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
_quat.x = s0 * fromX + s1 * toX;
|
|
50
|
+
_quat.y = s0 * fromY + s1 * toY;
|
|
51
|
+
_quat.z = s0 * fromZ + s1 * toZ;
|
|
52
|
+
_quat.w = s0 * fromW + s1 * toW;
|
|
53
|
+
return _quat;
|
|
34
54
|
}
|
|
35
55
|
|
|
36
56
|
export function rotateQuaternion(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
57
|
+
qx: number,
|
|
58
|
+
qy: number,
|
|
59
|
+
qz: number,
|
|
60
|
+
qw: number,
|
|
41
61
|
dx: number,
|
|
42
62
|
dy: number,
|
|
43
63
|
dz: number
|
|
44
64
|
): { x: number; y: number; z: number; w: number } {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
65
|
+
const hx = dx * DEG_TO_RAD * 0.5;
|
|
66
|
+
const hy = dy * DEG_TO_RAD * 0.5;
|
|
67
|
+
const hz = dz * DEG_TO_RAD * 0.5;
|
|
68
|
+
const cx = Math.cos(hx),
|
|
69
|
+
sx = Math.sin(hx);
|
|
70
|
+
const cy = Math.cos(hy),
|
|
71
|
+
sy = Math.sin(hy);
|
|
72
|
+
const cz = Math.cos(hz),
|
|
73
|
+
sz = Math.sin(hz);
|
|
74
|
+
|
|
75
|
+
const bx = sx * cy * cz + cx * sy * sz;
|
|
76
|
+
const by = cx * sy * cz - sx * cy * sz;
|
|
77
|
+
const bz = cx * cy * sz + sx * sy * cz;
|
|
78
|
+
const bw = cx * cy * cz - sx * sy * sz;
|
|
79
|
+
|
|
80
|
+
_quat.x = qw * bx + qx * bw + qy * bz - qz * by;
|
|
81
|
+
_quat.y = qw * by - qx * bz + qy * bw + qz * bx;
|
|
82
|
+
_quat.z = qw * bz + qx * by - qy * bx + qz * bw;
|
|
83
|
+
_quat.w = qw * bw - qx * bx - qy * by - qz * bz;
|
|
84
|
+
return _quat;
|
|
49
85
|
}
|
|
50
86
|
|
|
51
87
|
export function eulerToQuaternion(
|
|
@@ -53,8 +89,21 @@ export function eulerToQuaternion(
|
|
|
53
89
|
y: number,
|
|
54
90
|
z: number
|
|
55
91
|
): { x: number; y: number; z: number; w: number } {
|
|
56
|
-
|
|
57
|
-
|
|
92
|
+
const hx = x * DEG_TO_RAD * 0.5;
|
|
93
|
+
const hy = y * DEG_TO_RAD * 0.5;
|
|
94
|
+
const hz = z * DEG_TO_RAD * 0.5;
|
|
95
|
+
const cx = Math.cos(hx),
|
|
96
|
+
sx = Math.sin(hx);
|
|
97
|
+
const cy = Math.cos(hy),
|
|
98
|
+
sy = Math.sin(hy);
|
|
99
|
+
const cz = Math.cos(hz),
|
|
100
|
+
sz = Math.sin(hz);
|
|
101
|
+
|
|
102
|
+
_quat.x = sx * cy * cz + cx * sy * sz;
|
|
103
|
+
_quat.y = cx * sy * cz - sx * cy * sz;
|
|
104
|
+
_quat.z = cx * cy * sz + sx * sy * cz;
|
|
105
|
+
_quat.w = cx * cy * cz - sx * sy * sz;
|
|
106
|
+
return _quat;
|
|
58
107
|
}
|
|
59
108
|
|
|
60
109
|
export function quaternionToEuler(
|
|
@@ -76,30 +125,18 @@ export function quaternionToEuler(
|
|
|
76
125
|
wy = w * y2,
|
|
77
126
|
wz = w * z2;
|
|
78
127
|
|
|
79
|
-
const m11 = 1 - (yy + zz);
|
|
80
|
-
const m12 = xy - wz;
|
|
81
128
|
const m13 = xz + wy;
|
|
82
|
-
const
|
|
83
|
-
const m23 = yz - wx;
|
|
84
|
-
const m32 = yz + wx;
|
|
85
|
-
const m33 = 1 - (xx + yy);
|
|
86
|
-
|
|
87
|
-
const ey = Math.asin(Math.max(-1, Math.min(1, m13)));
|
|
88
|
-
let ex: number, ez: number;
|
|
129
|
+
const ey = Math.asin(m13 < -1 ? -1 : m13 > 1 ? 1 : m13);
|
|
89
130
|
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
|
|
131
|
+
if (m13 > -0.9999999 && m13 < 0.9999999) {
|
|
132
|
+
_euler.x = Math.atan2(wx - yz, 1 - (xx + yy)) * RAD_TO_DEG;
|
|
133
|
+
_euler.z = Math.atan2(wz - xy, 1 - (yy + zz)) * RAD_TO_DEG;
|
|
93
134
|
} else {
|
|
94
|
-
|
|
95
|
-
|
|
135
|
+
_euler.x = Math.atan2(yz + wx, 1 - (xx + zz)) * RAD_TO_DEG;
|
|
136
|
+
_euler.z = 0;
|
|
96
137
|
}
|
|
97
|
-
|
|
98
|
-
return
|
|
99
|
-
x: utils.radToDeg(ex),
|
|
100
|
-
y: utils.radToDeg(ey),
|
|
101
|
-
z: utils.radToDeg(ez),
|
|
102
|
-
};
|
|
138
|
+
_euler.y = ey * RAD_TO_DEG;
|
|
139
|
+
return _euler;
|
|
103
140
|
}
|
|
104
141
|
|
|
105
142
|
export function lookAt(
|
|
@@ -113,16 +150,59 @@ export function lookAt(
|
|
|
113
150
|
upY = 1,
|
|
114
151
|
upZ = 0
|
|
115
152
|
): { x: number; y: number; z: number; w: number } {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
153
|
+
let fwdX = targetX - eyeX;
|
|
154
|
+
let fwdY = targetY - eyeY;
|
|
155
|
+
let fwdZ = targetZ - eyeZ;
|
|
156
|
+
const fwdLenSq = fwdX * fwdX + fwdY * fwdY + fwdZ * fwdZ;
|
|
157
|
+
if (fwdLenSq > 0) {
|
|
158
|
+
const invLen = 1 / Math.sqrt(fwdLenSq);
|
|
159
|
+
fwdX *= invLen;
|
|
160
|
+
fwdY *= invLen;
|
|
161
|
+
fwdZ *= invLen;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
let rightX = upY * fwdZ - upZ * fwdY;
|
|
165
|
+
let rightY = upZ * fwdX - upX * fwdZ;
|
|
166
|
+
let rightZ = upX * fwdY - upY * fwdX;
|
|
167
|
+
const rightLenSq = rightX * rightX + rightY * rightY + rightZ * rightZ;
|
|
168
|
+
if (rightLenSq > 0) {
|
|
169
|
+
const invLen = 1 / Math.sqrt(rightLenSq);
|
|
170
|
+
rightX *= invLen;
|
|
171
|
+
rightY *= invLen;
|
|
172
|
+
rightZ *= invLen;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const newUpX = fwdY * rightZ - fwdZ * rightY;
|
|
176
|
+
const newUpY = fwdZ * rightX - fwdX * rightZ;
|
|
177
|
+
const newUpZ = fwdX * rightY - fwdY * rightX;
|
|
178
|
+
|
|
179
|
+
const trace = rightX + newUpY + fwdZ;
|
|
180
|
+
|
|
181
|
+
if (trace > 0) {
|
|
182
|
+
const s = 0.5 / Math.sqrt(trace + 1);
|
|
183
|
+
_quat.w = 0.25 / s;
|
|
184
|
+
_quat.x = (newUpZ - fwdY) * s;
|
|
185
|
+
_quat.y = (fwdX - rightZ) * s;
|
|
186
|
+
_quat.z = (rightY - newUpX) * s;
|
|
187
|
+
} else if (rightX > newUpY && rightX > fwdZ) {
|
|
188
|
+
const s = 2 * Math.sqrt(1 + rightX - newUpY - fwdZ);
|
|
189
|
+
_quat.w = (newUpZ - fwdY) / s;
|
|
190
|
+
_quat.x = 0.25 * s;
|
|
191
|
+
_quat.y = (newUpX + rightY) / s;
|
|
192
|
+
_quat.z = (fwdX + rightZ) / s;
|
|
193
|
+
} else if (newUpY > fwdZ) {
|
|
194
|
+
const s = 2 * Math.sqrt(1 + newUpY - rightX - fwdZ);
|
|
195
|
+
_quat.w = (fwdX - rightZ) / s;
|
|
196
|
+
_quat.x = (newUpX + rightY) / s;
|
|
197
|
+
_quat.y = 0.25 * s;
|
|
198
|
+
_quat.z = (fwdY + newUpZ) / s;
|
|
199
|
+
} else {
|
|
200
|
+
const s = 2 * Math.sqrt(1 + fwdZ - rightX - newUpY);
|
|
201
|
+
_quat.w = (rightY - newUpX) / s;
|
|
202
|
+
_quat.x = (fwdX + rightZ) / s;
|
|
203
|
+
_quat.y = (fwdY + newUpZ) / s;
|
|
204
|
+
_quat.z = 0.25 * s;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return _quat;
|
|
128
208
|
}
|