UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

481 lines (473 loc) 13.4 kB
import { clamp } from "three/src/math/MathUtils"; import { Quaternion } from "three/src/Three"; export class ObservableQuaternion { isQuaternion=true; ti; ii; si; ks; _onChangeCallback; ei; ri; constructor(t = 0, s = 0, i = 0, h = 1) { this.ti = t; this.ii = s; this.si = i; this.ks = h; this._onChangeCallback = () => {}; this.ei = () => {}; this.ri = () => {}; } onBeforeGetComponent(t) { this.ri = t; } onBeforeChange(t) { this.ei = t; } static slerp(t, s, i, h) { console.warn("THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead."); return i.slerpQuaternions(t, s, h); } static slerpFlat(t, s, i, h, e, r, n) { let a = i[h + 0], o = i[h + 1], u = i[h + 2], c = i[h + 3]; const l = e[r + 0], M = e[r + 1], f = e[r + 2], m = e[r + 3]; if (n === 0) { t[s + 0] = a; t[s + 1] = o; t[s + 2] = u; t[s + 3] = c; return; } if (n === 1) { t[s + 0] = l; t[s + 1] = M; t[s + 2] = f; t[s + 3] = m; return; } if (c !== m || a !== l || o !== M || u !== f) { let t = 1 - n; const s = a * l + o * M + u * f + c * m, i = s >= 0 ? 1 : -1, h = 1 - s * s; if (h > Number.EPSILON) { const e = Math.sqrt(h), r = Math.atan2(e, s * i); t = Math.sin(t * r) / e; n = Math.sin(n * r) / e; } const e = n * i; a = a * t + l * e; o = o * t + M * e; u = u * t + f * e; c = c * t + m * e; if (t === 1 - n) { const t = 1 / Math.sqrt(a * a + o * o + u * u + c * c); a *= t; o *= t; u *= t; c *= t; } } t[s] = a; t[s + 1] = o; t[s + 2] = u; t[s + 3] = c; } static multiplyQuaternionsFlat(t, s, i, h, e, r) { const n = i[h]; const a = i[h + 1]; const o = i[h + 2]; const u = i[h + 3]; const c = e[r]; const l = e[r + 1]; const M = e[r + 2]; const f = e[r + 3]; t[s] = n * f + u * c + a * M - o * l; t[s + 1] = a * f + u * l + o * c - n * M; t[s + 2] = o * f + u * M + n * l - a * c; t[s + 3] = u * f - n * c - a * l - o * M; return t; } get _x() { this.ri(); return this.ti; } set _x(t) { this.ti = t; } get _y() { this.ri(); return this.ii; } set _y(t) { this.ii = t; } get _z() { this.ri(); return this.si; } set _z(t) { this.si = t; } get _w() { this.ri(); return this.ks; } set _w(t) { this.ks = t; } get x() { this.ri(); return this.ti; } set x(t) { this.ei(); this.ti = t; this._onChangeCallback(); } get y() { this.ri(); return this.ii; } set y(t) { this.ei(); this.ii = t; this._onChangeCallback(); } get z() { this.ri(); return this.si; } set z(t) { this.ei(); this.si = t; this._onChangeCallback(); } get w() { this.ri(); return this.ks; } set w(t) { this.ei(); this.ks = t; this._onChangeCallback(); } set(t, s, i, h) { this.ei(); this.ti = t; this.ii = s; this.si = i; this.ks = h; this._onChangeCallback(); return this; } clone() { this.ri(); return new Quaternion(this.ti, this.ii, this.si, this.ks); } copy(t) { this.ei(); this.ti = t.x; this.ii = t.y; this.si = t.z; this.ks = t.w; this._onChangeCallback(); return this; } setFromEuler(t, s) { if (!(t && t.isEuler)) { throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order."); } const i = t._x, h = t._y, e = t._z, r = t._order; const n = Math.cos; const a = Math.sin; const o = n(i / 2); const u = n(h / 2); const c = n(e / 2); const l = a(i / 2); const M = a(h / 2); const f = a(e / 2); this.ei(); switch (r) { case "XYZ": this.ti = l * u * c + o * M * f; this.ii = o * M * c - l * u * f; this.si = o * u * f + l * M * c; this.ks = o * u * c - l * M * f; break; case "YXZ": this.ti = l * u * c + o * M * f; this.ii = o * M * c - l * u * f; this.si = o * u * f - l * M * c; this.ks = o * u * c + l * M * f; break; case "ZXY": this.ti = l * u * c - o * M * f; this.ii = o * M * c + l * u * f; this.si = o * u * f + l * M * c; this.ks = o * u * c - l * M * f; break; case "ZYX": this.ti = l * u * c - o * M * f; this.ii = o * M * c + l * u * f; this.si = o * u * f - l * M * c; this.ks = o * u * c + l * M * f; break; case "YZX": this.ti = l * u * c + o * M * f; this.ii = o * M * c + l * u * f; this.si = o * u * f - l * M * c; this.ks = o * u * c - l * M * f; break; case "XZY": this.ti = l * u * c - o * M * f; this.ii = o * M * c - l * u * f; this.si = o * u * f + l * M * c; this.ks = o * u * c + l * M * f; break; default: console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: " + r); } if (s !== false) this._onChangeCallback(); return this; } setFromAxisAngle(t, s) { const i = s / 2, h = Math.sin(i); this.ei(); this.ti = t.x * h; this.ii = t.y * h; this.si = t.z * h; this.ks = Math.cos(i); this._onChangeCallback(); return this; } setFromRotationMatrix(t) { const s = t.elements, i = s[0], h = s[4], e = s[8], r = s[1], n = s[5], a = s[9], o = s[2], u = s[6], c = s[10], l = i + n + c; this.ei(); if (l > 0) { const t = .5 / Math.sqrt(l + 1); this.ks = .25 / t; this.ti = (u - a) * t; this.ii = (e - o) * t; this.si = (r - h) * t; } else if (i > n && i > c) { const t = 2 * Math.sqrt(1 + i - n - c); this.ks = (u - a) / t; this.ti = .25 * t; this.ii = (h + r) / t; this.si = (e + o) / t; } else if (n > c) { const t = 2 * Math.sqrt(1 + n - i - c); this.ks = (e - o) / t; this.ti = (h + r) / t; this.ii = .25 * t; this.si = (a + u) / t; } else { const t = 2 * Math.sqrt(1 + c - i - n); this.ks = (r - h) / t; this.ti = (e + o) / t; this.ii = (a + u) / t; this.si = .25 * t; } this._onChangeCallback(); return this; } setFromUnitVectors(t, s) { let i = t.dot(s) + 1; this.ei(); if (i < Number.EPSILON) { i = 0; if (Math.abs(t.x) > Math.abs(t.z)) { this.ti = -t.y; this.ii = t.x; this.si = 0; this.ks = i; } else { this.ti = 0; this.ii = -t.z; this.si = t.y; this.ks = i; } } else { this.ti = t.y * s.z - t.z * s.y; this.ii = t.z * s.x - t.x * s.z; this.si = t.x * s.y - t.y * s.x; this.ks = i; } return this.normalize(); } angleTo(t) { return 2 * Math.acos(Math.abs(clamp(this.dot(t), -1, 1))); } rotateTowards(t, s) { const i = this.angleTo(t); if (i === 0) return this; const h = Math.min(1, s / i); this.slerp(t, h); return this; } identity() { return this.set(0, 0, 0, 1); } invert() { return this.conjugate(); } conjugate() { this.ri(); this.ei(); this.ti *= -1; this.ii *= -1; this.si *= -1; this._onChangeCallback(); return this; } dot(t) { this.ri(); return this.ti * t._x + this.ii * t._y + this.si * t._z + this.ks * t._w; } lengthSq() { this.ri(); return this.ti * this.ti + this.ii * this.ii + this.si * this.si + this.ks * this.ks; } length() { this.ri(); return Math.sqrt(this.ti * this.ti + this.ii * this.ii + this.si * this.si + this.ks * this.ks); } normalize() { let t = this.length(); if (t === 0) { this.ei(); this.ti = 0; this.ii = 0; this.si = 0; this.ks = 1; } else { t = 1 / t; this.ri(); this.ei(); this.ti = this.ti * t; this.ii = this.ii * t; this.si = this.si * t; this.ks = this.ks * t; } this._onChangeCallback(); return this; } multiply(t, s) { if (s !== undefined) { console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."); return this.multiplyQuaternions(t, s); } if (t._x === 0 && t._y === 0 && t._z === 0 && t._w === 1) return this; return this.multiplyQuaternions(this, t); } premultiply(t) { return this.multiplyQuaternions(t, this); } multiplyQuaternions(t, s) { const i = t._x, h = t._y, e = t._z, r = t._w; const n = s._x, a = s._y, o = s._z, u = s._w; this.ei(); this.ti = i * u + r * n + h * o - e * a; this.ii = h * u + r * a + e * n - i * o; this.si = e * u + r * o + i * a - h * n; this.ks = r * u - i * n - h * a - e * o; this._onChangeCallback(); return this; } slerp(t, s) { if (s === 0) return this; if (s === 1) return this.copy(t); this.ri(); const i = this.ti, h = this.ii, e = this.si, r = this.ks; let n = r * t._w + i * t._x + h * t._y + e * t._z; this.ei(); if (n < 0) { this.ks = -t._w; this.ti = -t._x; this.ii = -t._y; this.si = -t._z; n = -n; } else { this.copy(t); } if (n >= 1) { this.ks = r; this.ti = i; this.ii = h; this.si = e; return this; } const a = 1 - n * n; if (a <= Number.EPSILON) { const t = 1 - s; this.ks = t * r + s * this.ks; this.ti = t * i + s * this.ti; this.ii = t * h + s * this.ii; this.si = t * e + s * this.si; this.normalize(); return this; } const o = Math.sqrt(a); const u = Math.atan2(o, n); const c = Math.sin((1 - s) * u) / o, l = Math.sin(s * u) / o; this.ks = r * c + this.ks * l; this.ti = i * c + this.ti * l; this.ii = h * c + this.ii * l; this.si = e * c + this.si * l; this._onChangeCallback(); return this; } slerpQuaternions(t, s, i) { return this.copy(t).slerp(s, i); } random() { const t = Math.random(); const s = Math.sqrt(1 - t); const i = Math.sqrt(t); const h = 2 * Math.PI * Math.random(); const e = 2 * Math.PI * Math.random(); return this.set(s * Math.cos(h), i * Math.sin(e), i * Math.cos(e), s * Math.sin(h)); } equals(t) { this.ri(); return t._x === this.ti && t._y === this.ii && t._z === this.si && t._w === this.ks; } fromArray(t, s = 0) { if (this.ti === t[s] && this.ii === t[s + 1] && this.si === t[s + 2] && this.ks === t[s + 3]) return this; this.ei(); this.ti = t[s]; this.ii = t[s + 1]; this.si = t[s + 2]; this.ks = t[s + 3]; this._onChangeCallback(); return this; } toArray(t = [], s = 0) { this.ri(); t[s] = this.ti; t[s + 1] = this.ii; t[s + 2] = this.si; t[s + 3] = this.ks; return t; } fromBufferAttribute(t, s) { this.ti = t.getX(s); this.ii = t.getY(s); this.si = t.getZ(s); this.ks = t.getW(s); return this; } _onChange(t) { this._onChangeCallback = t; return this; } * [Symbol.iterator]() { this.ri(); yield this.ti; this.ri(); yield this.ii; this.ri(); yield this.si; this.ri(); yield this.ks; } }