@multiplekex/shallot 0.1.3 → 0.1.4

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/core/math.ts +95 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplekex/shallot",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/core/math.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  const DEG_TO_RAD = Math.PI / 180;
2
2
  const RAD_TO_DEG = 180 / Math.PI;
3
3
 
4
- const _quat = { x: 0, y: 0, z: 0, w: 1 };
5
- const _euler = { x: 0, y: 0, z: 0 };
6
-
7
4
  export function clamp(value: number, min: number, max: number): number {
8
5
  return value < min ? min : value > max ? max : value;
9
6
  }
@@ -46,11 +43,12 @@ export function slerp(
46
43
  s1 = sinTheta / sinTheta0;
47
44
  }
48
45
 
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;
46
+ return {
47
+ x: s0 * fromX + s1 * toX,
48
+ y: s0 * fromY + s1 * toY,
49
+ z: s0 * fromZ + s1 * toZ,
50
+ w: s0 * fromW + s1 * toW,
51
+ };
54
52
  }
55
53
 
56
54
  export function rotateQuaternion(
@@ -77,11 +75,12 @@ export function rotateQuaternion(
77
75
  const bz = cx * cy * sz + sx * sy * cz;
78
76
  const bw = cx * cy * cz - sx * sy * sz;
79
77
 
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;
78
+ return {
79
+ x: qw * bx + qx * bw + qy * bz - qz * by,
80
+ y: qw * by - qx * bz + qy * bw + qz * bx,
81
+ z: qw * bz + qx * by - qy * bx + qz * bw,
82
+ w: qw * bw - qx * bx - qy * by - qz * bz,
83
+ };
85
84
  }
86
85
 
87
86
  export function eulerToQuaternion(
@@ -99,11 +98,12 @@ export function eulerToQuaternion(
99
98
  const cz = Math.cos(hz),
100
99
  sz = Math.sin(hz);
101
100
 
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;
101
+ return {
102
+ x: sx * cy * cz + cx * sy * sz,
103
+ y: cx * sy * cz - sx * cy * sz,
104
+ z: cx * cy * sz + sx * sy * cz,
105
+ w: cx * cy * cz - sx * sy * sz,
106
+ };
107
107
  }
108
108
 
109
109
  export function quaternionToEuler(
@@ -129,14 +129,18 @@ export function quaternionToEuler(
129
129
  const ey = Math.asin(m13 < -1 ? -1 : m13 > 1 ? 1 : m13);
130
130
 
131
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;
132
+ return {
133
+ x: Math.atan2(wx - yz, 1 - (xx + yy)) * RAD_TO_DEG,
134
+ y: ey * RAD_TO_DEG,
135
+ z: Math.atan2(wz - xy, 1 - (yy + zz)) * RAD_TO_DEG,
136
+ };
134
137
  } else {
135
- _euler.x = Math.atan2(yz + wx, 1 - (xx + zz)) * RAD_TO_DEG;
136
- _euler.z = 0;
138
+ return {
139
+ x: Math.atan2(yz + wx, 1 - (xx + zz)) * RAD_TO_DEG,
140
+ y: ey * RAD_TO_DEG,
141
+ z: 0,
142
+ };
137
143
  }
138
- _euler.y = ey * RAD_TO_DEG;
139
- return _euler;
140
144
  }
141
145
 
142
146
  export function lookAt(
@@ -150,59 +154,82 @@ export function lookAt(
150
154
  upY = 1,
151
155
  upZ = 0
152
156
  ): { x: number; y: number; z: number; w: number } {
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;
157
+ let zx = eyeX - targetX;
158
+ let zy = eyeY - targetY;
159
+ let zz = eyeZ - targetZ;
160
+ let zLen = Math.sqrt(zx * zx + zy * zy + zz * zz);
161
+
162
+ if (zLen === 0) {
163
+ zz = 1;
164
+ } else {
165
+ zLen = 1 / zLen;
166
+ zx *= zLen;
167
+ zy *= zLen;
168
+ zz *= zLen;
162
169
  }
163
170
 
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;
171
+ let xx = upY * zz - upZ * zy;
172
+ let xy = upZ * zx - upX * zz;
173
+ let xz = upX * zy - upY * zx;
174
+ let xLen = Math.sqrt(xx * xx + xy * xy + xz * xz);
175
+
176
+ if (xLen === 0) {
177
+ if (upZ !== 0) {
178
+ upX += 1e-4 * upX;
179
+ upY += 1e-4 * upY;
180
+ upZ += 1e-4 * upZ;
181
+ } else if (upY !== 0) {
182
+ upX += 1e-4 * upX;
183
+ upY += 1e-4 * upY;
184
+ upZ += 1e-4 * upZ;
185
+ } else {
186
+ upX += 1e-4 * upX;
187
+ upY += 1e-4 * upY;
188
+ upZ += 1e-4 * upZ;
189
+ }
190
+ xx = upY * zz - upZ * zy;
191
+ xy = upZ * zx - upX * zz;
192
+ xz = upX * zy - upY * zx;
193
+ xLen = Math.sqrt(xx * xx + xy * xy + xz * xz);
173
194
  }
174
195
 
175
- const newUpX = fwdY * rightZ - fwdZ * rightY;
176
- const newUpY = fwdZ * rightX - fwdX * rightZ;
177
- const newUpZ = fwdX * rightY - fwdY * rightX;
196
+ xLen = 1 / xLen;
197
+ xx *= xLen;
198
+ xy *= xLen;
199
+ xz *= xLen;
200
+
201
+ const yx = zy * xz - zz * xy;
202
+ const yy = zz * xx - zx * xz;
203
+ const yz = zx * xy - zy * xx;
178
204
 
179
- const trace = rightX + newUpY + fwdZ;
205
+ const trace = xx + yy + zz;
206
+ let qw: number, qx: number, qy: number, qz: number;
180
207
 
181
208
  if (trace > 0) {
182
209
  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;
210
+ qw = 0.25 / s;
211
+ qx = (yz - zy) * s;
212
+ qy = (zx - xz) * s;
213
+ qz = (xy - yx) * s;
214
+ } else if (xx > yy && xx > zz) {
215
+ const s = 2 * Math.sqrt(1 + xx - yy - zz);
216
+ qw = (yz - zy) / s;
217
+ qx = 0.25 * s;
218
+ qy = (yx + xy) / s;
219
+ qz = (zx + xz) / s;
220
+ } else if (yy > zz) {
221
+ const s = 2 * Math.sqrt(1 + yy - xx - zz);
222
+ qw = (zx - xz) / s;
223
+ qx = (yx + xy) / s;
224
+ qy = 0.25 * s;
225
+ qz = (yz + zy) / s;
199
226
  } 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;
227
+ const s = 2 * Math.sqrt(1 + zz - xx - yy);
228
+ qw = (xy - yx) / s;
229
+ qx = (zx + xz) / s;
230
+ qy = (yz + zy) / s;
231
+ qz = 0.25 * s;
205
232
  }
206
233
 
207
- return _quat;
234
+ return { x: qx, y: qy, z: qz, w: qw };
208
235
  }