var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i6 = decorators.length - 1, decorator; i6 >= 0; i6--)
if (decorator = decorators[i6])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
// node_modules/@lit/reactive-element/css-tag.js
var t = globalThis;
var e = t.ShadowRoot && (void 0 === t.ShadyCSS || t.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype;
var s = Symbol();
var o = /* @__PURE__ */ new WeakMap();
var n = class {
constructor(t6, e8, o8) {
if (this._$cssResult$ = true, o8 !== s) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
this.cssText = t6, this.t = e8;
}
get styleSheet() {
let t6 = this.o;
const s5 = this.t;
if (e && void 0 === t6) {
const e8 = void 0 !== s5 && 1 === s5.length;
e8 && (t6 = o.get(s5)), void 0 === t6 && ((this.o = t6 = new CSSStyleSheet()).replaceSync(this.cssText), e8 && o.set(s5, t6));
}
return t6;
}
toString() {
return this.cssText;
}
};
var r = (t6) => new n("string" == typeof t6 ? t6 : t6 + "", void 0, s);
var S = (s5, o8) => {
if (e) s5.adoptedStyleSheets = o8.map((t6) => t6 instanceof CSSStyleSheet ? t6 : t6.styleSheet);
else for (const e8 of o8) {
const o9 = document.createElement("style"), n7 = t.litNonce;
void 0 !== n7 && o9.setAttribute("nonce", n7), o9.textContent = e8.cssText, s5.appendChild(o9);
}
};
var c = e ? (t6) => t6 : (t6) => t6 instanceof CSSStyleSheet ? ((t7) => {
let e8 = "";
for (const s5 of t7.cssRules) e8 += s5.cssText;
return r(e8);
})(t6) : t6;
// node_modules/@lit/reactive-element/reactive-element.js
var { is: i2, defineProperty: e2, getOwnPropertyDescriptor: h, getOwnPropertyNames: r2, getOwnPropertySymbols: o2, getPrototypeOf: n2 } = Object;
var a = globalThis;
var c2 = a.trustedTypes;
var l = c2 ? c2.emptyScript : "";
var p = a.reactiveElementPolyfillSupport;
var d = (t6, s5) => t6;
var u = { toAttribute(t6, s5) {
switch (s5) {
case Boolean:
t6 = t6 ? l : null;
break;
case Object:
case Array:
t6 = null == t6 ? t6 : JSON.stringify(t6);
}
return t6;
}, fromAttribute(t6, s5) {
let i6 = t6;
switch (s5) {
case Boolean:
i6 = null !== t6;
break;
case Number:
i6 = null === t6 ? null : Number(t6);
break;
case Object:
case Array:
try {
i6 = JSON.parse(t6);
} catch (t7) {
i6 = null;
}
}
return i6;
} };
var f = (t6, s5) => !i2(t6, s5);
var b = { attribute: true, type: String, converter: u, reflect: false, useDefault: false, hasChanged: f };
Symbol.metadata ??= Symbol("metadata"), a.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap();
var y = class extends HTMLElement {
static addInitializer(t6) {
this._$Ei(), (this.l ??= []).push(t6);
}
static get observedAttributes() {
return this.finalize(), this._$Eh && [...this._$Eh.keys()];
}
static createProperty(t6, s5 = b) {
if (s5.state && (s5.attribute = false), this._$Ei(), this.prototype.hasOwnProperty(t6) && ((s5 = Object.create(s5)).wrapped = true), this.elementProperties.set(t6, s5), !s5.noAccessor) {
const i6 = Symbol(), h4 = this.getPropertyDescriptor(t6, i6, s5);
void 0 !== h4 && e2(this.prototype, t6, h4);
}
}
static getPropertyDescriptor(t6, s5, i6) {
const { get: e8, set: r6 } = h(this.prototype, t6) ?? { get() {
return this[s5];
}, set(t7) {
this[s5] = t7;
} };
return { get: e8, set(s6) {
const h4 = e8?.call(this);
r6?.call(this, s6), this.requestUpdate(t6, h4, i6);
}, configurable: true, enumerable: true };
}
static getPropertyOptions(t6) {
return this.elementProperties.get(t6) ?? b;
}
static _$Ei() {
if (this.hasOwnProperty(d("elementProperties"))) return;
const t6 = n2(this);
t6.finalize(), void 0 !== t6.l && (this.l = [...t6.l]), this.elementProperties = new Map(t6.elementProperties);
}
static finalize() {
if (this.hasOwnProperty(d("finalized"))) return;
if (this.finalized = true, this._$Ei(), this.hasOwnProperty(d("properties"))) {
const t7 = this.properties, s5 = [...r2(t7), ...o2(t7)];
for (const i6 of s5) this.createProperty(i6, t7[i6]);
}
const t6 = this[Symbol.metadata];
if (null !== t6) {
const s5 = litPropertyMetadata.get(t6);
if (void 0 !== s5) for (const [t7, i6] of s5) this.elementProperties.set(t7, i6);
}
this._$Eh = /* @__PURE__ */ new Map();
for (const [t7, s5] of this.elementProperties) {
const i6 = this._$Eu(t7, s5);
void 0 !== i6 && this._$Eh.set(i6, t7);
}
this.elementStyles = this.finalizeStyles(this.styles);
}
static finalizeStyles(s5) {
const i6 = [];
if (Array.isArray(s5)) {
const e8 = new Set(s5.flat(1 / 0).reverse());
for (const s6 of e8) i6.unshift(c(s6));
} else void 0 !== s5 && i6.push(c(s5));
return i6;
}
static _$Eu(t6, s5) {
const i6 = s5.attribute;
return false === i6 ? void 0 : "string" == typeof i6 ? i6 : "string" == typeof t6 ? t6.toLowerCase() : void 0;
}
constructor() {
super(), this._$Ep = void 0, this.isUpdatePending = false, this.hasUpdated = false, this._$Em = null, this._$Ev();
}
_$Ev() {
this._$ES = new Promise((t6) => this.enableUpdating = t6), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t6) => t6(this));
}
addController(t6) {
(this._$EO ??= /* @__PURE__ */ new Set()).add(t6), void 0 !== this.renderRoot && this.isConnected && t6.hostConnected?.();
}
removeController(t6) {
this._$EO?.delete(t6);
}
_$E_() {
const t6 = /* @__PURE__ */ new Map(), s5 = this.constructor.elementProperties;
for (const i6 of s5.keys()) this.hasOwnProperty(i6) && (t6.set(i6, this[i6]), delete this[i6]);
t6.size > 0 && (this._$Ep = t6);
}
createRenderRoot() {
const t6 = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
return S(t6, this.constructor.elementStyles), t6;
}
connectedCallback() {
this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(true), this._$EO?.forEach((t6) => t6.hostConnected?.());
}
enableUpdating(t6) {
}
disconnectedCallback() {
this._$EO?.forEach((t6) => t6.hostDisconnected?.());
}
attributeChangedCallback(t6, s5, i6) {
this._$AK(t6, i6);
}
_$ET(t6, s5) {
const i6 = this.constructor.elementProperties.get(t6), e8 = this.constructor._$Eu(t6, i6);
if (void 0 !== e8 && true === i6.reflect) {
const h4 = (void 0 !== i6.converter?.toAttribute ? i6.converter : u).toAttribute(s5, i6.type);
this._$Em = t6, null == h4 ? this.removeAttribute(e8) : this.setAttribute(e8, h4), this._$Em = null;
}
}
_$AK(t6, s5) {
const i6 = this.constructor, e8 = i6._$Eh.get(t6);
if (void 0 !== e8 && this._$Em !== e8) {
const t7 = i6.getPropertyOptions(e8), h4 = "function" == typeof t7.converter ? { fromAttribute: t7.converter } : void 0 !== t7.converter?.fromAttribute ? t7.converter : u;
this._$Em = e8;
const r6 = h4.fromAttribute(s5, t7.type);
this[e8] = r6 ?? this._$Ej?.get(e8) ?? r6, this._$Em = null;
}
}
requestUpdate(t6, s5, i6, e8 = false, h4) {
if (void 0 !== t6) {
const r6 = this.constructor;
if (false === e8 && (h4 = this[t6]), i6 ??= r6.getPropertyOptions(t6), !((i6.hasChanged ?? f)(h4, s5) || i6.useDefault && i6.reflect && h4 === this._$Ej?.get(t6) && !this.hasAttribute(r6._$Eu(t6, i6)))) return;
this.C(t6, s5, i6);
}
false === this.isUpdatePending && (this._$ES = this._$EP());
}
C(t6, s5, { useDefault: i6, reflect: e8, wrapped: h4 }, r6) {
i6 && !(this._$Ej ??= /* @__PURE__ */ new Map()).has(t6) && (this._$Ej.set(t6, r6 ?? s5 ?? this[t6]), true !== h4 || void 0 !== r6) || (this._$AL.has(t6) || (this.hasUpdated || i6 || (s5 = void 0), this._$AL.set(t6, s5)), true === e8 && this._$Em !== t6 && (this._$Eq ??= /* @__PURE__ */ new Set()).add(t6));
}
async _$EP() {
this.isUpdatePending = true;
try {
await this._$ES;
} catch (t7) {
Promise.reject(t7);
}
const t6 = this.scheduleUpdate();
return null != t6 && await t6, !this.isUpdatePending;
}
scheduleUpdate() {
return this.performUpdate();
}
performUpdate() {
if (!this.isUpdatePending) return;
if (!this.hasUpdated) {
if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) {
for (const [t8, s6] of this._$Ep) this[t8] = s6;
this._$Ep = void 0;
}
const t7 = this.constructor.elementProperties;
if (t7.size > 0) for (const [s6, i6] of t7) {
const { wrapped: t8 } = i6, e8 = this[s6];
true !== t8 || this._$AL.has(s6) || void 0 === e8 || this.C(s6, void 0, i6, e8);
}
}
let t6 = false;
const s5 = this._$AL;
try {
t6 = this.shouldUpdate(s5), t6 ? (this.willUpdate(s5), this._$EO?.forEach((t7) => t7.hostUpdate?.()), this.update(s5)) : this._$EM();
} catch (s6) {
throw t6 = false, this._$EM(), s6;
}
t6 && this._$AE(s5);
}
willUpdate(t6) {
}
_$AE(t6) {
this._$EO?.forEach((t7) => t7.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t6)), this.updated(t6);
}
_$EM() {
this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = false;
}
get updateComplete() {
return this.getUpdateComplete();
}
getUpdateComplete() {
return this._$ES;
}
shouldUpdate(t6) {
return true;
}
update(t6) {
this._$Eq &&= this._$Eq.forEach((t7) => this._$ET(t7, this[t7])), this._$EM();
}
updated(t6) {
}
firstUpdated(t6) {
}
};
y.elementStyles = [], y.shadowRootOptions = { mode: "open" }, y[d("elementProperties")] = /* @__PURE__ */ new Map(), y[d("finalized")] = /* @__PURE__ */ new Map(), p?.({ ReactiveElement: y }), (a.reactiveElementVersions ??= []).push("2.1.2");
// node_modules/lit-html/lit-html.js
var t2 = globalThis;
var i3 = (t6) => t6;
var s2 = t2.trustedTypes;
var e3 = s2 ? s2.createPolicy("lit-html", { createHTML: (t6) => t6 }) : void 0;
var h2 = "$lit$";
var o3 = `lit$${Math.random().toFixed(9).slice(2)}$`;
var n3 = "?" + o3;
var r3 = `<${n3}>`;
var l2 = document;
var c3 = () => l2.createComment("");
var a2 = (t6) => null === t6 || "object" != typeof t6 && "function" != typeof t6;
var u2 = Array.isArray;
var d2 = (t6) => u2(t6) || "function" == typeof t6?.[Symbol.iterator];
var f2 = "[ \n\f\r]";
var v = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g;
var _ = /-->/g;
var m = />/g;
var p2 = RegExp(`>|${f2}(?:([^\\s"'>=/]+)(${f2}*=${f2}*(?:[^
\f\r"'\`<>=]|("|')|))|$)`, "g");
var g = /'/g;
var $ = /"/g;
var y2 = /^(?:script|style|textarea|title)$/i;
var x = (t6) => (i6, ...s5) => ({ _$litType$: t6, strings: i6, values: s5 });
var b2 = x(1);
var w = x(2);
var T = x(3);
var E = Symbol.for("lit-noChange");
var A = Symbol.for("lit-nothing");
var C = /* @__PURE__ */ new WeakMap();
var P = l2.createTreeWalker(l2, 129);
function V(t6, i6) {
if (!u2(t6) || !t6.hasOwnProperty("raw")) throw Error("invalid template strings array");
return void 0 !== e3 ? e3.createHTML(i6) : i6;
}
var N = (t6, i6) => {
const s5 = t6.length - 1, e8 = [];
let n7, l3 = 2 === i6 ? "" : 3 === i6 ? "" : "")), e8];
};
var S2 = class _S {
constructor({ strings: t6, _$litType$: i6 }, e8) {
let r6;
this.parts = [];
let l3 = 0, a3 = 0;
const u3 = t6.length - 1, d3 = this.parts, [f4, v2] = N(t6, i6);
if (this.el = _S.createElement(f4, e8), P.currentNode = this.el.content, 2 === i6 || 3 === i6) {
const t7 = this.el.content.firstChild;
t7.replaceWith(...t7.childNodes);
}
for (; null !== (r6 = P.nextNode()) && d3.length < u3; ) {
if (1 === r6.nodeType) {
if (r6.hasAttributes()) for (const t7 of r6.getAttributeNames()) if (t7.endsWith(h2)) {
const i7 = v2[a3++], s5 = r6.getAttribute(t7).split(o3), e9 = /([.?@])?(.*)/.exec(i7);
d3.push({ type: 1, index: l3, name: e9[2], strings: s5, ctor: "." === e9[1] ? I : "?" === e9[1] ? L : "@" === e9[1] ? z : H }), r6.removeAttribute(t7);
} else t7.startsWith(o3) && (d3.push({ type: 6, index: l3 }), r6.removeAttribute(t7));
if (y2.test(r6.tagName)) {
const t7 = r6.textContent.split(o3), i7 = t7.length - 1;
if (i7 > 0) {
r6.textContent = s2 ? s2.emptyScript : "";
for (let s5 = 0; s5 < i7; s5++) r6.append(t7[s5], c3()), P.nextNode(), d3.push({ type: 2, index: ++l3 });
r6.append(t7[i7], c3());
}
}
} else if (8 === r6.nodeType) if (r6.data === n3) d3.push({ type: 2, index: l3 });
else {
let t7 = -1;
for (; -1 !== (t7 = r6.data.indexOf(o3, t7 + 1)); ) d3.push({ type: 7, index: l3 }), t7 += o3.length - 1;
}
l3++;
}
}
static createElement(t6, i6) {
const s5 = l2.createElement("template");
return s5.innerHTML = t6, s5;
}
};
function M(t6, i6, s5 = t6, e8) {
if (i6 === E) return i6;
let h4 = void 0 !== e8 ? s5._$Co?.[e8] : s5._$Cl;
const o8 = a2(i6) ? void 0 : i6._$litDirective$;
return h4?.constructor !== o8 && (h4?._$AO?.(false), void 0 === o8 ? h4 = void 0 : (h4 = new o8(t6), h4._$AT(t6, s5, e8)), void 0 !== e8 ? (s5._$Co ??= [])[e8] = h4 : s5._$Cl = h4), void 0 !== h4 && (i6 = M(t6, h4._$AS(t6, i6.values), h4, e8)), i6;
}
var R = class {
constructor(t6, i6) {
this._$AV = [], this._$AN = void 0, this._$AD = t6, this._$AM = i6;
}
get parentNode() {
return this._$AM.parentNode;
}
get _$AU() {
return this._$AM._$AU;
}
u(t6) {
const { el: { content: i6 }, parts: s5 } = this._$AD, e8 = (t6?.creationScope ?? l2).importNode(i6, true);
P.currentNode = e8;
let h4 = P.nextNode(), o8 = 0, n7 = 0, r6 = s5[0];
for (; void 0 !== r6; ) {
if (o8 === r6.index) {
let i7;
2 === r6.type ? i7 = new k(h4, h4.nextSibling, this, t6) : 1 === r6.type ? i7 = new r6.ctor(h4, r6.name, r6.strings, this, t6) : 6 === r6.type && (i7 = new Z(h4, this, t6)), this._$AV.push(i7), r6 = s5[++n7];
}
o8 !== r6?.index && (h4 = P.nextNode(), o8++);
}
return P.currentNode = l2, e8;
}
p(t6) {
let i6 = 0;
for (const s5 of this._$AV) void 0 !== s5 && (void 0 !== s5.strings ? (s5._$AI(t6, s5, i6), i6 += s5.strings.length - 2) : s5._$AI(t6[i6])), i6++;
}
};
var k = class _k {
get _$AU() {
return this._$AM?._$AU ?? this._$Cv;
}
constructor(t6, i6, s5, e8) {
this.type = 2, this._$AH = A, this._$AN = void 0, this._$AA = t6, this._$AB = i6, this._$AM = s5, this.options = e8, this._$Cv = e8?.isConnected ?? true;
}
get parentNode() {
let t6 = this._$AA.parentNode;
const i6 = this._$AM;
return void 0 !== i6 && 11 === t6?.nodeType && (t6 = i6.parentNode), t6;
}
get startNode() {
return this._$AA;
}
get endNode() {
return this._$AB;
}
_$AI(t6, i6 = this) {
t6 = M(this, t6, i6), a2(t6) ? t6 === A || null == t6 || "" === t6 ? (this._$AH !== A && this._$AR(), this._$AH = A) : t6 !== this._$AH && t6 !== E && this._(t6) : void 0 !== t6._$litType$ ? this.$(t6) : void 0 !== t6.nodeType ? this.T(t6) : d2(t6) ? this.k(t6) : this._(t6);
}
O(t6) {
return this._$AA.parentNode.insertBefore(t6, this._$AB);
}
T(t6) {
this._$AH !== t6 && (this._$AR(), this._$AH = this.O(t6));
}
_(t6) {
this._$AH !== A && a2(this._$AH) ? this._$AA.nextSibling.data = t6 : this.T(l2.createTextNode(t6)), this._$AH = t6;
}
$(t6) {
const { values: i6, _$litType$: s5 } = t6, e8 = "number" == typeof s5 ? this._$AC(t6) : (void 0 === s5.el && (s5.el = S2.createElement(V(s5.h, s5.h[0]), this.options)), s5);
if (this._$AH?._$AD === e8) this._$AH.p(i6);
else {
const t7 = new R(e8, this), s6 = t7.u(this.options);
t7.p(i6), this.T(s6), this._$AH = t7;
}
}
_$AC(t6) {
let i6 = C.get(t6.strings);
return void 0 === i6 && C.set(t6.strings, i6 = new S2(t6)), i6;
}
k(t6) {
u2(this._$AH) || (this._$AH = [], this._$AR());
const i6 = this._$AH;
let s5, e8 = 0;
for (const h4 of t6) e8 === i6.length ? i6.push(s5 = new _k(this.O(c3()), this.O(c3()), this, this.options)) : s5 = i6[e8], s5._$AI(h4), e8++;
e8 < i6.length && (this._$AR(s5 && s5._$AB.nextSibling, e8), i6.length = e8);
}
_$AR(t6 = this._$AA.nextSibling, s5) {
for (this._$AP?.(false, true, s5); t6 !== this._$AB; ) {
const s6 = i3(t6).nextSibling;
i3(t6).remove(), t6 = s6;
}
}
setConnected(t6) {
void 0 === this._$AM && (this._$Cv = t6, this._$AP?.(t6));
}
};
var H = class {
get tagName() {
return this.element.tagName;
}
get _$AU() {
return this._$AM._$AU;
}
constructor(t6, i6, s5, e8, h4) {
this.type = 1, this._$AH = A, this._$AN = void 0, this.element = t6, this.name = i6, this._$AM = e8, this.options = h4, s5.length > 2 || "" !== s5[0] || "" !== s5[1] ? (this._$AH = Array(s5.length - 1).fill(new String()), this.strings = s5) : this._$AH = A;
}
_$AI(t6, i6 = this, s5, e8) {
const h4 = this.strings;
let o8 = false;
if (void 0 === h4) t6 = M(this, t6, i6, 0), o8 = !a2(t6) || t6 !== this._$AH && t6 !== E, o8 && (this._$AH = t6);
else {
const e9 = t6;
let n7, r6;
for (t6 = h4[0], n7 = 0; n7 < h4.length - 1; n7++) r6 = M(this, e9[s5 + n7], i6, n7), r6 === E && (r6 = this._$AH[n7]), o8 ||= !a2(r6) || r6 !== this._$AH[n7], r6 === A ? t6 = A : t6 !== A && (t6 += (r6 ?? "") + h4[n7 + 1]), this._$AH[n7] = r6;
}
o8 && !e8 && this.j(t6);
}
j(t6) {
t6 === A ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t6 ?? "");
}
};
var I = class extends H {
constructor() {
super(...arguments), this.type = 3;
}
j(t6) {
this.element[this.name] = t6 === A ? void 0 : t6;
}
};
var L = class extends H {
constructor() {
super(...arguments), this.type = 4;
}
j(t6) {
this.element.toggleAttribute(this.name, !!t6 && t6 !== A);
}
};
var z = class extends H {
constructor(t6, i6, s5, e8, h4) {
super(t6, i6, s5, e8, h4), this.type = 5;
}
_$AI(t6, i6 = this) {
if ((t6 = M(this, t6, i6, 0) ?? A) === E) return;
const s5 = this._$AH, e8 = t6 === A && s5 !== A || t6.capture !== s5.capture || t6.once !== s5.once || t6.passive !== s5.passive, h4 = t6 !== A && (s5 === A || e8);
e8 && this.element.removeEventListener(this.name, this, s5), h4 && this.element.addEventListener(this.name, this, t6), this._$AH = t6;
}
handleEvent(t6) {
"function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t6) : this._$AH.handleEvent(t6);
}
};
var Z = class {
constructor(t6, i6, s5) {
this.element = t6, this.type = 6, this._$AN = void 0, this._$AM = i6, this.options = s5;
}
get _$AU() {
return this._$AM._$AU;
}
_$AI(t6) {
M(this, t6);
}
};
var j = { M: h2, P: o3, A: n3, C: 1, L: N, R, D: d2, V: M, I: k, H, N: L, U: z, B: I, F: Z };
var B = t2.litHtmlPolyfillSupport;
B?.(S2, k), (t2.litHtmlVersions ??= []).push("3.3.2");
var D = (t6, i6, s5) => {
const e8 = s5?.renderBefore ?? i6;
let h4 = e8._$litPart$;
if (void 0 === h4) {
const t7 = s5?.renderBefore ?? null;
e8._$litPart$ = h4 = new k(i6.insertBefore(c3(), t7), t7, void 0, s5 ?? {});
}
return h4._$AI(t6), h4;
};
// node_modules/lit-element/lit-element.js
var s3 = globalThis;
var i4 = class extends y {
constructor() {
super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0;
}
createRenderRoot() {
const t6 = super.createRenderRoot();
return this.renderOptions.renderBefore ??= t6.firstChild, t6;
}
update(t6) {
const r6 = this.render();
this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t6), this._$Do = D(r6, this.renderRoot, this.renderOptions);
}
connectedCallback() {
super.connectedCallback(), this._$Do?.setConnected(true);
}
disconnectedCallback() {
super.disconnectedCallback(), this._$Do?.setConnected(false);
}
render() {
return E;
}
};
i4._$litElement$ = true, i4["finalized"] = true, s3.litElementHydrateSupport?.({ LitElement: i4 });
var o4 = s3.litElementPolyfillSupport;
o4?.({ LitElement: i4 });
(s3.litElementVersions ??= []).push("4.2.2");
// node_modules/lit-html/directive-helpers.js
var { I: t3 } = j;
var r4 = (o8) => void 0 === o8.strings;
// node_modules/lit-html/directive.js
var t4 = { ATTRIBUTE: 1, CHILD: 2, PROPERTY: 3, BOOLEAN_ATTRIBUTE: 4, EVENT: 5, ELEMENT: 6 };
var e4 = (t6) => (...e8) => ({ _$litDirective$: t6, values: e8 });
var i5 = class {
constructor(t6) {
}
get _$AU() {
return this._$AM._$AU;
}
_$AT(t6, e8, i6) {
this._$Ct = t6, this._$AM = e8, this._$Ci = i6;
}
_$AS(t6, e8) {
return this.update(t6, e8);
}
update(t6, e8) {
return this.render(...e8);
}
};
// node_modules/lit-html/async-directive.js
var s4 = (i6, t6) => {
const e8 = i6._$AN;
if (void 0 === e8) return false;
for (const i7 of e8) i7._$AO?.(t6, false), s4(i7, t6);
return true;
};
var o5 = (i6) => {
let t6, e8;
do {
if (void 0 === (t6 = i6._$AM)) break;
e8 = t6._$AN, e8.delete(i6), i6 = t6;
} while (0 === e8?.size);
};
var r5 = (i6) => {
for (let t6; t6 = i6._$AM; i6 = t6) {
let e8 = t6._$AN;
if (void 0 === e8) t6._$AN = e8 = /* @__PURE__ */ new Set();
else if (e8.has(i6)) break;
e8.add(i6), c4(t6);
}
};
function h3(i6) {
void 0 !== this._$AN ? (o5(this), this._$AM = i6, r5(this)) : this._$AM = i6;
}
function n4(i6, t6 = false, e8 = 0) {
const r6 = this._$AH, h4 = this._$AN;
if (void 0 !== h4 && 0 !== h4.size) if (t6) if (Array.isArray(r6)) for (let i7 = e8; i7 < r6.length; i7++) s4(r6[i7], false), o5(r6[i7]);
else null != r6 && (s4(r6, false), o5(r6));
else s4(this, i6);
}
var c4 = (i6) => {
i6.type == t4.CHILD && (i6._$AP ??= n4, i6._$AQ ??= h3);
};
var f3 = class extends i5 {
constructor() {
super(...arguments), this._$AN = void 0;
}
_$AT(i6, t6, e8) {
super._$AT(i6, t6, e8), r5(this), this.isConnected = i6._$AU;
}
_$AO(i6, t6 = true) {
i6 !== this.isConnected && (this.isConnected = i6, i6 ? this.reconnected?.() : this.disconnected?.()), t6 && (s4(this, i6), o5(this));
}
setValue(t6) {
if (r4(this._$Ct)) this._$Ct._$AI(t6, this);
else {
const i6 = [...this._$Ct._$AH];
i6[this._$Ci] = t6, this._$Ct._$AI(i6, this, 0);
}
}
disconnected() {
}
reconnected() {
}
};
// node_modules/lit-html/directives/ref.js
var o6 = /* @__PURE__ */ new WeakMap();
var n5 = e4(class extends f3 {
render(i6) {
return A;
}
update(i6, [s5]) {
const e8 = s5 !== this.G;
return e8 && void 0 !== this.G && this.rt(void 0), (e8 || this.lt !== this.ct) && (this.G = s5, this.ht = i6.options?.host, this.rt(this.ct = i6.element)), A;
}
rt(t6) {
if (this.isConnected || (t6 = void 0), "function" == typeof this.G) {
const i6 = this.ht ?? globalThis;
let s5 = o6.get(i6);
void 0 === s5 && (s5 = /* @__PURE__ */ new WeakMap(), o6.set(i6, s5)), void 0 !== s5.get(this.G) && this.G.call(this.ht, void 0), s5.set(this.G, t6), void 0 !== t6 && this.G.call(this.ht, t6);
} else this.G.value = t6;
}
get lt() {
return "function" == typeof this.G ? o6.get(this.ht ?? globalThis)?.get(this.G) : this.G?.value;
}
disconnected() {
this.lt === this.ct && this.rt(void 0);
}
reconnected() {
this.rt(this.ct);
}
});
// ../mini-lit/dist/mini.js
function fc(renderFn) {
return (props) => renderFn(props || {});
}
// node_modules/lit-html/directives/unsafe-html.js
var e6 = class extends i5 {
constructor(i6) {
if (super(i6), this.it = A, i6.type !== t4.CHILD) throw Error(this.constructor.directiveName + "() can only be used in child bindings");
}
render(r6) {
if (r6 === A || null == r6) return this._t = void 0, this.it = r6;
if (r6 === E) return r6;
if ("string" != typeof r6) throw Error(this.constructor.directiveName + "() called with a non-string value");
if (r6 === this.it) return this._t;
this.it = r6;
const s5 = [r6];
return s5.raw = s5, this._t = { _$litType$: this.constructor.resultType, strings: s5, values: [] };
}
};
e6.directiveName = "unsafeHTML", e6.resultType = 1;
var o7 = e4(e6);
// ../mini-lit/node_modules/lucide/dist/esm/defaultAttributes.js
var defaultAttributes = {
xmlns: "http://www.w3.org/2000/svg",
width: 24,
height: 24,
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
"stroke-width": 2,
"stroke-linecap": "round",
"stroke-linejoin": "round"
};
// ../mini-lit/node_modules/lucide/dist/esm/createElement.js
var createSVGElement = ([tag, attrs, children]) => {
const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
Object.keys(attrs).forEach((name) => {
element.setAttribute(name, String(attrs[name]));
});
if (children?.length) {
children.forEach((child) => {
const childElement = createSVGElement(child);
element.appendChild(childElement);
});
}
return element;
};
var createElement = (iconNode, customAttrs = {}) => {
const tag = "svg";
const attrs = {
...defaultAttributes,
...customAttrs
};
return createSVGElement([tag, attrs, iconNode]);
};
// ../mini-lit/dist/icons.js
var sizeClasses = {
xs: "w-3 h-3",
sm: "w-4 h-4",
md: "w-5 h-5",
lg: "w-6 h-6",
xl: "w-8 h-8"
};
function icon(lucideIcon, size = "md", className) {
return b2`${o7(iconDOM(lucideIcon, size, className).outerHTML)}`;
}
function iconDOM(lucideIcon, size = "md", className) {
const element = createElement(lucideIcon, {
class: sizeClasses[size] + (className ? " " + className : "")
});
return element;
}
// ../mini-lit/dist/Button.js
var Button = fc(({ variant = "default", size = "md", disabled = false, type = "button", loading = false, onClick, title, className = "", children }) => {
const sizeClasses2 = {
sm: "h-8 rounded-md px-3 text-xs",
md: "h-9 rounded-md px-4 text-sm",
lg: "h-10 rounded-md px-8 text-sm",
icon: "size-8 rounded-md"
};
const variantClasses = {
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90",
outline: "border border-input bg-background text-foreground shadow-xs hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
ghost: "text-foreground hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline"
};
const baseClasses = "inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-all cursor-pointer disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive";
const gapClass = size === "icon" ? "" : "gap-2";
const paddingAdjustClass = size === "icon" ? "" : "has-[>svg]:px-2.5";
const variantClass = variantClasses[variant] || variantClasses.default;
const handleClick = (e8) => {
if (disabled || loading) {
e8.preventDefault();
e8.stopPropagation();
return;
}
onClick?.(e8);
};
return b2`
`;
});
// node_modules/lucide/dist/esm/icons/arrow-left.js
var ArrowLeft = [
["path", { d: "m12 19-7-7 7-7" }],
["path", { d: "M19 12H5" }]
];
// node_modules/lucide/dist/esm/icons/download.js
var Download = [
["path", { d: "M12 15V3" }],
["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }],
["path", { d: "m7 10 5 5 5-5" }]
];
// node_modules/@lit/reactive-element/decorators/custom-element.js
var t5 = (t6) => (e8, o8) => {
void 0 !== o8 ? o8.addInitializer(() => {
customElements.define(t6, e8);
}) : customElements.define(t6, e8);
};
// node_modules/three/build/three.core.js
var REVISION = "180";
var CullFaceNone = 0;
var CullFaceBack = 1;
var CullFaceFront = 2;
var PCFShadowMap = 1;
var PCFSoftShadowMap = 2;
var VSMShadowMap = 3;
var FrontSide = 0;
var BackSide = 1;
var DoubleSide = 2;
var NoBlending = 0;
var NormalBlending = 1;
var AdditiveBlending = 2;
var SubtractiveBlending = 3;
var MultiplyBlending = 4;
var CustomBlending = 5;
var AddEquation = 100;
var SubtractEquation = 101;
var ReverseSubtractEquation = 102;
var MinEquation = 103;
var MaxEquation = 104;
var ZeroFactor = 200;
var OneFactor = 201;
var SrcColorFactor = 202;
var OneMinusSrcColorFactor = 203;
var SrcAlphaFactor = 204;
var OneMinusSrcAlphaFactor = 205;
var DstAlphaFactor = 206;
var OneMinusDstAlphaFactor = 207;
var DstColorFactor = 208;
var OneMinusDstColorFactor = 209;
var SrcAlphaSaturateFactor = 210;
var ConstantColorFactor = 211;
var OneMinusConstantColorFactor = 212;
var ConstantAlphaFactor = 213;
var OneMinusConstantAlphaFactor = 214;
var NeverDepth = 0;
var AlwaysDepth = 1;
var LessDepth = 2;
var LessEqualDepth = 3;
var EqualDepth = 4;
var GreaterEqualDepth = 5;
var GreaterDepth = 6;
var NotEqualDepth = 7;
var MultiplyOperation = 0;
var MixOperation = 1;
var AddOperation = 2;
var NoToneMapping = 0;
var LinearToneMapping = 1;
var ReinhardToneMapping = 2;
var CineonToneMapping = 3;
var ACESFilmicToneMapping = 4;
var CustomToneMapping = 5;
var AgXToneMapping = 6;
var NeutralToneMapping = 7;
var UVMapping = 300;
var CubeReflectionMapping = 301;
var CubeRefractionMapping = 302;
var EquirectangularReflectionMapping = 303;
var EquirectangularRefractionMapping = 304;
var CubeUVReflectionMapping = 306;
var RepeatWrapping = 1e3;
var ClampToEdgeWrapping = 1001;
var MirroredRepeatWrapping = 1002;
var NearestFilter = 1003;
var NearestMipmapNearestFilter = 1004;
var NearestMipmapLinearFilter = 1005;
var LinearFilter = 1006;
var LinearMipmapNearestFilter = 1007;
var LinearMipmapLinearFilter = 1008;
var UnsignedByteType = 1009;
var ByteType = 1010;
var ShortType = 1011;
var UnsignedShortType = 1012;
var IntType = 1013;
var UnsignedIntType = 1014;
var FloatType = 1015;
var HalfFloatType = 1016;
var UnsignedShort4444Type = 1017;
var UnsignedShort5551Type = 1018;
var UnsignedInt248Type = 1020;
var UnsignedInt5999Type = 35902;
var UnsignedInt101111Type = 35899;
var AlphaFormat = 1021;
var RGBFormat = 1022;
var RGBAFormat = 1023;
var DepthFormat = 1026;
var DepthStencilFormat = 1027;
var RedFormat = 1028;
var RedIntegerFormat = 1029;
var RGFormat = 1030;
var RGIntegerFormat = 1031;
var RGBAIntegerFormat = 1033;
var RGB_S3TC_DXT1_Format = 33776;
var RGBA_S3TC_DXT1_Format = 33777;
var RGBA_S3TC_DXT3_Format = 33778;
var RGBA_S3TC_DXT5_Format = 33779;
var RGB_PVRTC_4BPPV1_Format = 35840;
var RGB_PVRTC_2BPPV1_Format = 35841;
var RGBA_PVRTC_4BPPV1_Format = 35842;
var RGBA_PVRTC_2BPPV1_Format = 35843;
var RGB_ETC1_Format = 36196;
var RGB_ETC2_Format = 37492;
var RGBA_ETC2_EAC_Format = 37496;
var RGBA_ASTC_4x4_Format = 37808;
var RGBA_ASTC_5x4_Format = 37809;
var RGBA_ASTC_5x5_Format = 37810;
var RGBA_ASTC_6x5_Format = 37811;
var RGBA_ASTC_6x6_Format = 37812;
var RGBA_ASTC_8x5_Format = 37813;
var RGBA_ASTC_8x6_Format = 37814;
var RGBA_ASTC_8x8_Format = 37815;
var RGBA_ASTC_10x5_Format = 37816;
var RGBA_ASTC_10x6_Format = 37817;
var RGBA_ASTC_10x8_Format = 37818;
var RGBA_ASTC_10x10_Format = 37819;
var RGBA_ASTC_12x10_Format = 37820;
var RGBA_ASTC_12x12_Format = 37821;
var RGBA_BPTC_Format = 36492;
var RGB_BPTC_SIGNED_Format = 36494;
var RGB_BPTC_UNSIGNED_Format = 36495;
var RED_RGTC1_Format = 36283;
var SIGNED_RED_RGTC1_Format = 36284;
var RED_GREEN_RGTC2_Format = 36285;
var SIGNED_RED_GREEN_RGTC2_Format = 36286;
var InterpolateDiscrete = 2300;
var InterpolateLinear = 2301;
var InterpolateSmooth = 2302;
var ZeroCurvatureEnding = 2400;
var ZeroSlopeEnding = 2401;
var WrapAroundEnding = 2402;
var BasicDepthPacking = 3200;
var RGBADepthPacking = 3201;
var TangentSpaceNormalMap = 0;
var ObjectSpaceNormalMap = 1;
var NoColorSpace = "";
var SRGBColorSpace = "srgb";
var LinearSRGBColorSpace = "srgb-linear";
var LinearTransfer = "linear";
var SRGBTransfer = "srgb";
var KeepStencilOp = 7680;
var AlwaysStencilFunc = 519;
var NeverCompare = 512;
var LessCompare = 513;
var EqualCompare = 514;
var LessEqualCompare = 515;
var GreaterCompare = 516;
var NotEqualCompare = 517;
var GreaterEqualCompare = 518;
var AlwaysCompare = 519;
var StaticDrawUsage = 35044;
var GLSL3 = "300 es";
var WebGLCoordinateSystem = 2e3;
var WebGPUCoordinateSystem = 2001;
var EventDispatcher = class {
/**
* Adds the given event listener to the given event type.
*
* @param {string} type - The type of event to listen to.
* @param {Function} listener - The function that gets called when the event is fired.
*/
addEventListener(type, listener) {
if (this._listeners === void 0) this._listeners = {};
const listeners = this._listeners;
if (listeners[type] === void 0) {
listeners[type] = [];
}
if (listeners[type].indexOf(listener) === -1) {
listeners[type].push(listener);
}
}
/**
* Returns `true` if the given event listener has been added to the given event type.
*
* @param {string} type - The type of event.
* @param {Function} listener - The listener to check.
* @return {boolean} Whether the given event listener has been added to the given event type.
*/
hasEventListener(type, listener) {
const listeners = this._listeners;
if (listeners === void 0) return false;
return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1;
}
/**
* Removes the given event listener from the given event type.
*
* @param {string} type - The type of event.
* @param {Function} listener - The listener to remove.
*/
removeEventListener(type, listener) {
const listeners = this._listeners;
if (listeners === void 0) return;
const listenerArray = listeners[type];
if (listenerArray !== void 0) {
const index = listenerArray.indexOf(listener);
if (index !== -1) {
listenerArray.splice(index, 1);
}
}
}
/**
* Dispatches an event object.
*
* @param {Object} event - The event that gets fired.
*/
dispatchEvent(event) {
const listeners = this._listeners;
if (listeners === void 0) return;
const listenerArray = listeners[event.type];
if (listenerArray !== void 0) {
event.target = this;
const array = listenerArray.slice(0);
for (let i6 = 0, l3 = array.length; i6 < l3; i6++) {
array[i6].call(this, event);
}
event.target = null;
}
}
};
var _lut = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"];
var DEG2RAD = Math.PI / 180;
var RAD2DEG = 180 / Math.PI;
function generateUUID() {
const d0 = Math.random() * 4294967295 | 0;
const d1 = Math.random() * 4294967295 | 0;
const d22 = Math.random() * 4294967295 | 0;
const d3 = Math.random() * 4294967295 | 0;
const uuid = _lut[d0 & 255] + _lut[d0 >> 8 & 255] + _lut[d0 >> 16 & 255] + _lut[d0 >> 24 & 255] + "-" + _lut[d1 & 255] + _lut[d1 >> 8 & 255] + "-" + _lut[d1 >> 16 & 15 | 64] + _lut[d1 >> 24 & 255] + "-" + _lut[d22 & 63 | 128] + _lut[d22 >> 8 & 255] + "-" + _lut[d22 >> 16 & 255] + _lut[d22 >> 24 & 255] + _lut[d3 & 255] + _lut[d3 >> 8 & 255] + _lut[d3 >> 16 & 255] + _lut[d3 >> 24 & 255];
return uuid.toLowerCase();
}
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
function euclideanModulo(n7, m2) {
return (n7 % m2 + m2) % m2;
}
function lerp(x2, y3, t6) {
return (1 - t6) * x2 + t6 * y3;
}
function denormalize(value, array) {
switch (array.constructor) {
case Float32Array:
return value;
case Uint32Array:
return value / 4294967295;
case Uint16Array:
return value / 65535;
case Uint8Array:
return value / 255;
case Int32Array:
return Math.max(value / 2147483647, -1);
case Int16Array:
return Math.max(value / 32767, -1);
case Int8Array:
return Math.max(value / 127, -1);
default:
throw new Error("Invalid component type.");
}
}
function normalize(value, array) {
switch (array.constructor) {
case Float32Array:
return value;
case Uint32Array:
return Math.round(value * 4294967295);
case Uint16Array:
return Math.round(value * 65535);
case Uint8Array:
return Math.round(value * 255);
case Int32Array:
return Math.round(value * 2147483647);
case Int16Array:
return Math.round(value * 32767);
case Int8Array:
return Math.round(value * 127);
default:
throw new Error("Invalid component type.");
}
}
var Vector2 = class _Vector2 {
/**
* Constructs a new 2D vector.
*
* @param {number} [x=0] - The x value of this vector.
* @param {number} [y=0] - The y value of this vector.
*/
constructor(x2 = 0, y3 = 0) {
_Vector2.prototype.isVector2 = true;
this.x = x2;
this.y = y3;
}
/**
* Alias for {@link Vector2#x}.
*
* @type {number}
*/
get width() {
return this.x;
}
set width(value) {
this.x = value;
}
/**
* Alias for {@link Vector2#y}.
*
* @type {number}
*/
get height() {
return this.y;
}
set height(value) {
this.y = value;
}
/**
* Sets the vector components.
*
* @param {number} x - The value of the x component.
* @param {number} y - The value of the y component.
* @return {Vector2} A reference to this vector.
*/
set(x2, y3) {
this.x = x2;
this.y = y3;
return this;
}
/**
* Sets the vector components to the same value.
*
* @param {number} scalar - The value to set for all vector components.
* @return {Vector2} A reference to this vector.
*/
setScalar(scalar) {
this.x = scalar;
this.y = scalar;
return this;
}
/**
* Sets the vector's x component to the given value
*
* @param {number} x - The value to set.
* @return {Vector2} A reference to this vector.
*/
setX(x2) {
this.x = x2;
return this;
}
/**
* Sets the vector's y component to the given value
*
* @param {number} y - The value to set.
* @return {Vector2} A reference to this vector.
*/
setY(y3) {
this.y = y3;
return this;
}
/**
* Allows to set a vector component with an index.
*
* @param {number} index - The component index. `0` equals to x, `1` equals to y.
* @param {number} value - The value to set.
* @return {Vector2} A reference to this vector.
*/
setComponent(index, value) {
switch (index) {
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
default:
throw new Error("index is out of range: " + index);
}
return this;
}
/**
* Returns the value of the vector component which matches the given index.
*
* @param {number} index - The component index. `0` equals to x, `1` equals to y.
* @return {number} A vector component value.
*/
getComponent(index) {
switch (index) {
case 0:
return this.x;
case 1:
return this.y;
default:
throw new Error("index is out of range: " + index);
}
}
/**
* Returns a new vector with copied values from this instance.
*
* @return {Vector2} A clone of this instance.
*/
clone() {
return new this.constructor(this.x, this.y);
}
/**
* Copies the values of the given vector to this instance.
*
* @param {Vector2} v - The vector to copy.
* @return {Vector2} A reference to this vector.
*/
copy(v2) {
this.x = v2.x;
this.y = v2.y;
return this;
}
/**
* Adds the given vector to this instance.
*
* @param {Vector2} v - The vector to add.
* @return {Vector2} A reference to this vector.
*/
add(v2) {
this.x += v2.x;
this.y += v2.y;
return this;
}
/**
* Adds the given scalar value to all components of this instance.
*
* @param {number} s - The scalar to add.
* @return {Vector2} A reference to this vector.
*/
addScalar(s5) {
this.x += s5;
this.y += s5;
return this;
}
/**
* Adds the given vectors and stores the result in this instance.
*
* @param {Vector2} a - The first vector.
* @param {Vector2} b - The second vector.
* @return {Vector2} A reference to this vector.
*/
addVectors(a3, b3) {
this.x = a3.x + b3.x;
this.y = a3.y + b3.y;
return this;
}
/**
* Adds the given vector scaled by the given factor to this instance.
*
* @param {Vector2} v - The vector.
* @param {number} s - The factor that scales `v`.
* @return {Vector2} A reference to this vector.
*/
addScaledVector(v2, s5) {
this.x += v2.x * s5;
this.y += v2.y * s5;
return this;
}
/**
* Subtracts the given vector from this instance.
*
* @param {Vector2} v - The vector to subtract.
* @return {Vector2} A reference to this vector.
*/
sub(v2) {
this.x -= v2.x;
this.y -= v2.y;
return this;
}
/**
* Subtracts the given scalar value from all components of this instance.
*
* @param {number} s - The scalar to subtract.
* @return {Vector2} A reference to this vector.
*/
subScalar(s5) {
this.x -= s5;
this.y -= s5;
return this;
}
/**
* Subtracts the given vectors and stores the result in this instance.
*
* @param {Vector2} a - The first vector.
* @param {Vector2} b - The second vector.
* @return {Vector2} A reference to this vector.
*/
subVectors(a3, b3) {
this.x = a3.x - b3.x;
this.y = a3.y - b3.y;
return this;
}
/**
* Multiplies the given vector with this instance.
*
* @param {Vector2} v - The vector to multiply.
* @return {Vector2} A reference to this vector.
*/
multiply(v2) {
this.x *= v2.x;
this.y *= v2.y;
return this;
}
/**
* Multiplies the given scalar value with all components of this instance.
*
* @param {number} scalar - The scalar to multiply.
* @return {Vector2} A reference to this vector.
*/
multiplyScalar(scalar) {
this.x *= scalar;
this.y *= scalar;
return this;
}
/**
* Divides this instance by the given vector.
*
* @param {Vector2} v - The vector to divide.
* @return {Vector2} A reference to this vector.
*/
divide(v2) {
this.x /= v2.x;
this.y /= v2.y;
return this;
}
/**
* Divides this vector by the given scalar.
*
* @param {number} scalar - The scalar to divide.
* @return {Vector2} A reference to this vector.
*/
divideScalar(scalar) {
return this.multiplyScalar(1 / scalar);
}
/**
* Multiplies this vector (with an implicit 1 as the 3rd component) by
* the given 3x3 matrix.
*
* @param {Matrix3} m - The matrix to apply.
* @return {Vector2} A reference to this vector.
*/
applyMatrix3(m2) {
const x2 = this.x, y3 = this.y;
const e8 = m2.elements;
this.x = e8[0] * x2 + e8[3] * y3 + e8[6];
this.y = e8[1] * x2 + e8[4] * y3 + e8[7];
return this;
}
/**
* If this vector's x or y value is greater than the given vector's x or y
* value, replace that value with the corresponding min value.
*
* @param {Vector2} v - The vector.
* @return {Vector2} A reference to this vector.
*/
min(v2) {
this.x = Math.min(this.x, v2.x);
this.y = Math.min(this.y, v2.y);
return this;
}
/**
* If this vector's x or y value is less than the given vector's x or y
* value, replace that value with the corresponding max value.
*
* @param {Vector2} v - The vector.
* @return {Vector2} A reference to this vector.
*/
max(v2) {
this.x = Math.max(this.x, v2.x);
this.y = Math.max(this.y, v2.y);
return this;
}
/**
* If this vector's x or y value is greater than the max vector's x or y
* value, it is replaced by the corresponding value.
* If this vector's x or y value is less than the min vector's x or y value,
* it is replaced by the corresponding value.
*
* @param {Vector2} min - The minimum x and y values.
* @param {Vector2} max - The maximum x and y values in the desired range.
* @return {Vector2} A reference to this vector.
*/
clamp(min, max) {
this.x = clamp(this.x, min.x, max.x);
this.y = clamp(this.y, min.y, max.y);
return this;
}
/**
* If this vector's x or y values are greater than the max value, they are
* replaced by the max value.
* If this vector's x or y values are less than the min value, they are
* replaced by the min value.
*
* @param {number} minVal - The minimum value the components will be clamped to.
* @param {number} maxVal - The maximum value the components will be clamped to.
* @return {Vector2} A reference to this vector.
*/
clampScalar(minVal, maxVal) {
this.x = clamp(this.x, minVal, maxVal);
this.y = clamp(this.y, minVal, maxVal);
return this;
}
/**
* If this vector's length is greater than the max value, it is replaced by
* the max value.
* If this vector's length is less than the min value, it is replaced by the
* min value.
*
* @param {number} min - The minimum value the vector length will be clamped to.
* @param {number} max - The maximum value the vector length will be clamped to.
* @return {Vector2} A reference to this vector.
*/
clampLength(min, max) {
const length = this.length();
return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max));
}
/**
* The components of this vector are rounded down to the nearest integer value.
*
* @return {Vector2} A reference to this vector.
*/
floor() {
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
return this;
}
/**
* The components of this vector are rounded up to the nearest integer value.
*
* @return {Vector2} A reference to this vector.
*/
ceil() {
this.x = Math.ceil(this.x);
this.y = Math.ceil(this.y);
return this;
}
/**
* The components of this vector are rounded to the nearest integer value
*
* @return {Vector2} A reference to this vector.
*/
round() {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
}
/**
* The components of this vector are rounded towards zero (up if negative,
* down if positive) to an integer value.
*
* @return {Vector2} A reference to this vector.
*/
roundToZero() {
this.x = Math.trunc(this.x);
this.y = Math.trunc(this.y);
return this;
}
/**
* Inverts this vector - i.e. sets x = -x and y = -y.
*
* @return {Vector2} A reference to this vector.
*/
negate() {
this.x = -this.x;
this.y = -this.y;
return this;
}
/**
* Calculates the dot product of the given vector with this instance.
*
* @param {Vector2} v - The vector to compute the dot product with.
* @return {number} The result of the dot product.
*/
dot(v2) {
return this.x * v2.x + this.y * v2.y;
}
/**
* Calculates the cross product of the given vector with this instance.
*
* @param {Vector2} v - The vector to compute the cross product with.
* @return {number} The result of the cross product.
*/
cross(v2) {
return this.x * v2.y - this.y * v2.x;
}
/**
* Computes the square of the Euclidean length (straight-line length) from
* (0, 0) to (x, y). If you are comparing the lengths of vectors, you should
* compare the length squared instead as it is slightly more efficient to calculate.
*
* @return {number} The square length of this vector.
*/
lengthSq() {
return this.x * this.x + this.y * this.y;
}
/**
* Computes the Euclidean length (straight-line length) from (0, 0) to (x, y).
*
* @return {number} The length of this vector.
*/
length() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
* Computes the Manhattan length of this vector.
*
* @return {number} The length of this vector.
*/
manhattanLength() {
return Math.abs(this.x) + Math.abs(this.y);
}
/**
* Converts this vector to a unit vector - that is, sets it equal to a vector
* with the same direction as this one, but with a vector length of `1`.
*
* @return {Vector2} A reference to this vector.
*/
normalize() {
return this.divideScalar(this.length() || 1);
}
/**
* Computes the angle in radians of this vector with respect to the positive x-axis.
*
* @return {number} The angle in radians.
*/
angle() {
const angle = Math.atan2(-this.y, -this.x) + Math.PI;
return angle;
}
/**
* Returns the angle between the given vector and this instance in radians.
*
* @param {Vector2} v - The vector to compute the angle with.
* @return {number} The angle in radians.
*/
angleTo(v2) {
const denominator = Math.sqrt(this.lengthSq() * v2.lengthSq());
if (denominator === 0) return Math.PI / 2;
const theta = this.dot(v2) / denominator;
return Math.acos(clamp(theta, -1, 1));
}
/**
* Computes the distance from the given vector to this instance.
*
* @param {Vector2} v - The vector to compute the distance to.
* @return {number} The distance.
*/
distanceTo(v2) {
return Math.sqrt(this.distanceToSquared(v2));
}
/**
* Computes the squared distance from the given vector to this instance.
* If you are just comparing the distance with another distance, you should compare
* the distance squared instead as it is slightly more efficient to calculate.
*
* @param {Vector2} v - The vector to compute the squared distance to.
* @return {number} The squared distance.
*/
distanceToSquared(v2) {
const dx = this.x - v2.x, dy = this.y - v2.y;
return dx * dx + dy * dy;
}
/**
* Computes the Manhattan distance from the given vector to this instance.
*
* @param {Vector2} v - The vector to compute the Manhattan distance to.
* @return {number} The Manhattan distance.
*/
manhattanDistanceTo(v2) {
return Math.abs(this.x - v2.x) + Math.abs(this.y - v2.y);
}
/**
* Sets this vector to a vector with the same direction as this one, but
* with the specified length.
*
* @param {number} length - The new length of this vector.
* @return {Vector2} A reference to this vector.
*/
setLength(length) {
return this.normalize().multiplyScalar(length);
}
/**
* Linearly interpolates between the given vector and this instance, where
* alpha is the percent distance along the line - alpha = 0 will be this
* vector, and alpha = 1 will be the given one.
*
* @param {Vector2} v - The vector to interpolate towards.
* @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
* @return {Vector2} A reference to this vector.
*/
lerp(v2, alpha) {
this.x += (v2.x - this.x) * alpha;
this.y += (v2.y - this.y) * alpha;
return this;
}
/**
* Linearly interpolates between the given vectors, where alpha is the percent
* distance along the line - alpha = 0 will be first vector, and alpha = 1 will
* be the second one. The result is stored in this instance.
*
* @param {Vector2} v1 - The first vector.
* @param {Vector2} v2 - The second vector.
* @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
* @return {Vector2} A reference to this vector.
*/
lerpVectors(v1, v2, alpha) {
this.x = v1.x + (v2.x - v1.x) * alpha;
this.y = v1.y + (v2.y - v1.y) * alpha;
return this;
}
/**
* Returns `true` if this vector is equal with the given one.
*
* @param {Vector2} v - The vector to test for equality.
* @return {boolean} Whether this vector is equal with the given one.
*/
equals(v2) {
return v2.x === this.x && v2.y === this.y;
}
/**
* Sets this vector's x value to be `array[ offset ]` and y
* value to be `array[ offset + 1 ]`.
*
* @param {Array} array - An array holding the vector component values.
* @param {number} [offset=0] - The offset into the array.
* @return {Vector2} A reference to this vector.
*/
fromArray(array, offset = 0) {
this.x = array[offset];
this.y = array[offset + 1];
return this;
}
/**
* Writes the components of this vector to the given array. If no array is provided,
* the method returns a new instance.
*
* @param {Array} [array=[]] - The target array holding the vector components.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Array} The vector components.
*/
toArray(array = [], offset = 0) {
array[offset] = this.x;
array[offset + 1] = this.y;
return array;
}
/**
* Sets the components of this vector from the given buffer attribute.
*
* @param {BufferAttribute} attribute - The buffer attribute holding vector data.
* @param {number} index - The index into the attribute.
* @return {Vector2} A reference to this vector.
*/
fromBufferAttribute(attribute, index) {
this.x = attribute.getX(index);
this.y = attribute.getY(index);
return this;
}
/**
* Rotates this vector around the given center by the given angle.
*
* @param {Vector2} center - The point around which to rotate.
* @param {number} angle - The angle to rotate, in radians.
* @return {Vector2} A reference to this vector.
*/
rotateAround(center, angle) {
const c5 = Math.cos(angle), s5 = Math.sin(angle);
const x2 = this.x - center.x;
const y3 = this.y - center.y;
this.x = x2 * c5 - y3 * s5 + center.x;
this.y = x2 * s5 + y3 * c5 + center.y;
return this;
}
/**
* Sets each component of this vector to a pseudo-random value between `0` and
* `1`, excluding `1`.
*
* @return {Vector2} A reference to this vector.
*/
random() {
this.x = Math.random();
this.y = Math.random();
return this;
}
*[Symbol.iterator]() {
yield this.x;
yield this.y;
}
};
var Quaternion = class {
/**
* Constructs a new quaternion.
*
* @param {number} [x=0] - The x value of this quaternion.
* @param {number} [y=0] - The y value of this quaternion.
* @param {number} [z=0] - The z value of this quaternion.
* @param {number} [w=1] - The w value of this quaternion.
*/
constructor(x2 = 0, y3 = 0, z2 = 0, w2 = 1) {
this.isQuaternion = true;
this._x = x2;
this._y = y3;
this._z = z2;
this._w = w2;
}
/**
* Interpolates between two quaternions via SLERP. This implementation assumes the
* quaternion data are managed in flat arrays.
*
* @param {Array} dst - The destination array.
* @param {number} dstOffset - An offset into the destination array.
* @param {Array} src0 - The source array of the first quaternion.
* @param {number} srcOffset0 - An offset into the first source array.
* @param {Array} src1 - The source array of the second quaternion.
* @param {number} srcOffset1 - An offset into the second source array.
* @param {number} t - The interpolation factor in the range `[0,1]`.
* @see {@link Quaternion#slerp}
*/
static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t6) {
let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w0 = src0[srcOffset0 + 3];
const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w1 = src1[srcOffset1 + 3];
if (t6 === 0) {
dst[dstOffset + 0] = x0;
dst[dstOffset + 1] = y0;
dst[dstOffset + 2] = z0;
dst[dstOffset + 3] = w0;
return;
}
if (t6 === 1) {
dst[dstOffset + 0] = x1;
dst[dstOffset + 1] = y1;
dst[dstOffset + 2] = z1;
dst[dstOffset + 3] = w1;
return;
}
if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {
let s5 = 1 - t6;
const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, dir = cos >= 0 ? 1 : -1, sqrSin = 1 - cos * cos;
if (sqrSin > Number.EPSILON) {
const sin = Math.sqrt(sqrSin), len = Math.atan2(sin, cos * dir);
s5 = Math.sin(s5 * len) / sin;
t6 = Math.sin(t6 * len) / sin;
}
const tDir = t6 * dir;
x0 = x0 * s5 + x1 * tDir;
y0 = y0 * s5 + y1 * tDir;
z0 = z0 * s5 + z1 * tDir;
w0 = w0 * s5 + w1 * tDir;
if (s5 === 1 - t6) {
const f4 = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);
x0 *= f4;
y0 *= f4;
z0 *= f4;
w0 *= f4;
}
}
dst[dstOffset] = x0;
dst[dstOffset + 1] = y0;
dst[dstOffset + 2] = z0;
dst[dstOffset + 3] = w0;
}
/**
* Multiplies two quaternions. This implementation assumes the quaternion data are managed
* in flat arrays.
*
* @param {Array} dst - The destination array.
* @param {number} dstOffset - An offset into the destination array.
* @param {Array} src0 - The source array of the first quaternion.
* @param {number} srcOffset0 - An offset into the first source array.
* @param {Array} src1 - The source array of the second quaternion.
* @param {number} srcOffset1 - An offset into the second source array.
* @return {Array} The destination array.
* @see {@link Quaternion#multiplyQuaternions}.
*/
static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {
const x0 = src0[srcOffset0];
const y0 = src0[srcOffset0 + 1];
const z0 = src0[srcOffset0 + 2];
const w0 = src0[srcOffset0 + 3];
const x1 = src1[srcOffset1];
const y1 = src1[srcOffset1 + 1];
const z1 = src1[srcOffset1 + 2];
const w1 = src1[srcOffset1 + 3];
dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
return dst;
}
/**
* The x value of this quaternion.
*
* @type {number}
* @default 0
*/
get x() {
return this._x;
}
set x(value) {
this._x = value;
this._onChangeCallback();
}
/**
* The y value of this quaternion.
*
* @type {number}
* @default 0
*/
get y() {
return this._y;
}
set y(value) {
this._y = value;
this._onChangeCallback();
}
/**
* The z value of this quaternion.
*
* @type {number}
* @default 0
*/
get z() {
return this._z;
}
set z(value) {
this._z = value;
this._onChangeCallback();
}
/**
* The w value of this quaternion.
*
* @type {number}
* @default 1
*/
get w() {
return this._w;
}
set w(value) {
this._w = value;
this._onChangeCallback();
}
/**
* Sets the quaternion components.
*
* @param {number} x - The x value of this quaternion.
* @param {number} y - The y value of this quaternion.
* @param {number} z - The z value of this quaternion.
* @param {number} w - The w value of this quaternion.
* @return {Quaternion} A reference to this quaternion.
*/
set(x2, y3, z2, w2) {
this._x = x2;
this._y = y3;
this._z = z2;
this._w = w2;
this._onChangeCallback();
return this;
}
/**
* Returns a new quaternion with copied values from this instance.
*
* @return {Quaternion} A clone of this instance.
*/
clone() {
return new this.constructor(this._x, this._y, this._z, this._w);
}
/**
* Copies the values of the given quaternion to this instance.
*
* @param {Quaternion} quaternion - The quaternion to copy.
* @return {Quaternion} A reference to this quaternion.
*/
copy(quaternion) {
this._x = quaternion.x;
this._y = quaternion.y;
this._z = quaternion.z;
this._w = quaternion.w;
this._onChangeCallback();
return this;
}
/**
* Sets this quaternion from the rotation specified by the given
* Euler angles.
*
* @param {Euler} euler - The Euler angles.
* @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
* @return {Quaternion} A reference to this quaternion.
*/
setFromEuler(euler, update = true) {
const x2 = euler._x, y3 = euler._y, z2 = euler._z, order = euler._order;
const cos = Math.cos;
const sin = Math.sin;
const c1 = cos(x2 / 2);
const c22 = cos(y3 / 2);
const c32 = cos(z2 / 2);
const s1 = sin(x2 / 2);
const s22 = sin(y3 / 2);
const s32 = sin(z2 / 2);
switch (order) {
case "XYZ":
this._x = s1 * c22 * c32 + c1 * s22 * s32;
this._y = c1 * s22 * c32 - s1 * c22 * s32;
this._z = c1 * c22 * s32 + s1 * s22 * c32;
this._w = c1 * c22 * c32 - s1 * s22 * s32;
break;
case "YXZ":
this._x = s1 * c22 * c32 + c1 * s22 * s32;
this._y = c1 * s22 * c32 - s1 * c22 * s32;
this._z = c1 * c22 * s32 - s1 * s22 * c32;
this._w = c1 * c22 * c32 + s1 * s22 * s32;
break;
case "ZXY":
this._x = s1 * c22 * c32 - c1 * s22 * s32;
this._y = c1 * s22 * c32 + s1 * c22 * s32;
this._z = c1 * c22 * s32 + s1 * s22 * c32;
this._w = c1 * c22 * c32 - s1 * s22 * s32;
break;
case "ZYX":
this._x = s1 * c22 * c32 - c1 * s22 * s32;
this._y = c1 * s22 * c32 + s1 * c22 * s32;
this._z = c1 * c22 * s32 - s1 * s22 * c32;
this._w = c1 * c22 * c32 + s1 * s22 * s32;
break;
case "YZX":
this._x = s1 * c22 * c32 + c1 * s22 * s32;
this._y = c1 * s22 * c32 + s1 * c22 * s32;
this._z = c1 * c22 * s32 - s1 * s22 * c32;
this._w = c1 * c22 * c32 - s1 * s22 * s32;
break;
case "XZY":
this._x = s1 * c22 * c32 - c1 * s22 * s32;
this._y = c1 * s22 * c32 - s1 * c22 * s32;
this._z = c1 * c22 * s32 + s1 * s22 * c32;
this._w = c1 * c22 * c32 + s1 * s22 * s32;
break;
default:
console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: " + order);
}
if (update === true) this._onChangeCallback();
return this;
}
/**
* Sets this quaternion from the given axis and angle.
*
* @param {Vector3} axis - The normalized axis.
* @param {number} angle - The angle in radians.
* @return {Quaternion} A reference to this quaternion.
*/
setFromAxisAngle(axis, angle) {
const halfAngle = angle / 2, s5 = Math.sin(halfAngle);
this._x = axis.x * s5;
this._y = axis.y * s5;
this._z = axis.z * s5;
this._w = Math.cos(halfAngle);
this._onChangeCallback();
return this;
}
/**
* Sets this quaternion from the given rotation matrix.
*
* @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
* @return {Quaternion} A reference to this quaternion.
*/
setFromRotationMatrix(m2) {
const te = m2.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10], trace = m11 + m22 + m33;
if (trace > 0) {
const s5 = 0.5 / Math.sqrt(trace + 1);
this._w = 0.25 / s5;
this._x = (m32 - m23) * s5;
this._y = (m13 - m31) * s5;
this._z = (m21 - m12) * s5;
} else if (m11 > m22 && m11 > m33) {
const s5 = 2 * Math.sqrt(1 + m11 - m22 - m33);
this._w = (m32 - m23) / s5;
this._x = 0.25 * s5;
this._y = (m12 + m21) / s5;
this._z = (m13 + m31) / s5;
} else if (m22 > m33) {
const s5 = 2 * Math.sqrt(1 + m22 - m11 - m33);
this._w = (m13 - m31) / s5;
this._x = (m12 + m21) / s5;
this._y = 0.25 * s5;
this._z = (m23 + m32) / s5;
} else {
const s5 = 2 * Math.sqrt(1 + m33 - m11 - m22);
this._w = (m21 - m12) / s5;
this._x = (m13 + m31) / s5;
this._y = (m23 + m32) / s5;
this._z = 0.25 * s5;
}
this._onChangeCallback();
return this;
}
/**
* Sets this quaternion to the rotation required to rotate the direction vector
* `vFrom` to the direction vector `vTo`.
*
* @param {Vector3} vFrom - The first (normalized) direction vector.
* @param {Vector3} vTo - The second (normalized) direction vector.
* @return {Quaternion} A reference to this quaternion.
*/
setFromUnitVectors(vFrom, vTo) {
let r6 = vFrom.dot(vTo) + 1;
if (r6 < 1e-8) {
r6 = 0;
if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {
this._x = -vFrom.y;
this._y = vFrom.x;
this._z = 0;
this._w = r6;
} else {
this._x = 0;
this._y = -vFrom.z;
this._z = vFrom.y;
this._w = r6;
}
} else {
this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
this._w = r6;
}
return this.normalize();
}
/**
* Returns the angle between this quaternion and the given one in radians.
*
* @param {Quaternion} q - The quaternion to compute the angle with.
* @return {number} The angle in radians.
*/
angleTo(q) {
return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));
}
/**
* Rotates this quaternion by a given angular step to the given quaternion.
* The method ensures that the final quaternion will not overshoot `q`.
*
* @param {Quaternion} q - The target quaternion.
* @param {number} step - The angular step in radians.
* @return {Quaternion} A reference to this quaternion.
*/
rotateTowards(q, step) {
const angle = this.angleTo(q);
if (angle === 0) return this;
const t6 = Math.min(1, step / angle);
this.slerp(q, t6);
return this;
}
/**
* Sets this quaternion to the identity quaternion; that is, to the
* quaternion that represents "no rotation".
*
* @return {Quaternion} A reference to this quaternion.
*/
identity() {
return this.set(0, 0, 0, 1);
}
/**
* Inverts this quaternion via {@link Quaternion#conjugate}. The
* quaternion is assumed to have unit length.
*
* @return {Quaternion} A reference to this quaternion.
*/
invert() {
return this.conjugate();
}
/**
* Returns the rotational conjugate of this quaternion. The conjugate of a
* quaternion represents the same rotation in the opposite direction about
* the rotational axis.
*
* @return {Quaternion} A reference to this quaternion.
*/
conjugate() {
this._x *= -1;
this._y *= -1;
this._z *= -1;
this._onChangeCallback();
return this;
}
/**
* Calculates the dot product of this quaternion and the given one.
*
* @param {Quaternion} v - The quaternion to compute the dot product with.
* @return {number} The result of the dot product.
*/
dot(v2) {
return this._x * v2._x + this._y * v2._y + this._z * v2._z + this._w * v2._w;
}
/**
* Computes the squared Euclidean length (straight-line length) of this quaternion,
* considered as a 4 dimensional vector. This can be useful if you are comparing the
* lengths of two quaternions, as this is a slightly more efficient calculation than
* {@link Quaternion#length}.
*
* @return {number} The squared Euclidean length.
*/
lengthSq() {
return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
}
/**
* Computes the Euclidean length (straight-line length) of this quaternion,
* considered as a 4 dimensional vector.
*
* @return {number} The Euclidean length.
*/
length() {
return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
}
/**
* Normalizes this quaternion - that is, calculated the quaternion that performs
* the same rotation as this one, but has a length equal to `1`.
*
* @return {Quaternion} A reference to this quaternion.
*/
normalize() {
let l3 = this.length();
if (l3 === 0) {
this._x = 0;
this._y = 0;
this._z = 0;
this._w = 1;
} else {
l3 = 1 / l3;
this._x = this._x * l3;
this._y = this._y * l3;
this._z = this._z * l3;
this._w = this._w * l3;
}
this._onChangeCallback();
return this;
}
/**
* Multiplies this quaternion by the given one.
*
* @param {Quaternion} q - The quaternion.
* @return {Quaternion} A reference to this quaternion.
*/
multiply(q) {
return this.multiplyQuaternions(this, q);
}
/**
* Pre-multiplies this quaternion by the given one.
*
* @param {Quaternion} q - The quaternion.
* @return {Quaternion} A reference to this quaternion.
*/
premultiply(q) {
return this.multiplyQuaternions(q, this);
}
/**
* Multiplies the given quaternions and stores the result in this instance.
*
* @param {Quaternion} a - The first quaternion.
* @param {Quaternion} b - The second quaternion.
* @return {Quaternion} A reference to this quaternion.
*/
multiplyQuaternions(a3, b3) {
const qax = a3._x, qay = a3._y, qaz = a3._z, qaw = a3._w;
const qbx = b3._x, qby = b3._y, qbz = b3._z, qbw = b3._w;
this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
this._onChangeCallback();
return this;
}
/**
* Performs a spherical linear interpolation between quaternions.
*
* @param {Quaternion} qb - The target quaternion.
* @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
* @return {Quaternion} A reference to this quaternion.
*/
slerp(qb, t6) {
if (t6 === 0) return this;
if (t6 === 1) return this.copy(qb);
const x2 = this._x, y3 = this._y, z2 = this._z, w2 = this._w;
let cosHalfTheta = w2 * qb._w + x2 * qb._x + y3 * qb._y + z2 * qb._z;
if (cosHalfTheta < 0) {
this._w = -qb._w;
this._x = -qb._x;
this._y = -qb._y;
this._z = -qb._z;
cosHalfTheta = -cosHalfTheta;
} else {
this.copy(qb);
}
if (cosHalfTheta >= 1) {
this._w = w2;
this._x = x2;
this._y = y3;
this._z = z2;
return this;
}
const sqrSinHalfTheta = 1 - cosHalfTheta * cosHalfTheta;
if (sqrSinHalfTheta <= Number.EPSILON) {
const s5 = 1 - t6;
this._w = s5 * w2 + t6 * this._w;
this._x = s5 * x2 + t6 * this._x;
this._y = s5 * y3 + t6 * this._y;
this._z = s5 * z2 + t6 * this._z;
this.normalize();
return this;
}
const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);
const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);
const ratioA = Math.sin((1 - t6) * halfTheta) / sinHalfTheta, ratioB = Math.sin(t6 * halfTheta) / sinHalfTheta;
this._w = w2 * ratioA + this._w * ratioB;
this._x = x2 * ratioA + this._x * ratioB;
this._y = y3 * ratioA + this._y * ratioB;
this._z = z2 * ratioA + this._z * ratioB;
this._onChangeCallback();
return this;
}
/**
* Performs a spherical linear interpolation between the given quaternions
* and stores the result in this quaternion.
*
* @param {Quaternion} qa - The source quaternion.
* @param {Quaternion} qb - The target quaternion.
* @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
* @return {Quaternion} A reference to this quaternion.
*/
slerpQuaternions(qa, qb, t6) {
return this.copy(qa).slerp(qb, t6);
}
/**
* Sets this quaternion to a uniformly random, normalized quaternion.
*
* @return {Quaternion} A reference to this quaternion.
*/
random() {
const theta1 = 2 * Math.PI * Math.random();
const theta2 = 2 * Math.PI * Math.random();
const x0 = Math.random();
const r1 = Math.sqrt(1 - x0);
const r22 = Math.sqrt(x0);
return this.set(
r1 * Math.sin(theta1),
r1 * Math.cos(theta1),
r22 * Math.sin(theta2),
r22 * Math.cos(theta2)
);
}
/**
* Returns `true` if this quaternion is equal with the given one.
*
* @param {Quaternion} quaternion - The quaternion to test for equality.
* @return {boolean} Whether this quaternion is equal with the given one.
*/
equals(quaternion) {
return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;
}
/**
* Sets this quaternion's components from the given array.
*
* @param {Array} array - An array holding the quaternion component values.
* @param {number} [offset=0] - The offset into the array.
* @return {Quaternion} A reference to this quaternion.
*/
fromArray(array, offset = 0) {
this._x = array[offset];
this._y = array[offset + 1];
this._z = array[offset + 2];
this._w = array[offset + 3];
this._onChangeCallback();
return this;
}
/**
* Writes the components of this quaternion to the given array. If no array is provided,
* the method returns a new instance.
*
* @param {Array} [array=[]] - The target array holding the quaternion components.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Array} The quaternion components.
*/
toArray(array = [], offset = 0) {
array[offset] = this._x;
array[offset + 1] = this._y;
array[offset + 2] = this._z;
array[offset + 3] = this._w;
return array;
}
/**
* Sets the components of this quaternion from the given buffer attribute.
*
* @param {BufferAttribute} attribute - The buffer attribute holding quaternion data.
* @param {number} index - The index into the attribute.
* @return {Quaternion} A reference to this quaternion.
*/
fromBufferAttribute(attribute, index) {
this._x = attribute.getX(index);
this._y = attribute.getY(index);
this._z = attribute.getZ(index);
this._w = attribute.getW(index);
this._onChangeCallback();
return this;
}
/**
* This methods defines the serialization result of this class. Returns the
* numerical elements of this quaternion in an array of format `[x, y, z, w]`.
*
* @return {Array} The serialized quaternion.
*/
toJSON() {
return this.toArray();
}
_onChange(callback) {
this._onChangeCallback = callback;
return this;
}
_onChangeCallback() {
}
*[Symbol.iterator]() {
yield this._x;
yield this._y;
yield this._z;
yield this._w;
}
};
var Vector3 = class _Vector3 {
/**
* Constructs a new 3D vector.
*
* @param {number} [x=0] - The x value of this vector.
* @param {number} [y=0] - The y value of this vector.
* @param {number} [z=0] - The z value of this vector.
*/
constructor(x2 = 0, y3 = 0, z2 = 0) {
_Vector3.prototype.isVector3 = true;
this.x = x2;
this.y = y3;
this.z = z2;
}
/**
* Sets the vector components.
*
* @param {number} x - The value of the x component.
* @param {number} y - The value of the y component.
* @param {number} z - The value of the z component.
* @return {Vector3} A reference to this vector.
*/
set(x2, y3, z2) {
if (z2 === void 0) z2 = this.z;
this.x = x2;
this.y = y3;
this.z = z2;
return this;
}
/**
* Sets the vector components to the same value.
*
* @param {number} scalar - The value to set for all vector components.
* @return {Vector3} A reference to this vector.
*/
setScalar(scalar) {
this.x = scalar;
this.y = scalar;
this.z = scalar;
return this;
}
/**
* Sets the vector's x component to the given value
*
* @param {number} x - The value to set.
* @return {Vector3} A reference to this vector.
*/
setX(x2) {
this.x = x2;
return this;
}
/**
* Sets the vector's y component to the given value
*
* @param {number} y - The value to set.
* @return {Vector3} A reference to this vector.
*/
setY(y3) {
this.y = y3;
return this;
}
/**
* Sets the vector's z component to the given value
*
* @param {number} z - The value to set.
* @return {Vector3} A reference to this vector.
*/
setZ(z2) {
this.z = z2;
return this;
}
/**
* Allows to set a vector component with an index.
*
* @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
* @param {number} value - The value to set.
* @return {Vector3} A reference to this vector.
*/
setComponent(index, value) {
switch (index) {
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
case 2:
this.z = value;
break;
default:
throw new Error("index is out of range: " + index);
}
return this;
}
/**
* Returns the value of the vector component which matches the given index.
*
* @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
* @return {number} A vector component value.
*/
getComponent(index) {
switch (index) {
case 0:
return this.x;
case 1:
return this.y;
case 2:
return this.z;
default:
throw new Error("index is out of range: " + index);
}
}
/**
* Returns a new vector with copied values from this instance.
*
* @return {Vector3} A clone of this instance.
*/
clone() {
return new this.constructor(this.x, this.y, this.z);
}
/**
* Copies the values of the given vector to this instance.
*
* @param {Vector3} v - The vector to copy.
* @return {Vector3} A reference to this vector.
*/
copy(v2) {
this.x = v2.x;
this.y = v2.y;
this.z = v2.z;
return this;
}
/**
* Adds the given vector to this instance.
*
* @param {Vector3} v - The vector to add.
* @return {Vector3} A reference to this vector.
*/
add(v2) {
this.x += v2.x;
this.y += v2.y;
this.z += v2.z;
return this;
}
/**
* Adds the given scalar value to all components of this instance.
*
* @param {number} s - The scalar to add.
* @return {Vector3} A reference to this vector.
*/
addScalar(s5) {
this.x += s5;
this.y += s5;
this.z += s5;
return this;
}
/**
* Adds the given vectors and stores the result in this instance.
*
* @param {Vector3} a - The first vector.
* @param {Vector3} b - The second vector.
* @return {Vector3} A reference to this vector.
*/
addVectors(a3, b3) {
this.x = a3.x + b3.x;
this.y = a3.y + b3.y;
this.z = a3.z + b3.z;
return this;
}
/**
* Adds the given vector scaled by the given factor to this instance.
*
* @param {Vector3|Vector4} v - The vector.
* @param {number} s - The factor that scales `v`.
* @return {Vector3} A reference to this vector.
*/
addScaledVector(v2, s5) {
this.x += v2.x * s5;
this.y += v2.y * s5;
this.z += v2.z * s5;
return this;
}
/**
* Subtracts the given vector from this instance.
*
* @param {Vector3} v - The vector to subtract.
* @return {Vector3} A reference to this vector.
*/
sub(v2) {
this.x -= v2.x;
this.y -= v2.y;
this.z -= v2.z;
return this;
}
/**
* Subtracts the given scalar value from all components of this instance.
*
* @param {number} s - The scalar to subtract.
* @return {Vector3} A reference to this vector.
*/
subScalar(s5) {
this.x -= s5;
this.y -= s5;
this.z -= s5;
return this;
}
/**
* Subtracts the given vectors and stores the result in this instance.
*
* @param {Vector3} a - The first vector.
* @param {Vector3} b - The second vector.
* @return {Vector3} A reference to this vector.
*/
subVectors(a3, b3) {
this.x = a3.x - b3.x;
this.y = a3.y - b3.y;
this.z = a3.z - b3.z;
return this;
}
/**
* Multiplies the given vector with this instance.
*
* @param {Vector3} v - The vector to multiply.
* @return {Vector3} A reference to this vector.
*/
multiply(v2) {
this.x *= v2.x;
this.y *= v2.y;
this.z *= v2.z;
return this;
}
/**
* Multiplies the given scalar value with all components of this instance.
*
* @param {number} scalar - The scalar to multiply.
* @return {Vector3} A reference to this vector.
*/
multiplyScalar(scalar) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
return this;
}
/**
* Multiplies the given vectors and stores the result in this instance.
*
* @param {Vector3} a - The first vector.
* @param {Vector3} b - The second vector.
* @return {Vector3} A reference to this vector.
*/
multiplyVectors(a3, b3) {
this.x = a3.x * b3.x;
this.y = a3.y * b3.y;
this.z = a3.z * b3.z;
return this;
}
/**
* Applies the given Euler rotation to this vector.
*
* @param {Euler} euler - The Euler angles.
* @return {Vector3} A reference to this vector.
*/
applyEuler(euler) {
return this.applyQuaternion(_quaternion$4.setFromEuler(euler));
}
/**
* Applies a rotation specified by an axis and an angle to this vector.
*
* @param {Vector3} axis - A normalized vector representing the rotation axis.
* @param {number} angle - The angle in radians.
* @return {Vector3} A reference to this vector.
*/
applyAxisAngle(axis, angle) {
return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle));
}
/**
* Multiplies this vector with the given 3x3 matrix.
*
* @param {Matrix3} m - The 3x3 matrix.
* @return {Vector3} A reference to this vector.
*/
applyMatrix3(m2) {
const x2 = this.x, y3 = this.y, z2 = this.z;
const e8 = m2.elements;
this.x = e8[0] * x2 + e8[3] * y3 + e8[6] * z2;
this.y = e8[1] * x2 + e8[4] * y3 + e8[7] * z2;
this.z = e8[2] * x2 + e8[5] * y3 + e8[8] * z2;
return this;
}
/**
* Multiplies this vector by the given normal matrix and normalizes
* the result.
*
* @param {Matrix3} m - The normal matrix.
* @return {Vector3} A reference to this vector.
*/
applyNormalMatrix(m2) {
return this.applyMatrix3(m2).normalize();
}
/**
* Multiplies this vector (with an implicit 1 in the 4th dimension) by m, and
* divides by perspective.
*
* @param {Matrix4} m - The matrix to apply.
* @return {Vector3} A reference to this vector.
*/
applyMatrix4(m2) {
const x2 = this.x, y3 = this.y, z2 = this.z;
const e8 = m2.elements;
const w2 = 1 / (e8[3] * x2 + e8[7] * y3 + e8[11] * z2 + e8[15]);
this.x = (e8[0] * x2 + e8[4] * y3 + e8[8] * z2 + e8[12]) * w2;
this.y = (e8[1] * x2 + e8[5] * y3 + e8[9] * z2 + e8[13]) * w2;
this.z = (e8[2] * x2 + e8[6] * y3 + e8[10] * z2 + e8[14]) * w2;
return this;
}
/**
* Applies the given Quaternion to this vector.
*
* @param {Quaternion} q - The Quaternion.
* @return {Vector3} A reference to this vector.
*/
applyQuaternion(q) {
const vx = this.x, vy = this.y, vz = this.z;
const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
const tx = 2 * (qy * vz - qz * vy);
const ty = 2 * (qz * vx - qx * vz);
const tz = 2 * (qx * vy - qy * vx);
this.x = vx + qw * tx + qy * tz - qz * ty;
this.y = vy + qw * ty + qz * tx - qx * tz;
this.z = vz + qw * tz + qx * ty - qy * tx;
return this;
}
/**
* Projects this vector from world space into the camera's normalized
* device coordinate (NDC) space.
*
* @param {Camera} camera - The camera.
* @return {Vector3} A reference to this vector.
*/
project(camera) {
return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);
}
/**
* Unprojects this vector from the camera's normalized device coordinate (NDC)
* space into world space.
*
* @param {Camera} camera - The camera.
* @return {Vector3} A reference to this vector.
*/
unproject(camera) {
return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);
}
/**
* Transforms the direction of this vector by a matrix (the upper left 3 x 3
* subset of the given 4x4 matrix and then normalizes the result.
*
* @param {Matrix4} m - The matrix.
* @return {Vector3} A reference to this vector.
*/
transformDirection(m2) {
const x2 = this.x, y3 = this.y, z2 = this.z;
const e8 = m2.elements;
this.x = e8[0] * x2 + e8[4] * y3 + e8[8] * z2;
this.y = e8[1] * x2 + e8[5] * y3 + e8[9] * z2;
this.z = e8[2] * x2 + e8[6] * y3 + e8[10] * z2;
return this.normalize();
}
/**
* Divides this instance by the given vector.
*
* @param {Vector3} v - The vector to divide.
* @return {Vector3} A reference to this vector.
*/
divide(v2) {
this.x /= v2.x;
this.y /= v2.y;
this.z /= v2.z;
return this;
}
/**
* Divides this vector by the given scalar.
*
* @param {number} scalar - The scalar to divide.
* @return {Vector3} A reference to this vector.
*/
divideScalar(scalar) {
return this.multiplyScalar(1 / scalar);
}
/**
* If this vector's x, y or z value is greater than the given vector's x, y or z
* value, replace that value with the corresponding min value.
*
* @param {Vector3} v - The vector.
* @return {Vector3} A reference to this vector.
*/
min(v2) {
this.x = Math.min(this.x, v2.x);
this.y = Math.min(this.y, v2.y);
this.z = Math.min(this.z, v2.z);
return this;
}
/**
* If this vector's x, y or z value is less than the given vector's x, y or z
* value, replace that value with the corresponding max value.
*
* @param {Vector3} v - The vector.
* @return {Vector3} A reference to this vector.
*/
max(v2) {
this.x = Math.max(this.x, v2.x);
this.y = Math.max(this.y, v2.y);
this.z = Math.max(this.z, v2.z);
return this;
}
/**
* If this vector's x, y or z value is greater than the max vector's x, y or z
* value, it is replaced by the corresponding value.
* If this vector's x, y or z value is less than the min vector's x, y or z value,
* it is replaced by the corresponding value.
*
* @param {Vector3} min - The minimum x, y and z values.
* @param {Vector3} max - The maximum x, y and z values in the desired range.
* @return {Vector3} A reference to this vector.
*/
clamp(min, max) {
this.x = clamp(this.x, min.x, max.x);
this.y = clamp(this.y, min.y, max.y);
this.z = clamp(this.z, min.z, max.z);
return this;
}
/**
* If this vector's x, y or z values are greater than the max value, they are
* replaced by the max value.
* If this vector's x, y or z values are less than the min value, they are
* replaced by the min value.
*
* @param {number} minVal - The minimum value the components will be clamped to.
* @param {number} maxVal - The maximum value the components will be clamped to.
* @return {Vector3} A reference to this vector.
*/
clampScalar(minVal, maxVal) {
this.x = clamp(this.x, minVal, maxVal);
this.y = clamp(this.y, minVal, maxVal);
this.z = clamp(this.z, minVal, maxVal);
return this;
}
/**
* If this vector's length is greater than the max value, it is replaced by
* the max value.
* If this vector's length is less than the min value, it is replaced by the
* min value.
*
* @param {number} min - The minimum value the vector length will be clamped to.
* @param {number} max - The maximum value the vector length will be clamped to.
* @return {Vector3} A reference to this vector.
*/
clampLength(min, max) {
const length = this.length();
return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max));
}
/**
* The components of this vector are rounded down to the nearest integer value.
*
* @return {Vector3} A reference to this vector.
*/
floor() {
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
this.z = Math.floor(this.z);
return this;
}
/**
* The components of this vector are rounded up to the nearest integer value.
*
* @return {Vector3} A reference to this vector.
*/
ceil() {
this.x = Math.ceil(this.x);
this.y = Math.ceil(this.y);
this.z = Math.ceil(this.z);
return this;
}
/**
* The components of this vector are rounded to the nearest integer value
*
* @return {Vector3} A reference to this vector.
*/
round() {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
this.z = Math.round(this.z);
return this;
}
/**
* The components of this vector are rounded towards zero (up if negative,
* down if positive) to an integer value.
*
* @return {Vector3} A reference to this vector.
*/
roundToZero() {
this.x = Math.trunc(this.x);
this.y = Math.trunc(this.y);
this.z = Math.trunc(this.z);
return this;
}
/**
* Inverts this vector - i.e. sets x = -x, y = -y and z = -z.
*
* @return {Vector3} A reference to this vector.
*/
negate() {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
return this;
}
/**
* Calculates the dot product of the given vector with this instance.
*
* @param {Vector3} v - The vector to compute the dot product with.
* @return {number} The result of the dot product.
*/
dot(v2) {
return this.x * v2.x + this.y * v2.y + this.z * v2.z;
}
// TODO lengthSquared?
/**
* Computes the square of the Euclidean length (straight-line length) from
* (0, 0, 0) to (x, y, z). If you are comparing the lengths of vectors, you should
* compare the length squared instead as it is slightly more efficient to calculate.
*
* @return {number} The square length of this vector.
*/
lengthSq() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
/**
* Computes the Euclidean length (straight-line length) from (0, 0, 0) to (x, y, z).
*
* @return {number} The length of this vector.
*/
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
}
/**
* Computes the Manhattan length of this vector.
*
* @return {number} The length of this vector.
*/
manhattanLength() {
return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
}
/**
* Converts this vector to a unit vector - that is, sets it equal to a vector
* with the same direction as this one, but with a vector length of `1`.
*
* @return {Vector3} A reference to this vector.
*/
normalize() {
return this.divideScalar(this.length() || 1);
}
/**
* Sets this vector to a vector with the same direction as this one, but
* with the specified length.
*
* @param {number} length - The new length of this vector.
* @return {Vector3} A reference to this vector.
*/
setLength(length) {
return this.normalize().multiplyScalar(length);
}
/**
* Linearly interpolates between the given vector and this instance, where
* alpha is the percent distance along the line - alpha = 0 will be this
* vector, and alpha = 1 will be the given one.
*
* @param {Vector3} v - The vector to interpolate towards.
* @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
* @return {Vector3} A reference to this vector.
*/
lerp(v2, alpha) {
this.x += (v2.x - this.x) * alpha;
this.y += (v2.y - this.y) * alpha;
this.z += (v2.z - this.z) * alpha;
return this;
}
/**
* Linearly interpolates between the given vectors, where alpha is the percent
* distance along the line - alpha = 0 will be first vector, and alpha = 1 will
* be the second one. The result is stored in this instance.
*
* @param {Vector3} v1 - The first vector.
* @param {Vector3} v2 - The second vector.
* @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
* @return {Vector3} A reference to this vector.
*/
lerpVectors(v1, v2, alpha) {
this.x = v1.x + (v2.x - v1.x) * alpha;
this.y = v1.y + (v2.y - v1.y) * alpha;
this.z = v1.z + (v2.z - v1.z) * alpha;
return this;
}
/**
* Calculates the cross product of the given vector with this instance.
*
* @param {Vector3} v - The vector to compute the cross product with.
* @return {Vector3} The result of the cross product.
*/
cross(v2) {
return this.crossVectors(this, v2);
}
/**
* Calculates the cross product of the given vectors and stores the result
* in this instance.
*
* @param {Vector3} a - The first vector.
* @param {Vector3} b - The second vector.
* @return {Vector3} A reference to this vector.
*/
crossVectors(a3, b3) {
const ax = a3.x, ay = a3.y, az = a3.z;
const bx = b3.x, by = b3.y, bz = b3.z;
this.x = ay * bz - az * by;
this.y = az * bx - ax * bz;
this.z = ax * by - ay * bx;
return this;
}
/**
* Projects this vector onto the given one.
*
* @param {Vector3} v - The vector to project to.
* @return {Vector3} A reference to this vector.
*/
projectOnVector(v2) {
const denominator = v2.lengthSq();
if (denominator === 0) return this.set(0, 0, 0);
const scalar = v2.dot(this) / denominator;
return this.copy(v2).multiplyScalar(scalar);
}
/**
* Projects this vector onto a plane by subtracting this
* vector projected onto the plane's normal from this vector.
*
* @param {Vector3} planeNormal - The plane normal.
* @return {Vector3} A reference to this vector.
*/
projectOnPlane(planeNormal) {
_vector$c.copy(this).projectOnVector(planeNormal);
return this.sub(_vector$c);
}
/**
* Reflects this vector off a plane orthogonal to the given normal vector.
*
* @param {Vector3} normal - The (normalized) normal vector.
* @return {Vector3} A reference to this vector.
*/
reflect(normal) {
return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal)));
}
/**
* Returns the angle between the given vector and this instance in radians.
*
* @param {Vector3} v - The vector to compute the angle with.
* @return {number} The angle in radians.
*/
angleTo(v2) {
const denominator = Math.sqrt(this.lengthSq() * v2.lengthSq());
if (denominator === 0) return Math.PI / 2;
const theta = this.dot(v2) / denominator;
return Math.acos(clamp(theta, -1, 1));
}
/**
* Computes the distance from the given vector to this instance.
*
* @param {Vector3} v - The vector to compute the distance to.
* @return {number} The distance.
*/
distanceTo(v2) {
return Math.sqrt(this.distanceToSquared(v2));
}
/**
* Computes the squared distance from the given vector to this instance.
* If you are just comparing the distance with another distance, you should compare
* the distance squared instead as it is slightly more efficient to calculate.
*
* @param {Vector3} v - The vector to compute the squared distance to.
* @return {number} The squared distance.
*/
distanceToSquared(v2) {
const dx = this.x - v2.x, dy = this.y - v2.y, dz = this.z - v2.z;
return dx * dx + dy * dy + dz * dz;
}
/**
* Computes the Manhattan distance from the given vector to this instance.
*
* @param {Vector3} v - The vector to compute the Manhattan distance to.
* @return {number} The Manhattan distance.
*/
manhattanDistanceTo(v2) {
return Math.abs(this.x - v2.x) + Math.abs(this.y - v2.y) + Math.abs(this.z - v2.z);
}
/**
* Sets the vector components from the given spherical coordinates.
*
* @param {Spherical} s - The spherical coordinates.
* @return {Vector3} A reference to this vector.
*/
setFromSpherical(s5) {
return this.setFromSphericalCoords(s5.radius, s5.phi, s5.theta);
}
/**
* Sets the vector components from the given spherical coordinates.
*
* @param {number} radius - The radius.
* @param {number} phi - The phi angle in radians.
* @param {number} theta - The theta angle in radians.
* @return {Vector3} A reference to this vector.
*/
setFromSphericalCoords(radius, phi, theta) {
const sinPhiRadius = Math.sin(phi) * radius;
this.x = sinPhiRadius * Math.sin(theta);
this.y = Math.cos(phi) * radius;
this.z = sinPhiRadius * Math.cos(theta);
return this;
}
/**
* Sets the vector components from the given cylindrical coordinates.
*
* @param {Cylindrical} c - The cylindrical coordinates.
* @return {Vector3} A reference to this vector.
*/
setFromCylindrical(c5) {
return this.setFromCylindricalCoords(c5.radius, c5.theta, c5.y);
}
/**
* Sets the vector components from the given cylindrical coordinates.
*
* @param {number} radius - The radius.
* @param {number} theta - The theta angle in radians.
* @param {number} y - The y value.
* @return {Vector3} A reference to this vector.
*/
setFromCylindricalCoords(radius, theta, y3) {
this.x = radius * Math.sin(theta);
this.y = y3;
this.z = radius * Math.cos(theta);
return this;
}
/**
* Sets the vector components to the position elements of the
* given transformation matrix.
*
* @param {Matrix4} m - The 4x4 matrix.
* @return {Vector3} A reference to this vector.
*/
setFromMatrixPosition(m2) {
const e8 = m2.elements;
this.x = e8[12];
this.y = e8[13];
this.z = e8[14];
return this;
}
/**
* Sets the vector components to the scale elements of the
* given transformation matrix.
*
* @param {Matrix4} m - The 4x4 matrix.
* @return {Vector3} A reference to this vector.
*/
setFromMatrixScale(m2) {
const sx = this.setFromMatrixColumn(m2, 0).length();
const sy = this.setFromMatrixColumn(m2, 1).length();
const sz = this.setFromMatrixColumn(m2, 2).length();
this.x = sx;
this.y = sy;
this.z = sz;
return this;
}
/**
* Sets the vector components from the specified matrix column.
*
* @param {Matrix4} m - The 4x4 matrix.
* @param {number} index - The column index.
* @return {Vector3} A reference to this vector.
*/
setFromMatrixColumn(m2, index) {
return this.fromArray(m2.elements, index * 4);
}
/**
* Sets the vector components from the specified matrix column.
*
* @param {Matrix3} m - The 3x3 matrix.
* @param {number} index - The column index.
* @return {Vector3} A reference to this vector.
*/
setFromMatrix3Column(m2, index) {
return this.fromArray(m2.elements, index * 3);
}
/**
* Sets the vector components from the given Euler angles.
*
* @param {Euler} e - The Euler angles to set.
* @return {Vector3} A reference to this vector.
*/
setFromEuler(e8) {
this.x = e8._x;
this.y = e8._y;
this.z = e8._z;
return this;
}
/**
* Sets the vector components from the RGB components of the
* given color.
*
* @param {Color} c - The color to set.
* @return {Vector3} A reference to this vector.
*/
setFromColor(c5) {
this.x = c5.r;
this.y = c5.g;
this.z = c5.b;
return this;
}
/**
* Returns `true` if this vector is equal with the given one.
*
* @param {Vector3} v - The vector to test for equality.
* @return {boolean} Whether this vector is equal with the given one.
*/
equals(v2) {
return v2.x === this.x && v2.y === this.y && v2.z === this.z;
}
/**
* Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`
* and z value to be `array[ offset + 2 ]`.
*
* @param {Array} array - An array holding the vector component values.
* @param {number} [offset=0] - The offset into the array.
* @return {Vector3} A reference to this vector.
*/
fromArray(array, offset = 0) {
this.x = array[offset];
this.y = array[offset + 1];
this.z = array[offset + 2];
return this;
}
/**
* Writes the components of this vector to the given array. If no array is provided,
* the method returns a new instance.
*
* @param {Array} [array=[]] - The target array holding the vector components.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Array} The vector components.
*/
toArray(array = [], offset = 0) {
array[offset] = this.x;
array[offset + 1] = this.y;
array[offset + 2] = this.z;
return array;
}
/**
* Sets the components of this vector from the given buffer attribute.
*
* @param {BufferAttribute} attribute - The buffer attribute holding vector data.
* @param {number} index - The index into the attribute.
* @return {Vector3} A reference to this vector.
*/
fromBufferAttribute(attribute, index) {
this.x = attribute.getX(index);
this.y = attribute.getY(index);
this.z = attribute.getZ(index);
return this;
}
/**
* Sets each component of this vector to a pseudo-random value between `0` and
* `1`, excluding `1`.
*
* @return {Vector3} A reference to this vector.
*/
random() {
this.x = Math.random();
this.y = Math.random();
this.z = Math.random();
return this;
}
/**
* Sets this vector to a uniformly random point on a unit sphere.
*
* @return {Vector3} A reference to this vector.
*/
randomDirection() {
const theta = Math.random() * Math.PI * 2;
const u3 = Math.random() * 2 - 1;
const c5 = Math.sqrt(1 - u3 * u3);
this.x = c5 * Math.cos(theta);
this.y = u3;
this.z = c5 * Math.sin(theta);
return this;
}
*[Symbol.iterator]() {
yield this.x;
yield this.y;
yield this.z;
}
};
var _vector$c = /* @__PURE__ */ new Vector3();
var _quaternion$4 = /* @__PURE__ */ new Quaternion();
var Matrix3 = class _Matrix3 {
/**
* Constructs a new 3x3 matrix. The arguments are supposed to be
* in row-major order. If no arguments are provided, the constructor
* initializes the matrix as an identity matrix.
*
* @param {number} [n11] - 1-1 matrix element.
* @param {number} [n12] - 1-2 matrix element.
* @param {number} [n13] - 1-3 matrix element.
* @param {number} [n21] - 2-1 matrix element.
* @param {number} [n22] - 2-2 matrix element.
* @param {number} [n23] - 2-3 matrix element.
* @param {number} [n31] - 3-1 matrix element.
* @param {number} [n32] - 3-2 matrix element.
* @param {number} [n33] - 3-3 matrix element.
*/
constructor(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
_Matrix3.prototype.isMatrix3 = true;
this.elements = [
1,
0,
0,
0,
1,
0,
0,
0,
1
];
if (n11 !== void 0) {
this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33);
}
}
/**
* Sets the elements of the matrix.The arguments are supposed to be
* in row-major order.
*
* @param {number} [n11] - 1-1 matrix element.
* @param {number} [n12] - 1-2 matrix element.
* @param {number} [n13] - 1-3 matrix element.
* @param {number} [n21] - 2-1 matrix element.
* @param {number} [n22] - 2-2 matrix element.
* @param {number} [n23] - 2-3 matrix element.
* @param {number} [n31] - 3-1 matrix element.
* @param {number} [n32] - 3-2 matrix element.
* @param {number} [n33] - 3-3 matrix element.
* @return {Matrix3} A reference to this matrix.
*/
set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
const te = this.elements;
te[0] = n11;
te[1] = n21;
te[2] = n31;
te[3] = n12;
te[4] = n22;
te[5] = n32;
te[6] = n13;
te[7] = n23;
te[8] = n33;
return this;
}
/**
* Sets this matrix to the 3x3 identity matrix.
*
* @return {Matrix3} A reference to this matrix.
*/
identity() {
this.set(
1,
0,
0,
0,
1,
0,
0,
0,
1
);
return this;
}
/**
* Copies the values of the given matrix to this instance.
*
* @param {Matrix3} m - The matrix to copy.
* @return {Matrix3} A reference to this matrix.
*/
copy(m2) {
const te = this.elements;
const me = m2.elements;
te[0] = me[0];
te[1] = me[1];
te[2] = me[2];
te[3] = me[3];
te[4] = me[4];
te[5] = me[5];
te[6] = me[6];
te[7] = me[7];
te[8] = me[8];
return this;
}
/**
* Extracts the basis of this matrix into the three axis vectors provided.
*
* @param {Vector3} xAxis - The basis's x axis.
* @param {Vector3} yAxis - The basis's y axis.
* @param {Vector3} zAxis - The basis's z axis.
* @return {Matrix3} A reference to this matrix.
*/
extractBasis(xAxis, yAxis, zAxis) {
xAxis.setFromMatrix3Column(this, 0);
yAxis.setFromMatrix3Column(this, 1);
zAxis.setFromMatrix3Column(this, 2);
return this;
}
/**
* Set this matrix to the upper 3x3 matrix of the given 4x4 matrix.
*
* @param {Matrix4} m - The 4x4 matrix.
* @return {Matrix3} A reference to this matrix.
*/
setFromMatrix4(m2) {
const me = m2.elements;
this.set(
me[0],
me[4],
me[8],
me[1],
me[5],
me[9],
me[2],
me[6],
me[10]
);
return this;
}
/**
* Post-multiplies this matrix by the given 3x3 matrix.
*
* @param {Matrix3} m - The matrix to multiply with.
* @return {Matrix3} A reference to this matrix.
*/
multiply(m2) {
return this.multiplyMatrices(this, m2);
}
/**
* Pre-multiplies this matrix by the given 3x3 matrix.
*
* @param {Matrix3} m - The matrix to multiply with.
* @return {Matrix3} A reference to this matrix.
*/
premultiply(m2) {
return this.multiplyMatrices(m2, this);
}
/**
* Multiples the given 3x3 matrices and stores the result
* in this matrix.
*
* @param {Matrix3} a - The first matrix.
* @param {Matrix3} b - The second matrix.
* @return {Matrix3} A reference to this matrix.
*/
multiplyMatrices(a3, b3) {
const ae = a3.elements;
const be = b3.elements;
const te = this.elements;
const a11 = ae[0], a12 = ae[3], a13 = ae[6];
const a21 = ae[1], a22 = ae[4], a23 = ae[7];
const a31 = ae[2], a32 = ae[5], a33 = ae[8];
const b11 = be[0], b12 = be[3], b13 = be[6];
const b21 = be[1], b22 = be[4], b23 = be[7];
const b31 = be[2], b32 = be[5], b33 = be[8];
te[0] = a11 * b11 + a12 * b21 + a13 * b31;
te[3] = a11 * b12 + a12 * b22 + a13 * b32;
te[6] = a11 * b13 + a12 * b23 + a13 * b33;
te[1] = a21 * b11 + a22 * b21 + a23 * b31;
te[4] = a21 * b12 + a22 * b22 + a23 * b32;
te[7] = a21 * b13 + a22 * b23 + a23 * b33;
te[2] = a31 * b11 + a32 * b21 + a33 * b31;
te[5] = a31 * b12 + a32 * b22 + a33 * b32;
te[8] = a31 * b13 + a32 * b23 + a33 * b33;
return this;
}
/**
* Multiplies every component of the matrix by the given scalar.
*
* @param {number} s - The scalar.
* @return {Matrix3} A reference to this matrix.
*/
multiplyScalar(s5) {
const te = this.elements;
te[0] *= s5;
te[3] *= s5;
te[6] *= s5;
te[1] *= s5;
te[4] *= s5;
te[7] *= s5;
te[2] *= s5;
te[5] *= s5;
te[8] *= s5;
return this;
}
/**
* Computes and returns the determinant of this matrix.
*
* @return {number} The determinant.
*/
determinant() {
const te = this.elements;
const a3 = te[0], b3 = te[1], c5 = te[2], d3 = te[3], e8 = te[4], f4 = te[5], g2 = te[6], h4 = te[7], i6 = te[8];
return a3 * e8 * i6 - a3 * f4 * h4 - b3 * d3 * i6 + b3 * f4 * g2 + c5 * d3 * h4 - c5 * e8 * g2;
}
/**
* Inverts this matrix, using the [analytic method]{@link https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution}.
* You can not invert with a determinant of zero. If you attempt this, the method produces
* a zero matrix instead.
*
* @return {Matrix3} A reference to this matrix.
*/
invert() {
const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n12 = te[3], n22 = te[4], n32 = te[5], n13 = te[6], n23 = te[7], n33 = te[8], t11 = n33 * n22 - n32 * n23, t12 = n32 * n13 - n33 * n12, t13 = n23 * n12 - n22 * n13, det = n11 * t11 + n21 * t12 + n31 * t13;
if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
const detInv = 1 / det;
te[0] = t11 * detInv;
te[1] = (n31 * n23 - n33 * n21) * detInv;
te[2] = (n32 * n21 - n31 * n22) * detInv;
te[3] = t12 * detInv;
te[4] = (n33 * n11 - n31 * n13) * detInv;
te[5] = (n31 * n12 - n32 * n11) * detInv;
te[6] = t13 * detInv;
te[7] = (n21 * n13 - n23 * n11) * detInv;
te[8] = (n22 * n11 - n21 * n12) * detInv;
return this;
}
/**
* Transposes this matrix in place.
*
* @return {Matrix3} A reference to this matrix.
*/
transpose() {
let tmp;
const m2 = this.elements;
tmp = m2[1];
m2[1] = m2[3];
m2[3] = tmp;
tmp = m2[2];
m2[2] = m2[6];
m2[6] = tmp;
tmp = m2[5];
m2[5] = m2[7];
m2[7] = tmp;
return this;
}
/**
* Computes the normal matrix which is the inverse transpose of the upper
* left 3x3 portion of the given 4x4 matrix.
*
* @param {Matrix4} matrix4 - The 4x4 matrix.
* @return {Matrix3} A reference to this matrix.
*/
getNormalMatrix(matrix4) {
return this.setFromMatrix4(matrix4).invert().transpose();
}
/**
* Transposes this matrix into the supplied array, and returns itself unchanged.
*
* @param {Array} r - An array to store the transposed matrix elements.
* @return {Matrix3} A reference to this matrix.
*/
transposeIntoArray(r6) {
const m2 = this.elements;
r6[0] = m2[0];
r6[1] = m2[3];
r6[2] = m2[6];
r6[3] = m2[1];
r6[4] = m2[4];
r6[5] = m2[7];
r6[6] = m2[2];
r6[7] = m2[5];
r6[8] = m2[8];
return this;
}
/**
* Sets the UV transform matrix from offset, repeat, rotation, and center.
*
* @param {number} tx - Offset x.
* @param {number} ty - Offset y.
* @param {number} sx - Repeat x.
* @param {number} sy - Repeat y.
* @param {number} rotation - Rotation, in radians. Positive values rotate counterclockwise.
* @param {number} cx - Center x of rotation.
* @param {number} cy - Center y of rotation
* @return {Matrix3} A reference to this matrix.
*/
setUvTransform(tx, ty, sx, sy, rotation, cx, cy) {
const c5 = Math.cos(rotation);
const s5 = Math.sin(rotation);
this.set(
sx * c5,
sx * s5,
-sx * (c5 * cx + s5 * cy) + cx + tx,
-sy * s5,
sy * c5,
-sy * (-s5 * cx + c5 * cy) + cy + ty,
0,
0,
1
);
return this;
}
/**
* Scales this matrix with the given scalar values.
*
* @param {number} sx - The amount to scale in the X axis.
* @param {number} sy - The amount to scale in the Y axis.
* @return {Matrix3} A reference to this matrix.
*/
scale(sx, sy) {
this.premultiply(_m3.makeScale(sx, sy));
return this;
}
/**
* Rotates this matrix by the given angle.
*
* @param {number} theta - The rotation in radians.
* @return {Matrix3} A reference to this matrix.
*/
rotate(theta) {
this.premultiply(_m3.makeRotation(-theta));
return this;
}
/**
* Translates this matrix by the given scalar values.
*
* @param {number} tx - The amount to translate in the X axis.
* @param {number} ty - The amount to translate in the Y axis.
* @return {Matrix3} A reference to this matrix.
*/
translate(tx, ty) {
this.premultiply(_m3.makeTranslation(tx, ty));
return this;
}
// for 2D Transforms
/**
* Sets this matrix as a 2D translation transform.
*
* @param {number|Vector2} x - The amount to translate in the X axis or alternatively a translation vector.
* @param {number} y - The amount to translate in the Y axis.
* @return {Matrix3} A reference to this matrix.
*/
makeTranslation(x2, y3) {
if (x2.isVector2) {
this.set(
1,
0,
x2.x,
0,
1,
x2.y,
0,
0,
1
);
} else {
this.set(
1,
0,
x2,
0,
1,
y3,
0,
0,
1
);
}
return this;
}
/**
* Sets this matrix as a 2D rotational transformation.
*
* @param {number} theta - The rotation in radians.
* @return {Matrix3} A reference to this matrix.
*/
makeRotation(theta) {
const c5 = Math.cos(theta);
const s5 = Math.sin(theta);
this.set(
c5,
-s5,
0,
s5,
c5,
0,
0,
0,
1
);
return this;
}
/**
* Sets this matrix as a 2D scale transform.
*
* @param {number} x - The amount to scale in the X axis.
* @param {number} y - The amount to scale in the Y axis.
* @return {Matrix3} A reference to this matrix.
*/
makeScale(x2, y3) {
this.set(
x2,
0,
0,
0,
y3,
0,
0,
0,
1
);
return this;
}
/**
* Returns `true` if this matrix is equal with the given one.
*
* @param {Matrix3} matrix - The matrix to test for equality.
* @return {boolean} Whether this matrix is equal with the given one.
*/
equals(matrix) {
const te = this.elements;
const me = matrix.elements;
for (let i6 = 0; i6 < 9; i6++) {
if (te[i6] !== me[i6]) return false;
}
return true;
}
/**
* Sets the elements of the matrix from the given array.
*
* @param {Array} array - The matrix elements in column-major order.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Matrix3} A reference to this matrix.
*/
fromArray(array, offset = 0) {
for (let i6 = 0; i6 < 9; i6++) {
this.elements[i6] = array[i6 + offset];
}
return this;
}
/**
* Writes the elements of this matrix to the given array. If no array is provided,
* the method returns a new instance.
*
* @param {Array} [array=[]] - The target array holding the matrix elements in column-major order.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Array} The matrix elements in column-major order.
*/
toArray(array = [], offset = 0) {
const te = this.elements;
array[offset] = te[0];
array[offset + 1] = te[1];
array[offset + 2] = te[2];
array[offset + 3] = te[3];
array[offset + 4] = te[4];
array[offset + 5] = te[5];
array[offset + 6] = te[6];
array[offset + 7] = te[7];
array[offset + 8] = te[8];
return array;
}
/**
* Returns a matrix with copied values from this instance.
*
* @return {Matrix3} A clone of this instance.
*/
clone() {
return new this.constructor().fromArray(this.elements);
}
};
var _m3 = /* @__PURE__ */ new Matrix3();
function arrayNeedsUint32(array) {
for (let i6 = array.length - 1; i6 >= 0; --i6) {
if (array[i6] >= 65535) return true;
}
return false;
}
function createElementNS(name) {
return document.createElementNS("http://www.w3.org/1999/xhtml", name);
}
function createCanvasElement() {
const canvas = createElementNS("canvas");
canvas.style.display = "block";
return canvas;
}
var _cache = {};
function warnOnce(message) {
if (message in _cache) return;
_cache[message] = true;
console.warn(message);
}
function probeAsync(gl, sync, interval) {
return new Promise(function(resolve, reject) {
function probe() {
switch (gl.clientWaitSync(sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0)) {
case gl.WAIT_FAILED:
reject();
break;
case gl.TIMEOUT_EXPIRED:
setTimeout(probe, interval);
break;
default:
resolve();
}
}
setTimeout(probe, interval);
});
}
var LINEAR_REC709_TO_XYZ = /* @__PURE__ */ new Matrix3().set(
0.4123908,
0.3575843,
0.1804808,
0.212639,
0.7151687,
0.0721923,
0.0193308,
0.1191948,
0.9505322
);
var XYZ_TO_LINEAR_REC709 = /* @__PURE__ */ new Matrix3().set(
3.2409699,
-1.5373832,
-0.4986108,
-0.9692436,
1.8759675,
0.0415551,
0.0556301,
-0.203977,
1.0569715
);
function createColorManagement() {
const ColorManagement2 = {
enabled: true,
workingColorSpace: LinearSRGBColorSpace,
/**
* Implementations of supported color spaces.
*
* Required:
* - primaries: chromaticity coordinates [ rx ry gx gy bx by ]
* - whitePoint: reference white [ x y ]
* - transfer: transfer function (pre-defined)
* - toXYZ: Matrix3 RGB to XYZ transform
* - fromXYZ: Matrix3 XYZ to RGB transform
* - luminanceCoefficients: RGB luminance coefficients
*
* Optional:
* - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace, toneMappingMode: 'extended' | 'standard' }
* - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }
*
* Reference:
* - https://www.russellcottrell.com/photo/matrixCalculator.htm
*/
spaces: {},
convert: function(color, sourceColorSpace, targetColorSpace) {
if (this.enabled === false || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) {
return color;
}
if (this.spaces[sourceColorSpace].transfer === SRGBTransfer) {
color.r = SRGBToLinear(color.r);
color.g = SRGBToLinear(color.g);
color.b = SRGBToLinear(color.b);
}
if (this.spaces[sourceColorSpace].primaries !== this.spaces[targetColorSpace].primaries) {
color.applyMatrix3(this.spaces[sourceColorSpace].toXYZ);
color.applyMatrix3(this.spaces[targetColorSpace].fromXYZ);
}
if (this.spaces[targetColorSpace].transfer === SRGBTransfer) {
color.r = LinearToSRGB(color.r);
color.g = LinearToSRGB(color.g);
color.b = LinearToSRGB(color.b);
}
return color;
},
workingToColorSpace: function(color, targetColorSpace) {
return this.convert(color, this.workingColorSpace, targetColorSpace);
},
colorSpaceToWorking: function(color, sourceColorSpace) {
return this.convert(color, sourceColorSpace, this.workingColorSpace);
},
getPrimaries: function(colorSpace) {
return this.spaces[colorSpace].primaries;
},
getTransfer: function(colorSpace) {
if (colorSpace === NoColorSpace) return LinearTransfer;
return this.spaces[colorSpace].transfer;
},
getToneMappingMode: function(colorSpace) {
return this.spaces[colorSpace].outputColorSpaceConfig.toneMappingMode || "standard";
},
getLuminanceCoefficients: function(target, colorSpace = this.workingColorSpace) {
return target.fromArray(this.spaces[colorSpace].luminanceCoefficients);
},
define: function(colorSpaces) {
Object.assign(this.spaces, colorSpaces);
},
// Internal APIs
_getMatrix: function(targetMatrix, sourceColorSpace, targetColorSpace) {
return targetMatrix.copy(this.spaces[sourceColorSpace].toXYZ).multiply(this.spaces[targetColorSpace].fromXYZ);
},
_getDrawingBufferColorSpace: function(colorSpace) {
return this.spaces[colorSpace].outputColorSpaceConfig.drawingBufferColorSpace;
},
_getUnpackColorSpace: function(colorSpace = this.workingColorSpace) {
return this.spaces[colorSpace].workingColorSpaceConfig.unpackColorSpace;
},
// Deprecated
fromWorkingColorSpace: function(color, targetColorSpace) {
warnOnce("THREE.ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace().");
return ColorManagement2.workingToColorSpace(color, targetColorSpace);
},
toWorkingColorSpace: function(color, sourceColorSpace) {
warnOnce("THREE.ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking().");
return ColorManagement2.colorSpaceToWorking(color, sourceColorSpace);
}
};
const REC709_PRIMARIES = [0.64, 0.33, 0.3, 0.6, 0.15, 0.06];
const REC709_LUMINANCE_COEFFICIENTS = [0.2126, 0.7152, 0.0722];
const D65 = [0.3127, 0.329];
ColorManagement2.define({
[LinearSRGBColorSpace]: {
primaries: REC709_PRIMARIES,
whitePoint: D65,
transfer: LinearTransfer,
toXYZ: LINEAR_REC709_TO_XYZ,
fromXYZ: XYZ_TO_LINEAR_REC709,
luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace },
outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
},
[SRGBColorSpace]: {
primaries: REC709_PRIMARIES,
whitePoint: D65,
transfer: SRGBTransfer,
toXYZ: LINEAR_REC709_TO_XYZ,
fromXYZ: XYZ_TO_LINEAR_REC709,
luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
}
});
return ColorManagement2;
}
var ColorManagement = /* @__PURE__ */ createColorManagement();
function SRGBToLinear(c5) {
return c5 < 0.04045 ? c5 * 0.0773993808 : Math.pow(c5 * 0.9478672986 + 0.0521327014, 2.4);
}
function LinearToSRGB(c5) {
return c5 < 31308e-7 ? c5 * 12.92 : 1.055 * Math.pow(c5, 0.41666) - 0.055;
}
var _canvas;
var ImageUtils = class {
/**
* Returns a data URI containing a representation of the given image.
*
* @param {(HTMLImageElement|HTMLCanvasElement)} image - The image object.
* @param {string} [type='image/png'] - Indicates the image format.
* @return {string} The data URI.
*/
static getDataURL(image, type = "image/png") {
if (/^data:/i.test(image.src)) {
return image.src;
}
if (typeof HTMLCanvasElement === "undefined") {
return image.src;
}
let canvas;
if (image instanceof HTMLCanvasElement) {
canvas = image;
} else {
if (_canvas === void 0) _canvas = createElementNS("canvas");
_canvas.width = image.width;
_canvas.height = image.height;
const context = _canvas.getContext("2d");
if (image instanceof ImageData) {
context.putImageData(image, 0, 0);
} else {
context.drawImage(image, 0, 0, image.width, image.height);
}
canvas = _canvas;
}
return canvas.toDataURL(type);
}
/**
* Converts the given sRGB image data to linear color space.
*
* @param {(HTMLImageElement|HTMLCanvasElement|ImageBitmap|Object)} image - The image object.
* @return {HTMLCanvasElement|Object} The converted image.
*/
static sRGBToLinear(image) {
if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) {
const canvas = createElementNS("canvas");
canvas.width = image.width;
canvas.height = image.height;
const context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
const imageData = context.getImageData(0, 0, image.width, image.height);
const data = imageData.data;
for (let i6 = 0; i6 < data.length; i6++) {
data[i6] = SRGBToLinear(data[i6] / 255) * 255;
}
context.putImageData(imageData, 0, 0);
return canvas;
} else if (image.data) {
const data = image.data.slice(0);
for (let i6 = 0; i6 < data.length; i6++) {
if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) {
data[i6] = Math.floor(SRGBToLinear(data[i6] / 255) * 255);
} else {
data[i6] = SRGBToLinear(data[i6]);
}
}
return {
data,
width: image.width,
height: image.height
};
} else {
console.warn("THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.");
return image;
}
}
};
var _sourceId = 0;
var Source = class {
/**
* Constructs a new video texture.
*
* @param {any} [data=null] - The data definition of a texture.
*/
constructor(data = null) {
this.isSource = true;
Object.defineProperty(this, "id", { value: _sourceId++ });
this.uuid = generateUUID();
this.data = data;
this.dataReady = true;
this.version = 0;
}
/**
* Returns the dimensions of the source into the given target vector.
*
* @param {(Vector2|Vector3)} target - The target object the result is written into.
* @return {(Vector2|Vector3)} The dimensions of the source.
*/
getSize(target) {
const data = this.data;
if (typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement) {
target.set(data.videoWidth, data.videoHeight, 0);
} else if (data instanceof VideoFrame) {
target.set(data.displayHeight, data.displayWidth, 0);
} else if (data !== null) {
target.set(data.width, data.height, data.depth || 0);
} else {
target.set(0, 0, 0);
}
return target;
}
/**
* When the property is set to `true`, the engine allocates the memory
* for the texture (if necessary) and triggers the actual texture upload
* to the GPU next time the source is used.
*
* @type {boolean}
* @default false
* @param {boolean} value
*/
set needsUpdate(value) {
if (value === true) this.version++;
}
/**
* Serializes the source into JSON.
*
* @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
* @return {Object} A JSON object representing the serialized source.
* @see {@link ObjectLoader#parse}
*/
toJSON(meta) {
const isRootObject = meta === void 0 || typeof meta === "string";
if (!isRootObject && meta.images[this.uuid] !== void 0) {
return meta.images[this.uuid];
}
const output = {
uuid: this.uuid,
url: ""
};
const data = this.data;
if (data !== null) {
let url;
if (Array.isArray(data)) {
url = [];
for (let i6 = 0, l3 = data.length; i6 < l3; i6++) {
if (data[i6].isDataTexture) {
url.push(serializeImage(data[i6].image));
} else {
url.push(serializeImage(data[i6]));
}
}
} else {
url = serializeImage(data);
}
output.url = url;
}
if (!isRootObject) {
meta.images[this.uuid] = output;
}
return output;
}
};
function serializeImage(image) {
if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) {
return ImageUtils.getDataURL(image);
} else {
if (image.data) {
return {
data: Array.from(image.data),
width: image.width,
height: image.height,
type: image.data.constructor.name
};
} else {
console.warn("THREE.Texture: Unable to serialize Texture.");
return {};
}
}
}
var _textureId = 0;
var _tempVec3 = /* @__PURE__ */ new Vector3();
var Texture = class _Texture extends EventDispatcher {
/**
* Constructs a new texture.
*
* @param {?Object} [image=Texture.DEFAULT_IMAGE] - The image holding the texture data.
* @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping.
* @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
* @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
* @param {number} [magFilter=LinearFilter] - The mag filter value.
* @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value.
* @param {number} [format=RGBAFormat] - The texture format.
* @param {number} [type=UnsignedByteType] - The texture type.
* @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value.
* @param {string} [colorSpace=NoColorSpace] - The color space.
*/
constructor(image = _Texture.DEFAULT_IMAGE, mapping = _Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = _Texture.DEFAULT_ANISOTROPY, colorSpace = NoColorSpace) {
super();
this.isTexture = true;
Object.defineProperty(this, "id", { value: _textureId++ });
this.uuid = generateUUID();
this.name = "";
this.source = new Source(image);
this.mipmaps = [];
this.mapping = mapping;
this.channel = 0;
this.wrapS = wrapS;
this.wrapT = wrapT;
this.magFilter = magFilter;
this.minFilter = minFilter;
this.anisotropy = anisotropy;
this.format = format;
this.internalFormat = null;
this.type = type;
this.offset = new Vector2(0, 0);
this.repeat = new Vector2(1, 1);
this.center = new Vector2(0, 0);
this.rotation = 0;
this.matrixAutoUpdate = true;
this.matrix = new Matrix3();
this.generateMipmaps = true;
this.premultiplyAlpha = false;
this.flipY = true;
this.unpackAlignment = 4;
this.colorSpace = colorSpace;
this.userData = {};
this.updateRanges = [];
this.version = 0;
this.onUpdate = null;
this.renderTarget = null;
this.isRenderTargetTexture = false;
this.isArrayTexture = image && image.depth && image.depth > 1 ? true : false;
this.pmremVersion = 0;
}
/**
* The width of the texture in pixels.
*/
get width() {
return this.source.getSize(_tempVec3).x;
}
/**
* The height of the texture in pixels.
*/
get height() {
return this.source.getSize(_tempVec3).y;
}
/**
* The depth of the texture in pixels.
*/
get depth() {
return this.source.getSize(_tempVec3).z;
}
/**
* The image object holding the texture data.
*
* @type {?Object}
*/
get image() {
return this.source.data;
}
set image(value = null) {
this.source.data = value;
}
/**
* Updates the texture transformation matrix from the from the properties {@link Texture#offset},
* {@link Texture#repeat}, {@link Texture#rotation}, and {@link Texture#center}.
*/
updateMatrix() {
this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y);
}
/**
* Adds a range of data in the data texture to be updated on the GPU.
*
* @param {number} start - Position at which to start update.
* @param {number} count - The number of components to update.
*/
addUpdateRange(start, count) {
this.updateRanges.push({ start, count });
}
/**
* Clears the update ranges.
*/
clearUpdateRanges() {
this.updateRanges.length = 0;
}
/**
* Returns a new texture with copied values from this instance.
*
* @return {Texture} A clone of this instance.
*/
clone() {
return new this.constructor().copy(this);
}
/**
* Copies the values of the given texture to this instance.
*
* @param {Texture} source - The texture to copy.
* @return {Texture} A reference to this instance.
*/
copy(source) {
this.name = source.name;
this.source = source.source;
this.mipmaps = source.mipmaps.slice(0);
this.mapping = source.mapping;
this.channel = source.channel;
this.wrapS = source.wrapS;
this.wrapT = source.wrapT;
this.magFilter = source.magFilter;
this.minFilter = source.minFilter;
this.anisotropy = source.anisotropy;
this.format = source.format;
this.internalFormat = source.internalFormat;
this.type = source.type;
this.offset.copy(source.offset);
this.repeat.copy(source.repeat);
this.center.copy(source.center);
this.rotation = source.rotation;
this.matrixAutoUpdate = source.matrixAutoUpdate;
this.matrix.copy(source.matrix);
this.generateMipmaps = source.generateMipmaps;
this.premultiplyAlpha = source.premultiplyAlpha;
this.flipY = source.flipY;
this.unpackAlignment = source.unpackAlignment;
this.colorSpace = source.colorSpace;
this.renderTarget = source.renderTarget;
this.isRenderTargetTexture = source.isRenderTargetTexture;
this.isArrayTexture = source.isArrayTexture;
this.userData = JSON.parse(JSON.stringify(source.userData));
this.needsUpdate = true;
return this;
}
/**
* Sets this texture's properties based on `values`.
* @param {Object} values - A container with texture parameters.
*/
setValues(values) {
for (const key in values) {
const newValue = values[key];
if (newValue === void 0) {
console.warn(`THREE.Texture.setValues(): parameter '${key}' has value of undefined.`);
continue;
}
const currentValue = this[key];
if (currentValue === void 0) {
console.warn(`THREE.Texture.setValues(): property '${key}' does not exist.`);
continue;
}
if (currentValue && newValue && (currentValue.isVector2 && newValue.isVector2)) {
currentValue.copy(newValue);
} else if (currentValue && newValue && (currentValue.isVector3 && newValue.isVector3)) {
currentValue.copy(newValue);
} else if (currentValue && newValue && (currentValue.isMatrix3 && newValue.isMatrix3)) {
currentValue.copy(newValue);
} else {
this[key] = newValue;
}
}
}
/**
* Serializes the texture into JSON.
*
* @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
* @return {Object} A JSON object representing the serialized texture.
* @see {@link ObjectLoader#parse}
*/
toJSON(meta) {
const isRootObject = meta === void 0 || typeof meta === "string";
if (!isRootObject && meta.textures[this.uuid] !== void 0) {
return meta.textures[this.uuid];
}
const output = {
metadata: {
version: 4.7,
type: "Texture",
generator: "Texture.toJSON"
},
uuid: this.uuid,
name: this.name,
image: this.source.toJSON(meta).uuid,
mapping: this.mapping,
channel: this.channel,
repeat: [this.repeat.x, this.repeat.y],
offset: [this.offset.x, this.offset.y],
center: [this.center.x, this.center.y],
rotation: this.rotation,
wrap: [this.wrapS, this.wrapT],
format: this.format,
internalFormat: this.internalFormat,
type: this.type,
colorSpace: this.colorSpace,
minFilter: this.minFilter,
magFilter: this.magFilter,
anisotropy: this.anisotropy,
flipY: this.flipY,
generateMipmaps: this.generateMipmaps,
premultiplyAlpha: this.premultiplyAlpha,
unpackAlignment: this.unpackAlignment
};
if (Object.keys(this.userData).length > 0) output.userData = this.userData;
if (!isRootObject) {
meta.textures[this.uuid] = output;
}
return output;
}
/**
* Frees the GPU-related resources allocated by this instance. Call this
* method whenever this instance is no longer used in your app.
*
* @fires Texture#dispose
*/
dispose() {
this.dispatchEvent({ type: "dispose" });
}
/**
* Transforms the given uv vector with the textures uv transformation matrix.
*
* @param {Vector2} uv - The uv vector.
* @return {Vector2} The transformed uv vector.
*/
transformUv(uv) {
if (this.mapping !== UVMapping) return uv;
uv.applyMatrix3(this.matrix);
if (uv.x < 0 || uv.x > 1) {
switch (this.wrapS) {
case RepeatWrapping:
uv.x = uv.x - Math.floor(uv.x);
break;
case ClampToEdgeWrapping:
uv.x = uv.x < 0 ? 0 : 1;
break;
case MirroredRepeatWrapping:
if (Math.abs(Math.floor(uv.x) % 2) === 1) {
uv.x = Math.ceil(uv.x) - uv.x;
} else {
uv.x = uv.x - Math.floor(uv.x);
}
break;
}
}
if (uv.y < 0 || uv.y > 1) {
switch (this.wrapT) {
case RepeatWrapping:
uv.y = uv.y - Math.floor(uv.y);
break;
case ClampToEdgeWrapping:
uv.y = uv.y < 0 ? 0 : 1;
break;
case MirroredRepeatWrapping:
if (Math.abs(Math.floor(uv.y) % 2) === 1) {
uv.y = Math.ceil(uv.y) - uv.y;
} else {
uv.y = uv.y - Math.floor(uv.y);
}
break;
}
}
if (this.flipY) {
uv.y = 1 - uv.y;
}
return uv;
}
/**
* Setting this property to `true` indicates the engine the texture
* must be updated in the next render. This triggers a texture upload
* to the GPU and ensures correct texture parameter configuration.
*
* @type {boolean}
* @default false
* @param {boolean} value
*/
set needsUpdate(value) {
if (value === true) {
this.version++;
this.source.needsUpdate = true;
}
}
/**
* Setting this property to `true` indicates the engine the PMREM
* must be regenerated.
*
* @type {boolean}
* @default false
* @param {boolean} value
*/
set needsPMREMUpdate(value) {
if (value === true) {
this.pmremVersion++;
}
}
};
Texture.DEFAULT_IMAGE = null;
Texture.DEFAULT_MAPPING = UVMapping;
Texture.DEFAULT_ANISOTROPY = 1;
var Vector4 = class _Vector4 {
/**
* Constructs a new 4D vector.
*
* @param {number} [x=0] - The x value of this vector.
* @param {number} [y=0] - The y value of this vector.
* @param {number} [z=0] - The z value of this vector.
* @param {number} [w=1] - The w value of this vector.
*/
constructor(x2 = 0, y3 = 0, z2 = 0, w2 = 1) {
_Vector4.prototype.isVector4 = true;
this.x = x2;
this.y = y3;
this.z = z2;
this.w = w2;
}
/**
* Alias for {@link Vector4#z}.
*
* @type {number}
*/
get width() {
return this.z;
}
set width(value) {
this.z = value;
}
/**
* Alias for {@link Vector4#w}.
*
* @type {number}
*/
get height() {
return this.w;
}
set height(value) {
this.w = value;
}
/**
* Sets the vector components.
*
* @param {number} x - The value of the x component.
* @param {number} y - The value of the y component.
* @param {number} z - The value of the z component.
* @param {number} w - The value of the w component.
* @return {Vector4} A reference to this vector.
*/
set(x2, y3, z2, w2) {
this.x = x2;
this.y = y3;
this.z = z2;
this.w = w2;
return this;
}
/**
* Sets the vector components to the same value.
*
* @param {number} scalar - The value to set for all vector components.
* @return {Vector4} A reference to this vector.
*/
setScalar(scalar) {
this.x = scalar;
this.y = scalar;
this.z = scalar;
this.w = scalar;
return this;
}
/**
* Sets the vector's x component to the given value
*
* @param {number} x - The value to set.
* @return {Vector4} A reference to this vector.
*/
setX(x2) {
this.x = x2;
return this;
}
/**
* Sets the vector's y component to the given value
*
* @param {number} y - The value to set.
* @return {Vector4} A reference to this vector.
*/
setY(y3) {
this.y = y3;
return this;
}
/**
* Sets the vector's z component to the given value
*
* @param {number} z - The value to set.
* @return {Vector4} A reference to this vector.
*/
setZ(z2) {
this.z = z2;
return this;
}
/**
* Sets the vector's w component to the given value
*
* @param {number} w - The value to set.
* @return {Vector4} A reference to this vector.
*/
setW(w2) {
this.w = w2;
return this;
}
/**
* Allows to set a vector component with an index.
*
* @param {number} index - The component index. `0` equals to x, `1` equals to y,
* `2` equals to z, `3` equals to w.
* @param {number} value - The value to set.
* @return {Vector4} A reference to this vector.
*/
setComponent(index, value) {
switch (index) {
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
case 2:
this.z = value;
break;
case 3:
this.w = value;
break;
default:
throw new Error("index is out of range: " + index);
}
return this;
}
/**
* Returns the value of the vector component which matches the given index.
*
* @param {number} index - The component index. `0` equals to x, `1` equals to y,
* `2` equals to z, `3` equals to w.
* @return {number} A vector component value.
*/
getComponent(index) {
switch (index) {
case 0:
return this.x;
case 1:
return this.y;
case 2:
return this.z;
case 3:
return this.w;
default:
throw new Error("index is out of range: " + index);
}
}
/**
* Returns a new vector with copied values from this instance.
*
* @return {Vector4} A clone of this instance.
*/
clone() {
return new this.constructor(this.x, this.y, this.z, this.w);
}
/**
* Copies the values of the given vector to this instance.
*
* @param {Vector3|Vector4} v - The vector to copy.
* @return {Vector4} A reference to this vector.
*/
copy(v2) {
this.x = v2.x;
this.y = v2.y;
this.z = v2.z;
this.w = v2.w !== void 0 ? v2.w : 1;
return this;
}
/**
* Adds the given vector to this instance.
*
* @param {Vector4} v - The vector to add.
* @return {Vector4} A reference to this vector.
*/
add(v2) {
this.x += v2.x;
this.y += v2.y;
this.z += v2.z;
this.w += v2.w;
return this;
}
/**
* Adds the given scalar value to all components of this instance.
*
* @param {number} s - The scalar to add.
* @return {Vector4} A reference to this vector.
*/
addScalar(s5) {
this.x += s5;
this.y += s5;
this.z += s5;
this.w += s5;
return this;
}
/**
* Adds the given vectors and stores the result in this instance.
*
* @param {Vector4} a - The first vector.
* @param {Vector4} b - The second vector.
* @return {Vector4} A reference to this vector.
*/
addVectors(a3, b3) {
this.x = a3.x + b3.x;
this.y = a3.y + b3.y;
this.z = a3.z + b3.z;
this.w = a3.w + b3.w;
return this;
}
/**
* Adds the given vector scaled by the given factor to this instance.
*
* @param {Vector4} v - The vector.
* @param {number} s - The factor that scales `v`.
* @return {Vector4} A reference to this vector.
*/
addScaledVector(v2, s5) {
this.x += v2.x * s5;
this.y += v2.y * s5;
this.z += v2.z * s5;
this.w += v2.w * s5;
return this;
}
/**
* Subtracts the given vector from this instance.
*
* @param {Vector4} v - The vector to subtract.
* @return {Vector4} A reference to this vector.
*/
sub(v2) {
this.x -= v2.x;
this.y -= v2.y;
this.z -= v2.z;
this.w -= v2.w;
return this;
}
/**
* Subtracts the given scalar value from all components of this instance.
*
* @param {number} s - The scalar to subtract.
* @return {Vector4} A reference to this vector.
*/
subScalar(s5) {
this.x -= s5;
this.y -= s5;
this.z -= s5;
this.w -= s5;
return this;
}
/**
* Subtracts the given vectors and stores the result in this instance.
*
* @param {Vector4} a - The first vector.
* @param {Vector4} b - The second vector.
* @return {Vector4} A reference to this vector.
*/
subVectors(a3, b3) {
this.x = a3.x - b3.x;
this.y = a3.y - b3.y;
this.z = a3.z - b3.z;
this.w = a3.w - b3.w;
return this;
}
/**
* Multiplies the given vector with this instance.
*
* @param {Vector4} v - The vector to multiply.
* @return {Vector4} A reference to this vector.
*/
multiply(v2) {
this.x *= v2.x;
this.y *= v2.y;
this.z *= v2.z;
this.w *= v2.w;
return this;
}
/**
* Multiplies the given scalar value with all components of this instance.
*
* @param {number} scalar - The scalar to multiply.
* @return {Vector4} A reference to this vector.
*/
multiplyScalar(scalar) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
this.w *= scalar;
return this;
}
/**
* Multiplies this vector with the given 4x4 matrix.
*
* @param {Matrix4} m - The 4x4 matrix.
* @return {Vector4} A reference to this vector.
*/
applyMatrix4(m2) {
const x2 = this.x, y3 = this.y, z2 = this.z, w2 = this.w;
const e8 = m2.elements;
this.x = e8[0] * x2 + e8[4] * y3 + e8[8] * z2 + e8[12] * w2;
this.y = e8[1] * x2 + e8[5] * y3 + e8[9] * z2 + e8[13] * w2;
this.z = e8[2] * x2 + e8[6] * y3 + e8[10] * z2 + e8[14] * w2;
this.w = e8[3] * x2 + e8[7] * y3 + e8[11] * z2 + e8[15] * w2;
return this;
}
/**
* Divides this instance by the given vector.
*
* @param {Vector4} v - The vector to divide.
* @return {Vector4} A reference to this vector.
*/
divide(v2) {
this.x /= v2.x;
this.y /= v2.y;
this.z /= v2.z;
this.w /= v2.w;
return this;
}
/**
* Divides this vector by the given scalar.
*
* @param {number} scalar - The scalar to divide.
* @return {Vector4} A reference to this vector.
*/
divideScalar(scalar) {
return this.multiplyScalar(1 / scalar);
}
/**
* Sets the x, y and z components of this
* vector to the quaternion's axis and w to the angle.
*
* @param {Quaternion} q - The Quaternion to set.
* @return {Vector4} A reference to this vector.
*/
setAxisAngleFromQuaternion(q) {
this.w = 2 * Math.acos(q.w);
const s5 = Math.sqrt(1 - q.w * q.w);
if (s5 < 1e-4) {
this.x = 1;
this.y = 0;
this.z = 0;
} else {
this.x = q.x / s5;
this.y = q.y / s5;
this.z = q.z / s5;
}
return this;
}
/**
* Sets the x, y and z components of this
* vector to the axis of rotation and w to the angle.
*
* @param {Matrix4} m - A 4x4 matrix of which the upper left 3x3 matrix is a pure rotation matrix.
* @return {Vector4} A reference to this vector.
*/
setAxisAngleFromRotationMatrix(m2) {
let angle, x2, y3, z2;
const epsilon = 0.01, epsilon2 = 0.1, te = m2.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10];
if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) {
if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) {
this.set(1, 0, 0, 0);
return this;
}
angle = Math.PI;
const xx = (m11 + 1) / 2;
const yy = (m22 + 1) / 2;
const zz = (m33 + 1) / 2;
const xy = (m12 + m21) / 4;
const xz = (m13 + m31) / 4;
const yz = (m23 + m32) / 4;
if (xx > yy && xx > zz) {
if (xx < epsilon) {
x2 = 0;
y3 = 0.707106781;
z2 = 0.707106781;
} else {
x2 = Math.sqrt(xx);
y3 = xy / x2;
z2 = xz / x2;
}
} else if (yy > zz) {
if (yy < epsilon) {
x2 = 0.707106781;
y3 = 0;
z2 = 0.707106781;
} else {
y3 = Math.sqrt(yy);
x2 = xy / y3;
z2 = yz / y3;
}
} else {
if (zz < epsilon) {
x2 = 0.707106781;
y3 = 0.707106781;
z2 = 0;
} else {
z2 = Math.sqrt(zz);
x2 = xz / z2;
y3 = yz / z2;
}
}
this.set(x2, y3, z2, angle);
return this;
}
let s5 = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12));
if (Math.abs(s5) < 1e-3) s5 = 1;
this.x = (m32 - m23) / s5;
this.y = (m13 - m31) / s5;
this.z = (m21 - m12) / s5;
this.w = Math.acos((m11 + m22 + m33 - 1) / 2);
return this;
}
/**
* Sets the vector components to the position elements of the
* given transformation matrix.
*
* @param {Matrix4} m - The 4x4 matrix.
* @return {Vector4} A reference to this vector.
*/
setFromMatrixPosition(m2) {
const e8 = m2.elements;
this.x = e8[12];
this.y = e8[13];
this.z = e8[14];
this.w = e8[15];
return this;
}
/**
* If this vector's x, y, z or w value is greater than the given vector's x, y, z or w
* value, replace that value with the corresponding min value.
*
* @param {Vector4} v - The vector.
* @return {Vector4} A reference to this vector.
*/
min(v2) {
this.x = Math.min(this.x, v2.x);
this.y = Math.min(this.y, v2.y);
this.z = Math.min(this.z, v2.z);
this.w = Math.min(this.w, v2.w);
return this;
}
/**
* If this vector's x, y, z or w value is less than the given vector's x, y, z or w
* value, replace that value with the corresponding max value.
*
* @param {Vector4} v - The vector.
* @return {Vector4} A reference to this vector.
*/
max(v2) {
this.x = Math.max(this.x, v2.x);
this.y = Math.max(this.y, v2.y);
this.z = Math.max(this.z, v2.z);
this.w = Math.max(this.w, v2.w);
return this;
}
/**
* If this vector's x, y, z or w value is greater than the max vector's x, y, z or w
* value, it is replaced by the corresponding value.
* If this vector's x, y, z or w value is less than the min vector's x, y, z or w value,
* it is replaced by the corresponding value.
*
* @param {Vector4} min - The minimum x, y and z values.
* @param {Vector4} max - The maximum x, y and z values in the desired range.
* @return {Vector4} A reference to this vector.
*/
clamp(min, max) {
this.x = clamp(this.x, min.x, max.x);
this.y = clamp(this.y, min.y, max.y);
this.z = clamp(this.z, min.z, max.z);
this.w = clamp(this.w, min.w, max.w);
return this;
}
/**
* If this vector's x, y, z or w values are greater than the max value, they are
* replaced by the max value.
* If this vector's x, y, z or w values are less than the min value, they are
* replaced by the min value.
*
* @param {number} minVal - The minimum value the components will be clamped to.
* @param {number} maxVal - The maximum value the components will be clamped to.
* @return {Vector4} A reference to this vector.
*/
clampScalar(minVal, maxVal) {
this.x = clamp(this.x, minVal, maxVal);
this.y = clamp(this.y, minVal, maxVal);
this.z = clamp(this.z, minVal, maxVal);
this.w = clamp(this.w, minVal, maxVal);
return this;
}
/**
* If this vector's length is greater than the max value, it is replaced by
* the max value.
* If this vector's length is less than the min value, it is replaced by the
* min value.
*
* @param {number} min - The minimum value the vector length will be clamped to.
* @param {number} max - The maximum value the vector length will be clamped to.
* @return {Vector4} A reference to this vector.
*/
clampLength(min, max) {
const length = this.length();
return this.divideScalar(length || 1).multiplyScalar(clamp(length, min, max));
}
/**
* The components of this vector are rounded down to the nearest integer value.
*
* @return {Vector4} A reference to this vector.
*/
floor() {
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
this.z = Math.floor(this.z);
this.w = Math.floor(this.w);
return this;
}
/**
* The components of this vector are rounded up to the nearest integer value.
*
* @return {Vector4} A reference to this vector.
*/
ceil() {
this.x = Math.ceil(this.x);
this.y = Math.ceil(this.y);
this.z = Math.ceil(this.z);
this.w = Math.ceil(this.w);
return this;
}
/**
* The components of this vector are rounded to the nearest integer value
*
* @return {Vector4} A reference to this vector.
*/
round() {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
this.z = Math.round(this.z);
this.w = Math.round(this.w);
return this;
}
/**
* The components of this vector are rounded towards zero (up if negative,
* down if positive) to an integer value.
*
* @return {Vector4} A reference to this vector.
*/
roundToZero() {
this.x = Math.trunc(this.x);
this.y = Math.trunc(this.y);
this.z = Math.trunc(this.z);
this.w = Math.trunc(this.w);
return this;
}
/**
* Inverts this vector - i.e. sets x = -x, y = -y, z = -z, w = -w.
*
* @return {Vector4} A reference to this vector.
*/
negate() {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
this.w = -this.w;
return this;
}
/**
* Calculates the dot product of the given vector with this instance.
*
* @param {Vector4} v - The vector to compute the dot product with.
* @return {number} The result of the dot product.
*/
dot(v2) {
return this.x * v2.x + this.y * v2.y + this.z * v2.z + this.w * v2.w;
}
/**
* Computes the square of the Euclidean length (straight-line length) from
* (0, 0, 0, 0) to (x, y, z, w). If you are comparing the lengths of vectors, you should
* compare the length squared instead as it is slightly more efficient to calculate.
*
* @return {number} The square length of this vector.
*/
lengthSq() {
return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
}
/**
* Computes the Euclidean length (straight-line length) from (0, 0, 0, 0) to (x, y, z, w).
*
* @return {number} The length of this vector.
*/
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
}
/**
* Computes the Manhattan length of this vector.
*
* @return {number} The length of this vector.
*/
manhattanLength() {
return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w);
}
/**
* Converts this vector to a unit vector - that is, sets it equal to a vector
* with the same direction as this one, but with a vector length of `1`.
*
* @return {Vector4} A reference to this vector.
*/
normalize() {
return this.divideScalar(this.length() || 1);
}
/**
* Sets this vector to a vector with the same direction as this one, but
* with the specified length.
*
* @param {number} length - The new length of this vector.
* @return {Vector4} A reference to this vector.
*/
setLength(length) {
return this.normalize().multiplyScalar(length);
}
/**
* Linearly interpolates between the given vector and this instance, where
* alpha is the percent distance along the line - alpha = 0 will be this
* vector, and alpha = 1 will be the given one.
*
* @param {Vector4} v - The vector to interpolate towards.
* @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
* @return {Vector4} A reference to this vector.
*/
lerp(v2, alpha) {
this.x += (v2.x - this.x) * alpha;
this.y += (v2.y - this.y) * alpha;
this.z += (v2.z - this.z) * alpha;
this.w += (v2.w - this.w) * alpha;
return this;
}
/**
* Linearly interpolates between the given vectors, where alpha is the percent
* distance along the line - alpha = 0 will be first vector, and alpha = 1 will
* be the second one. The result is stored in this instance.
*
* @param {Vector4} v1 - The first vector.
* @param {Vector4} v2 - The second vector.
* @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
* @return {Vector4} A reference to this vector.
*/
lerpVectors(v1, v2, alpha) {
this.x = v1.x + (v2.x - v1.x) * alpha;
this.y = v1.y + (v2.y - v1.y) * alpha;
this.z = v1.z + (v2.z - v1.z) * alpha;
this.w = v1.w + (v2.w - v1.w) * alpha;
return this;
}
/**
* Returns `true` if this vector is equal with the given one.
*
* @param {Vector4} v - The vector to test for equality.
* @return {boolean} Whether this vector is equal with the given one.
*/
equals(v2) {
return v2.x === this.x && v2.y === this.y && v2.z === this.z && v2.w === this.w;
}
/**
* Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`,
* z value to be `array[ offset + 2 ]`, w value to be `array[ offset + 3 ]`.
*
* @param {Array} array - An array holding the vector component values.
* @param {number} [offset=0] - The offset into the array.
* @return {Vector4} A reference to this vector.
*/
fromArray(array, offset = 0) {
this.x = array[offset];
this.y = array[offset + 1];
this.z = array[offset + 2];
this.w = array[offset + 3];
return this;
}
/**
* Writes the components of this vector to the given array. If no array is provided,
* the method returns a new instance.
*
* @param {Array} [array=[]] - The target array holding the vector components.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Array} The vector components.
*/
toArray(array = [], offset = 0) {
array[offset] = this.x;
array[offset + 1] = this.y;
array[offset + 2] = this.z;
array[offset + 3] = this.w;
return array;
}
/**
* Sets the components of this vector from the given buffer attribute.
*
* @param {BufferAttribute} attribute - The buffer attribute holding vector data.
* @param {number} index - The index into the attribute.
* @return {Vector4} A reference to this vector.
*/
fromBufferAttribute(attribute, index) {
this.x = attribute.getX(index);
this.y = attribute.getY(index);
this.z = attribute.getZ(index);
this.w = attribute.getW(index);
return this;
}
/**
* Sets each component of this vector to a pseudo-random value between `0` and
* `1`, excluding `1`.
*
* @return {Vector4} A reference to this vector.
*/
random() {
this.x = Math.random();
this.y = Math.random();
this.z = Math.random();
this.w = Math.random();
return this;
}
*[Symbol.iterator]() {
yield this.x;
yield this.y;
yield this.z;
yield this.w;
}
};
var RenderTarget = class extends EventDispatcher {
/**
* Render target options.
*
* @typedef {Object} RenderTarget~Options
* @property {boolean} [generateMipmaps=false] - Whether to generate mipmaps or not.
* @property {number} [magFilter=LinearFilter] - The mag filter.
* @property {number} [minFilter=LinearFilter] - The min filter.
* @property {number} [format=RGBAFormat] - The texture format.
* @property {number} [type=UnsignedByteType] - The texture type.
* @property {?string} [internalFormat=null] - The texture's internal format.
* @property {number} [wrapS=ClampToEdgeWrapping] - The texture's uv wrapping mode.
* @property {number} [wrapT=ClampToEdgeWrapping] - The texture's uv wrapping mode.
* @property {number} [anisotropy=1] - The texture's anisotropy value.
* @property {string} [colorSpace=NoColorSpace] - The texture's color space.
* @property {boolean} [depthBuffer=true] - Whether to allocate a depth buffer or not.
* @property {boolean} [stencilBuffer=false] - Whether to allocate a stencil buffer or not.
* @property {boolean} [resolveDepthBuffer=true] - Whether to resolve the depth buffer or not.
* @property {boolean} [resolveStencilBuffer=true] - Whether to resolve the stencil buffer or not.
* @property {?Texture} [depthTexture=null] - Reference to a depth texture.
* @property {number} [samples=0] - The MSAA samples count.
* @property {number} [count=1] - Defines the number of color attachments . Must be at least `1`.
* @property {number} [depth=1] - The texture depth.
* @property {boolean} [multiview=false] - Whether this target is used for multiview rendering.
*/
/**
* Constructs a new render target.
*
* @param {number} [width=1] - The width of the render target.
* @param {number} [height=1] - The height of the render target.
* @param {RenderTarget~Options} [options] - The configuration object.
*/
constructor(width = 1, height = 1, options = {}) {
super();
options = Object.assign({
generateMipmaps: false,
internalFormat: null,
minFilter: LinearFilter,
depthBuffer: true,
stencilBuffer: false,
resolveDepthBuffer: true,
resolveStencilBuffer: true,
depthTexture: null,
samples: 0,
count: 1,
depth: 1,
multiview: false
}, options);
this.isRenderTarget = true;
this.width = width;
this.height = height;
this.depth = options.depth;
this.scissor = new Vector4(0, 0, width, height);
this.scissorTest = false;
this.viewport = new Vector4(0, 0, width, height);
const image = { width, height, depth: options.depth };
const texture = new Texture(image);
this.textures = [];
const count = options.count;
for (let i6 = 0; i6 < count; i6++) {
this.textures[i6] = texture.clone();
this.textures[i6].isRenderTargetTexture = true;
this.textures[i6].renderTarget = this;
}
this._setTextureOptions(options);
this.depthBuffer = options.depthBuffer;
this.stencilBuffer = options.stencilBuffer;
this.resolveDepthBuffer = options.resolveDepthBuffer;
this.resolveStencilBuffer = options.resolveStencilBuffer;
this._depthTexture = null;
this.depthTexture = options.depthTexture;
this.samples = options.samples;
this.multiview = options.multiview;
}
_setTextureOptions(options = {}) {
const values = {
minFilter: LinearFilter,
generateMipmaps: false,
flipY: false,
internalFormat: null
};
if (options.mapping !== void 0) values.mapping = options.mapping;
if (options.wrapS !== void 0) values.wrapS = options.wrapS;
if (options.wrapT !== void 0) values.wrapT = options.wrapT;
if (options.wrapR !== void 0) values.wrapR = options.wrapR;
if (options.magFilter !== void 0) values.magFilter = options.magFilter;
if (options.minFilter !== void 0) values.minFilter = options.minFilter;
if (options.format !== void 0) values.format = options.format;
if (options.type !== void 0) values.type = options.type;
if (options.anisotropy !== void 0) values.anisotropy = options.anisotropy;
if (options.colorSpace !== void 0) values.colorSpace = options.colorSpace;
if (options.flipY !== void 0) values.flipY = options.flipY;
if (options.generateMipmaps !== void 0) values.generateMipmaps = options.generateMipmaps;
if (options.internalFormat !== void 0) values.internalFormat = options.internalFormat;
for (let i6 = 0; i6 < this.textures.length; i6++) {
const texture = this.textures[i6];
texture.setValues(values);
}
}
/**
* The texture representing the default color attachment.
*
* @type {Texture}
*/
get texture() {
return this.textures[0];
}
set texture(value) {
this.textures[0] = value;
}
set depthTexture(current) {
if (this._depthTexture !== null) this._depthTexture.renderTarget = null;
if (current !== null) current.renderTarget = this;
this._depthTexture = current;
}
/**
* Instead of saving the depth in a renderbuffer, a texture
* can be used instead which is useful for further processing
* e.g. in context of post-processing.
*
* @type {?DepthTexture}
* @default null
*/
get depthTexture() {
return this._depthTexture;
}
/**
* Sets the size of this render target.
*
* @param {number} width - The width.
* @param {number} height - The height.
* @param {number} [depth=1] - The depth.
*/
setSize(width, height, depth = 1) {
if (this.width !== width || this.height !== height || this.depth !== depth) {
this.width = width;
this.height = height;
this.depth = depth;
for (let i6 = 0, il = this.textures.length; i6 < il; i6++) {
this.textures[i6].image.width = width;
this.textures[i6].image.height = height;
this.textures[i6].image.depth = depth;
this.textures[i6].isArrayTexture = this.textures[i6].image.depth > 1;
}
this.dispose();
}
this.viewport.set(0, 0, width, height);
this.scissor.set(0, 0, width, height);
}
/**
* Returns a new render target with copied values from this instance.
*
* @return {RenderTarget} A clone of this instance.
*/
clone() {
return new this.constructor().copy(this);
}
/**
* Copies the settings of the given render target. This is a structural copy so
* no resources are shared between render targets after the copy. That includes
* all MRT textures and the depth texture.
*
* @param {RenderTarget} source - The render target to copy.
* @return {RenderTarget} A reference to this instance.
*/
copy(source) {
this.width = source.width;
this.height = source.height;
this.depth = source.depth;
this.scissor.copy(source.scissor);
this.scissorTest = source.scissorTest;
this.viewport.copy(source.viewport);
this.textures.length = 0;
for (let i6 = 0, il = source.textures.length; i6 < il; i6++) {
this.textures[i6] = source.textures[i6].clone();
this.textures[i6].isRenderTargetTexture = true;
this.textures[i6].renderTarget = this;
const image = Object.assign({}, source.textures[i6].image);
this.textures[i6].source = new Source(image);
}
this.depthBuffer = source.depthBuffer;
this.stencilBuffer = source.stencilBuffer;
this.resolveDepthBuffer = source.resolveDepthBuffer;
this.resolveStencilBuffer = source.resolveStencilBuffer;
if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone();
this.samples = source.samples;
return this;
}
/**
* Frees the GPU-related resources allocated by this instance. Call this
* method whenever this instance is no longer used in your app.
*
* @fires RenderTarget#dispose
*/
dispose() {
this.dispatchEvent({ type: "dispose" });
}
};
var WebGLRenderTarget = class extends RenderTarget {
/**
* Constructs a new 3D render target.
*
* @param {number} [width=1] - The width of the render target.
* @param {number} [height=1] - The height of the render target.
* @param {RenderTarget~Options} [options] - The configuration object.
*/
constructor(width = 1, height = 1, options = {}) {
super(width, height, options);
this.isWebGLRenderTarget = true;
}
};
var DataArrayTexture = class extends Texture {
/**
* Constructs a new data array texture.
*
* @param {?TypedArray} [data=null] - The buffer data.
* @param {number} [width=1] - The width of the texture.
* @param {number} [height=1] - The height of the texture.
* @param {number} [depth=1] - The depth of the texture.
*/
constructor(data = null, width = 1, height = 1, depth = 1) {
super(null);
this.isDataArrayTexture = true;
this.image = { data, width, height, depth };
this.magFilter = NearestFilter;
this.minFilter = NearestFilter;
this.wrapR = ClampToEdgeWrapping;
this.generateMipmaps = false;
this.flipY = false;
this.unpackAlignment = 1;
this.layerUpdates = /* @__PURE__ */ new Set();
}
/**
* Describes that a specific layer of the texture needs to be updated.
* Normally when {@link Texture#needsUpdate} is set to `true`, the
* entire data texture array is sent to the GPU. Marking specific
* layers will only transmit subsets of all mipmaps associated with a
* specific depth in the array which is often much more performant.
*
* @param {number} layerIndex - The layer index that should be updated.
*/
addLayerUpdate(layerIndex) {
this.layerUpdates.add(layerIndex);
}
/**
* Resets the layer updates registry.
*/
clearLayerUpdates() {
this.layerUpdates.clear();
}
};
var Data3DTexture = class extends Texture {
/**
* Constructs a new data array texture.
*
* @param {?TypedArray} [data=null] - The buffer data.
* @param {number} [width=1] - The width of the texture.
* @param {number} [height=1] - The height of the texture.
* @param {number} [depth=1] - The depth of the texture.
*/
constructor(data = null, width = 1, height = 1, depth = 1) {
super(null);
this.isData3DTexture = true;
this.image = { data, width, height, depth };
this.magFilter = NearestFilter;
this.minFilter = NearestFilter;
this.wrapR = ClampToEdgeWrapping;
this.generateMipmaps = false;
this.flipY = false;
this.unpackAlignment = 1;
}
};
var Box3 = class {
/**
* Constructs a new bounding box.
*
* @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box.
* @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box.
*/
constructor(min = new Vector3(Infinity, Infinity, Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) {
this.isBox3 = true;
this.min = min;
this.max = max;
}
/**
* Sets the lower and upper boundaries of this box.
* Please note that this method only copies the values from the given objects.
*
* @param {Vector3} min - The lower boundary of the box.
* @param {Vector3} max - The upper boundary of the box.
* @return {Box3} A reference to this bounding box.
*/
set(min, max) {
this.min.copy(min);
this.max.copy(max);
return this;
}
/**
* Sets the upper and lower bounds of this box so it encloses the position data
* in the given array.
*
* @param {Array} array - An array holding 3D position data.
* @return {Box3} A reference to this bounding box.
*/
setFromArray(array) {
this.makeEmpty();
for (let i6 = 0, il = array.length; i6 < il; i6 += 3) {
this.expandByPoint(_vector$b.fromArray(array, i6));
}
return this;
}
/**
* Sets the upper and lower bounds of this box so it encloses the position data
* in the given buffer attribute.
*
* @param {BufferAttribute} attribute - A buffer attribute holding 3D position data.
* @return {Box3} A reference to this bounding box.
*/
setFromBufferAttribute(attribute) {
this.makeEmpty();
for (let i6 = 0, il = attribute.count; i6 < il; i6++) {
this.expandByPoint(_vector$b.fromBufferAttribute(attribute, i6));
}
return this;
}
/**
* Sets the upper and lower bounds of this box so it encloses the position data
* in the given array.
*
* @param {Array} points - An array holding 3D position data as instances of {@link Vector3}.
* @return {Box3} A reference to this bounding box.
*/
setFromPoints(points) {
this.makeEmpty();
for (let i6 = 0, il = points.length; i6 < il; i6++) {
this.expandByPoint(points[i6]);
}
return this;
}
/**
* Centers this box on the given center vector and sets this box's width, height and
* depth to the given size values.
*
* @param {Vector3} center - The center of the box.
* @param {Vector3} size - The x, y and z dimensions of the box.
* @return {Box3} A reference to this bounding box.
*/
setFromCenterAndSize(center, size) {
const halfSize = _vector$b.copy(size).multiplyScalar(0.5);
this.min.copy(center).sub(halfSize);
this.max.copy(center).add(halfSize);
return this;
}
/**
* Computes the world-axis-aligned bounding box for the given 3D object
* (including its children), accounting for the object's, and children's,
* world transforms. The function may result in a larger box than strictly necessary.
*
* @param {Object3D} object - The 3D object to compute the bounding box for.
* @param {boolean} [precise=false] - If set to `true`, the method computes the smallest
* world-axis-aligned bounding box at the expense of more computation.
* @return {Box3} A reference to this bounding box.
*/
setFromObject(object, precise = false) {
this.makeEmpty();
return this.expandByObject(object, precise);
}
/**
* Returns a new box with copied values from this instance.
*
* @return {Box3} A clone of this instance.
*/
clone() {
return new this.constructor().copy(this);
}
/**
* Copies the values of the given box to this instance.
*
* @param {Box3} box - The box to copy.
* @return {Box3} A reference to this bounding box.
*/
copy(box) {
this.min.copy(box.min);
this.max.copy(box.max);
return this;
}
/**
* Makes this box empty which means in encloses a zero space in 3D.
*
* @return {Box3} A reference to this bounding box.
*/
makeEmpty() {
this.min.x = this.min.y = this.min.z = Infinity;
this.max.x = this.max.y = this.max.z = -Infinity;
return this;
}
/**
* Returns true if this box includes zero points within its bounds.
* Note that a box with equal lower and upper bounds still includes one
* point, the one both bounds share.
*
* @return {boolean} Whether this box is empty or not.
*/
isEmpty() {
return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;
}
/**
* Returns the center point of this box.
*
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {Vector3} The center point.
*/
getCenter(target) {
return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);
}
/**
* Returns the dimensions of this box.
*
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {Vector3} The size.
*/
getSize(target) {
return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min);
}
/**
* Expands the boundaries of this box to include the given point.
*
* @param {Vector3} point - The point that should be included by the bounding box.
* @return {Box3} A reference to this bounding box.
*/
expandByPoint(point) {
this.min.min(point);
this.max.max(point);
return this;
}
/**
* Expands this box equilaterally by the given vector. The width of this
* box will be expanded by the x component of the vector in both
* directions. The height of this box will be expanded by the y component of
* the vector in both directions. The depth of this box will be
* expanded by the z component of the vector in both directions.
*
* @param {Vector3} vector - The vector that should expand the bounding box.
* @return {Box3} A reference to this bounding box.
*/
expandByVector(vector) {
this.min.sub(vector);
this.max.add(vector);
return this;
}
/**
* Expands each dimension of the box by the given scalar. If negative, the
* dimensions of the box will be contracted.
*
* @param {number} scalar - The scalar value that should expand the bounding box.
* @return {Box3} A reference to this bounding box.
*/
expandByScalar(scalar) {
this.min.addScalar(-scalar);
this.max.addScalar(scalar);
return this;
}
/**
* Expands the boundaries of this box to include the given 3D object and
* its children, accounting for the object's, and children's, world
* transforms. The function may result in a larger box than strictly
* necessary (unless the precise parameter is set to true).
*
* @param {Object3D} object - The 3D object that should expand the bounding box.
* @param {boolean} precise - If set to `true`, the method expands the bounding box
* as little as necessary at the expense of more computation.
* @return {Box3} A reference to this bounding box.
*/
expandByObject(object, precise = false) {
object.updateWorldMatrix(false, false);
const geometry = object.geometry;
if (geometry !== void 0) {
const positionAttribute = geometry.getAttribute("position");
if (precise === true && positionAttribute !== void 0 && object.isInstancedMesh !== true) {
for (let i6 = 0, l3 = positionAttribute.count; i6 < l3; i6++) {
if (object.isMesh === true) {
object.getVertexPosition(i6, _vector$b);
} else {
_vector$b.fromBufferAttribute(positionAttribute, i6);
}
_vector$b.applyMatrix4(object.matrixWorld);
this.expandByPoint(_vector$b);
}
} else {
if (object.boundingBox !== void 0) {
if (object.boundingBox === null) {
object.computeBoundingBox();
}
_box$4.copy(object.boundingBox);
} else {
if (geometry.boundingBox === null) {
geometry.computeBoundingBox();
}
_box$4.copy(geometry.boundingBox);
}
_box$4.applyMatrix4(object.matrixWorld);
this.union(_box$4);
}
}
const children = object.children;
for (let i6 = 0, l3 = children.length; i6 < l3; i6++) {
this.expandByObject(children[i6], precise);
}
return this;
}
/**
* Returns `true` if the given point lies within or on the boundaries of this box.
*
* @param {Vector3} point - The point to test.
* @return {boolean} Whether the bounding box contains the given point or not.
*/
containsPoint(point) {
return point.x >= this.min.x && point.x <= this.max.x && point.y >= this.min.y && point.y <= this.max.y && point.z >= this.min.z && point.z <= this.max.z;
}
/**
* Returns `true` if this bounding box includes the entirety of the given bounding box.
* If this box and the given one are identical, this function also returns `true`.
*
* @param {Box3} box - The bounding box to test.
* @return {boolean} Whether the bounding box contains the given bounding box or not.
*/
containsBox(box) {
return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z;
}
/**
* Returns a point as a proportion of this box's width, height and depth.
*
* @param {Vector3} point - A point in 3D space.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {Vector3} A point as a proportion of this box's width, height and depth.
*/
getParameter(point, target) {
return target.set(
(point.x - this.min.x) / (this.max.x - this.min.x),
(point.y - this.min.y) / (this.max.y - this.min.y),
(point.z - this.min.z) / (this.max.z - this.min.z)
);
}
/**
* Returns `true` if the given bounding box intersects with this bounding box.
*
* @param {Box3} box - The bounding box to test.
* @return {boolean} Whether the given bounding box intersects with this bounding box.
*/
intersectsBox(box) {
return box.max.x >= this.min.x && box.min.x <= this.max.x && box.max.y >= this.min.y && box.min.y <= this.max.y && box.max.z >= this.min.z && box.min.z <= this.max.z;
}
/**
* Returns `true` if the given bounding sphere intersects with this bounding box.
*
* @param {Sphere} sphere - The bounding sphere to test.
* @return {boolean} Whether the given bounding sphere intersects with this bounding box.
*/
intersectsSphere(sphere) {
this.clampPoint(sphere.center, _vector$b);
return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;
}
/**
* Returns `true` if the given plane intersects with this bounding box.
*
* @param {Plane} plane - The plane to test.
* @return {boolean} Whether the given plane intersects with this bounding box.
*/
intersectsPlane(plane) {
let min, max;
if (plane.normal.x > 0) {
min = plane.normal.x * this.min.x;
max = plane.normal.x * this.max.x;
} else {
min = plane.normal.x * this.max.x;
max = plane.normal.x * this.min.x;
}
if (plane.normal.y > 0) {
min += plane.normal.y * this.min.y;
max += plane.normal.y * this.max.y;
} else {
min += plane.normal.y * this.max.y;
max += plane.normal.y * this.min.y;
}
if (plane.normal.z > 0) {
min += plane.normal.z * this.min.z;
max += plane.normal.z * this.max.z;
} else {
min += plane.normal.z * this.max.z;
max += plane.normal.z * this.min.z;
}
return min <= -plane.constant && max >= -plane.constant;
}
/**
* Returns `true` if the given triangle intersects with this bounding box.
*
* @param {Triangle} triangle - The triangle to test.
* @return {boolean} Whether the given triangle intersects with this bounding box.
*/
intersectsTriangle(triangle) {
if (this.isEmpty()) {
return false;
}
this.getCenter(_center);
_extents.subVectors(this.max, _center);
_v0$2.subVectors(triangle.a, _center);
_v1$7.subVectors(triangle.b, _center);
_v2$4.subVectors(triangle.c, _center);
_f0.subVectors(_v1$7, _v0$2);
_f1.subVectors(_v2$4, _v1$7);
_f2.subVectors(_v0$2, _v2$4);
let axes = [
0,
-_f0.z,
_f0.y,
0,
-_f1.z,
_f1.y,
0,
-_f2.z,
_f2.y,
_f0.z,
0,
-_f0.x,
_f1.z,
0,
-_f1.x,
_f2.z,
0,
-_f2.x,
-_f0.y,
_f0.x,
0,
-_f1.y,
_f1.x,
0,
-_f2.y,
_f2.x,
0
];
if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {
return false;
}
axes = [1, 0, 0, 0, 1, 0, 0, 0, 1];
if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {
return false;
}
_triangleNormal.crossVectors(_f0, _f1);
axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z];
return satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents);
}
/**
* Clamps the given point within the bounds of this box.
*
* @param {Vector3} point - The point to clamp.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {Vector3} The clamped point.
*/
clampPoint(point, target) {
return target.copy(point).clamp(this.min, this.max);
}
/**
* Returns the euclidean distance from any edge of this box to the specified point. If
* the given point lies inside of this box, the distance will be `0`.
*
* @param {Vector3} point - The point to compute the distance to.
* @return {number} The euclidean distance.
*/
distanceToPoint(point) {
return this.clampPoint(point, _vector$b).distanceTo(point);
}
/**
* Returns a bounding sphere that encloses this bounding box.
*
* @param {Sphere} target - The target sphere that is used to store the method's result.
* @return {Sphere} The bounding sphere that encloses this bounding box.
*/
getBoundingSphere(target) {
if (this.isEmpty()) {
target.makeEmpty();
} else {
this.getCenter(target.center);
target.radius = this.getSize(_vector$b).length() * 0.5;
}
return target;
}
/**
* Computes the intersection of this bounding box and the given one, setting the upper
* bound of this box to the lesser of the two boxes' upper bounds and the
* lower bound of this box to the greater of the two boxes' lower bounds. If
* there's no overlap, makes this box empty.
*
* @param {Box3} box - The bounding box to intersect with.
* @return {Box3} A reference to this bounding box.
*/
intersect(box) {
this.min.max(box.min);
this.max.min(box.max);
if (this.isEmpty()) this.makeEmpty();
return this;
}
/**
* Computes the union of this box and another and the given one, setting the upper
* bound of this box to the greater of the two boxes' upper bounds and the
* lower bound of this box to the lesser of the two boxes' lower bounds.
*
* @param {Box3} box - The bounding box that will be unioned with this instance.
* @return {Box3} A reference to this bounding box.
*/
union(box) {
this.min.min(box.min);
this.max.max(box.max);
return this;
}
/**
* Transforms this bounding box by the given 4x4 transformation matrix.
*
* @param {Matrix4} matrix - The transformation matrix.
* @return {Box3} A reference to this bounding box.
*/
applyMatrix4(matrix) {
if (this.isEmpty()) return this;
_points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix);
_points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix);
_points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix);
_points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix);
_points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix);
_points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix);
_points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix);
_points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix);
this.setFromPoints(_points);
return this;
}
/**
* Adds the given offset to both the upper and lower bounds of this bounding box,
* effectively moving it in 3D space.
*
* @param {Vector3} offset - The offset that should be used to translate the bounding box.
* @return {Box3} A reference to this bounding box.
*/
translate(offset) {
this.min.add(offset);
this.max.add(offset);
return this;
}
/**
* Returns `true` if this bounding box is equal with the given one.
*
* @param {Box3} box - The box to test for equality.
* @return {boolean} Whether this bounding box is equal with the given one.
*/
equals(box) {
return box.min.equals(this.min) && box.max.equals(this.max);
}
/**
* Returns a serialized structure of the bounding box.
*
* @return {Object} Serialized structure with fields representing the object state.
*/
toJSON() {
return {
min: this.min.toArray(),
max: this.max.toArray()
};
}
/**
* Returns a serialized structure of the bounding box.
*
* @param {Object} json - The serialized json to set the box from.
* @return {Box3} A reference to this bounding box.
*/
fromJSON(json) {
this.min.fromArray(json.min);
this.max.fromArray(json.max);
return this;
}
};
var _points = [
/* @__PURE__ */ new Vector3(),
/* @__PURE__ */ new Vector3(),
/* @__PURE__ */ new Vector3(),
/* @__PURE__ */ new Vector3(),
/* @__PURE__ */ new Vector3(),
/* @__PURE__ */ new Vector3(),
/* @__PURE__ */ new Vector3(),
/* @__PURE__ */ new Vector3()
];
var _vector$b = /* @__PURE__ */ new Vector3();
var _box$4 = /* @__PURE__ */ new Box3();
var _v0$2 = /* @__PURE__ */ new Vector3();
var _v1$7 = /* @__PURE__ */ new Vector3();
var _v2$4 = /* @__PURE__ */ new Vector3();
var _f0 = /* @__PURE__ */ new Vector3();
var _f1 = /* @__PURE__ */ new Vector3();
var _f2 = /* @__PURE__ */ new Vector3();
var _center = /* @__PURE__ */ new Vector3();
var _extents = /* @__PURE__ */ new Vector3();
var _triangleNormal = /* @__PURE__ */ new Vector3();
var _testAxis = /* @__PURE__ */ new Vector3();
function satForAxes(axes, v0, v1, v2, extents) {
for (let i6 = 0, j2 = axes.length - 3; i6 <= j2; i6 += 3) {
_testAxis.fromArray(axes, i6);
const r6 = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z);
const p0 = v0.dot(_testAxis);
const p1 = v1.dot(_testAxis);
const p22 = v2.dot(_testAxis);
if (Math.max(-Math.max(p0, p1, p22), Math.min(p0, p1, p22)) > r6) {
return false;
}
}
return true;
}
var _box$3 = /* @__PURE__ */ new Box3();
var _v1$6 = /* @__PURE__ */ new Vector3();
var _v2$3 = /* @__PURE__ */ new Vector3();
var Sphere = class {
/**
* Constructs a new sphere.
*
* @param {Vector3} [center=(0,0,0)] - The center of the sphere
* @param {number} [radius=-1] - The radius of the sphere.
*/
constructor(center = new Vector3(), radius = -1) {
this.isSphere = true;
this.center = center;
this.radius = radius;
}
/**
* Sets the sphere's components by copying the given values.
*
* @param {Vector3} center - The center.
* @param {number} radius - The radius.
* @return {Sphere} A reference to this sphere.
*/
set(center, radius) {
this.center.copy(center);
this.radius = radius;
return this;
}
/**
* Computes the minimum bounding sphere for list of points.
* If the optional center point is given, it is used as the sphere's
* center. Otherwise, the center of the axis-aligned bounding box
* encompassing the points is calculated.
*
* @param {Array} points - A list of points in 3D space.
* @param {Vector3} [optionalCenter] - The center of the sphere.
* @return {Sphere} A reference to this sphere.
*/
setFromPoints(points, optionalCenter) {
const center = this.center;
if (optionalCenter !== void 0) {
center.copy(optionalCenter);
} else {
_box$3.setFromPoints(points).getCenter(center);
}
let maxRadiusSq = 0;
for (let i6 = 0, il = points.length; i6 < il; i6++) {
maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i6]));
}
this.radius = Math.sqrt(maxRadiusSq);
return this;
}
/**
* Copies the values of the given sphere to this instance.
*
* @param {Sphere} sphere - The sphere to copy.
* @return {Sphere} A reference to this sphere.
*/
copy(sphere) {
this.center.copy(sphere.center);
this.radius = sphere.radius;
return this;
}
/**
* Returns `true` if the sphere is empty (the radius set to a negative number).
*
* Spheres with a radius of `0` contain only their center point and are not
* considered to be empty.
*
* @return {boolean} Whether this sphere is empty or not.
*/
isEmpty() {
return this.radius < 0;
}
/**
* Makes this sphere empty which means in encloses a zero space in 3D.
*
* @return {Sphere} A reference to this sphere.
*/
makeEmpty() {
this.center.set(0, 0, 0);
this.radius = -1;
return this;
}
/**
* Returns `true` if this sphere contains the given point inclusive of
* the surface of the sphere.
*
* @param {Vector3} point - The point to check.
* @return {boolean} Whether this sphere contains the given point or not.
*/
containsPoint(point) {
return point.distanceToSquared(this.center) <= this.radius * this.radius;
}
/**
* Returns the closest distance from the boundary of the sphere to the
* given point. If the sphere contains the point, the distance will
* be negative.
*
* @param {Vector3} point - The point to compute the distance to.
* @return {number} The distance to the point.
*/
distanceToPoint(point) {
return point.distanceTo(this.center) - this.radius;
}
/**
* Returns `true` if this sphere intersects with the given one.
*
* @param {Sphere} sphere - The sphere to test.
* @return {boolean} Whether this sphere intersects with the given one or not.
*/
intersectsSphere(sphere) {
const radiusSum = this.radius + sphere.radius;
return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum;
}
/**
* Returns `true` if this sphere intersects with the given box.
*
* @param {Box3} box - The box to test.
* @return {boolean} Whether this sphere intersects with the given box or not.
*/
intersectsBox(box) {
return box.intersectsSphere(this);
}
/**
* Returns `true` if this sphere intersects with the given plane.
*
* @param {Plane} plane - The plane to test.
* @return {boolean} Whether this sphere intersects with the given plane or not.
*/
intersectsPlane(plane) {
return Math.abs(plane.distanceToPoint(this.center)) <= this.radius;
}
/**
* Clamps a point within the sphere. If the point is outside the sphere, it
* will clamp it to the closest point on the edge of the sphere. Points
* already inside the sphere will not be affected.
*
* @param {Vector3} point - The plane to clamp.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {Vector3} The clamped point.
*/
clampPoint(point, target) {
const deltaLengthSq = this.center.distanceToSquared(point);
target.copy(point);
if (deltaLengthSq > this.radius * this.radius) {
target.sub(this.center).normalize();
target.multiplyScalar(this.radius).add(this.center);
}
return target;
}
/**
* Returns a bounding box that encloses this sphere.
*
* @param {Box3} target - The target box that is used to store the method's result.
* @return {Box3} The bounding box that encloses this sphere.
*/
getBoundingBox(target) {
if (this.isEmpty()) {
target.makeEmpty();
return target;
}
target.set(this.center, this.center);
target.expandByScalar(this.radius);
return target;
}
/**
* Transforms this sphere with the given 4x4 transformation matrix.
*
* @param {Matrix4} matrix - The transformation matrix.
* @return {Sphere} A reference to this sphere.
*/
applyMatrix4(matrix) {
this.center.applyMatrix4(matrix);
this.radius = this.radius * matrix.getMaxScaleOnAxis();
return this;
}
/**
* Translates the sphere's center by the given offset.
*
* @param {Vector3} offset - The offset.
* @return {Sphere} A reference to this sphere.
*/
translate(offset) {
this.center.add(offset);
return this;
}
/**
* Expands the boundaries of this sphere to include the given point.
*
* @param {Vector3} point - The point to include.
* @return {Sphere} A reference to this sphere.
*/
expandByPoint(point) {
if (this.isEmpty()) {
this.center.copy(point);
this.radius = 0;
return this;
}
_v1$6.subVectors(point, this.center);
const lengthSq = _v1$6.lengthSq();
if (lengthSq > this.radius * this.radius) {
const length = Math.sqrt(lengthSq);
const delta = (length - this.radius) * 0.5;
this.center.addScaledVector(_v1$6, delta / length);
this.radius += delta;
}
return this;
}
/**
* Expands this sphere to enclose both the original sphere and the given sphere.
*
* @param {Sphere} sphere - The sphere to include.
* @return {Sphere} A reference to this sphere.
*/
union(sphere) {
if (sphere.isEmpty()) {
return this;
}
if (this.isEmpty()) {
this.copy(sphere);
return this;
}
if (this.center.equals(sphere.center) === true) {
this.radius = Math.max(this.radius, sphere.radius);
} else {
_v2$3.subVectors(sphere.center, this.center).setLength(sphere.radius);
this.expandByPoint(_v1$6.copy(sphere.center).add(_v2$3));
this.expandByPoint(_v1$6.copy(sphere.center).sub(_v2$3));
}
return this;
}
/**
* Returns `true` if this sphere is equal with the given one.
*
* @param {Sphere} sphere - The sphere to test for equality.
* @return {boolean} Whether this bounding sphere is equal with the given one.
*/
equals(sphere) {
return sphere.center.equals(this.center) && sphere.radius === this.radius;
}
/**
* Returns a new sphere with copied values from this instance.
*
* @return {Sphere} A clone of this instance.
*/
clone() {
return new this.constructor().copy(this);
}
/**
* Returns a serialized structure of the bounding sphere.
*
* @return {Object} Serialized structure with fields representing the object state.
*/
toJSON() {
return {
radius: this.radius,
center: this.center.toArray()
};
}
/**
* Returns a serialized structure of the bounding sphere.
*
* @param {Object} json - The serialized json to set the sphere from.
* @return {Box3} A reference to this bounding sphere.
*/
fromJSON(json) {
this.radius = json.radius;
this.center.fromArray(json.center);
return this;
}
};
var _vector$a = /* @__PURE__ */ new Vector3();
var _segCenter = /* @__PURE__ */ new Vector3();
var _segDir = /* @__PURE__ */ new Vector3();
var _diff = /* @__PURE__ */ new Vector3();
var _edge1 = /* @__PURE__ */ new Vector3();
var _edge2 = /* @__PURE__ */ new Vector3();
var _normal$1 = /* @__PURE__ */ new Vector3();
var Ray = class {
/**
* Constructs a new ray.
*
* @param {Vector3} [origin=(0,0,0)] - The origin of the ray.
* @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray.
*/
constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) {
this.origin = origin;
this.direction = direction;
}
/**
* Sets the ray's components by copying the given values.
*
* @param {Vector3} origin - The origin.
* @param {Vector3} direction - The direction.
* @return {Ray} A reference to this ray.
*/
set(origin, direction) {
this.origin.copy(origin);
this.direction.copy(direction);
return this;
}
/**
* Copies the values of the given ray to this instance.
*
* @param {Ray} ray - The ray to copy.
* @return {Ray} A reference to this ray.
*/
copy(ray) {
this.origin.copy(ray.origin);
this.direction.copy(ray.direction);
return this;
}
/**
* Returns a vector that is located at a given distance along this ray.
*
* @param {number} t - The distance along the ray to retrieve a position for.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {Vector3} A position on the ray.
*/
at(t6, target) {
return target.copy(this.origin).addScaledVector(this.direction, t6);
}
/**
* Adjusts the direction of the ray to point at the given vector in world space.
*
* @param {Vector3} v - The target position.
* @return {Ray} A reference to this ray.
*/
lookAt(v2) {
this.direction.copy(v2).sub(this.origin).normalize();
return this;
}
/**
* Shift the origin of this ray along its direction by the given distance.
*
* @param {number} t - The distance along the ray to interpolate.
* @return {Ray} A reference to this ray.
*/
recast(t6) {
this.origin.copy(this.at(t6, _vector$a));
return this;
}
/**
* Returns the point along this ray that is closest to the given point.
*
* @param {Vector3} point - A point in 3D space to get the closet location on the ray for.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {Vector3} The closest point on this ray.
*/
closestPointToPoint(point, target) {
target.subVectors(point, this.origin);
const directionDistance = target.dot(this.direction);
if (directionDistance < 0) {
return target.copy(this.origin);
}
return target.copy(this.origin).addScaledVector(this.direction, directionDistance);
}
/**
* Returns the distance of the closest approach between this ray and the given point.
*
* @param {Vector3} point - A point in 3D space to compute the distance to.
* @return {number} The distance.
*/
distanceToPoint(point) {
return Math.sqrt(this.distanceSqToPoint(point));
}
/**
* Returns the squared distance of the closest approach between this ray and the given point.
*
* @param {Vector3} point - A point in 3D space to compute the distance to.
* @return {number} The squared distance.
*/
distanceSqToPoint(point) {
const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction);
if (directionDistance < 0) {
return this.origin.distanceToSquared(point);
}
_vector$a.copy(this.origin).addScaledVector(this.direction, directionDistance);
return _vector$a.distanceToSquared(point);
}
/**
* Returns the squared distance between this ray and the given line segment.
*
* @param {Vector3} v0 - The start point of the line segment.
* @param {Vector3} v1 - The end point of the line segment.
* @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment.
* @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray.
* @return {number} The squared distance.
*/
distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) {
_segCenter.copy(v0).add(v1).multiplyScalar(0.5);
_segDir.copy(v1).sub(v0).normalize();
_diff.copy(this.origin).sub(_segCenter);
const segExtent = v0.distanceTo(v1) * 0.5;
const a01 = -this.direction.dot(_segDir);
const b0 = _diff.dot(this.direction);
const b1 = -_diff.dot(_segDir);
const c5 = _diff.lengthSq();
const det = Math.abs(1 - a01 * a01);
let s0, s1, sqrDist, extDet;
if (det > 0) {
s0 = a01 * b1 - b0;
s1 = a01 * b0 - b1;
extDet = segExtent * det;
if (s0 >= 0) {
if (s1 >= -extDet) {
if (s1 <= extDet) {
const invDet = 1 / det;
s0 *= invDet;
s1 *= invDet;
sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c5;
} else {
s1 = segExtent;
s0 = Math.max(0, -(a01 * s1 + b0));
sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c5;
}
} else {
s1 = -segExtent;
s0 = Math.max(0, -(a01 * s1 + b0));
sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c5;
}
} else {
if (s1 <= -extDet) {
s0 = Math.max(0, -(-a01 * segExtent + b0));
s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c5;
} else if (s1 <= extDet) {
s0 = 0;
s1 = Math.min(Math.max(-segExtent, -b1), segExtent);
sqrDist = s1 * (s1 + 2 * b1) + c5;
} else {
s0 = Math.max(0, -(a01 * segExtent + b0));
s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c5;
}
}
} else {
s1 = a01 > 0 ? -segExtent : segExtent;
s0 = Math.max(0, -(a01 * s1 + b0));
sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c5;
}
if (optionalPointOnRay) {
optionalPointOnRay.copy(this.origin).addScaledVector(this.direction, s0);
}
if (optionalPointOnSegment) {
optionalPointOnSegment.copy(_segCenter).addScaledVector(_segDir, s1);
}
return sqrDist;
}
/**
* Intersects this ray with the given sphere, returning the intersection
* point or `null` if there is no intersection.
*
* @param {Sphere} sphere - The sphere to intersect.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {?Vector3} The intersection point.
*/
intersectSphere(sphere, target) {
_vector$a.subVectors(sphere.center, this.origin);
const tca = _vector$a.dot(this.direction);
const d22 = _vector$a.dot(_vector$a) - tca * tca;
const radius2 = sphere.radius * sphere.radius;
if (d22 > radius2) return null;
const thc = Math.sqrt(radius2 - d22);
const t0 = tca - thc;
const t1 = tca + thc;
if (t1 < 0) return null;
if (t0 < 0) return this.at(t1, target);
return this.at(t0, target);
}
/**
* Returns `true` if this ray intersects with the given sphere.
*
* @param {Sphere} sphere - The sphere to intersect.
* @return {boolean} Whether this ray intersects with the given sphere or not.
*/
intersectsSphere(sphere) {
if (sphere.radius < 0) return false;
return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius;
}
/**
* Computes the distance from the ray's origin to the given plane. Returns `null` if the ray
* does not intersect with the plane.
*
* @param {Plane} plane - The plane to compute the distance to.
* @return {?number} Whether this ray intersects with the given sphere or not.
*/
distanceToPlane(plane) {
const denominator = plane.normal.dot(this.direction);
if (denominator === 0) {
if (plane.distanceToPoint(this.origin) === 0) {
return 0;
}
return null;
}
const t6 = -(this.origin.dot(plane.normal) + plane.constant) / denominator;
return t6 >= 0 ? t6 : null;
}
/**
* Intersects this ray with the given plane, returning the intersection
* point or `null` if there is no intersection.
*
* @param {Plane} plane - The plane to intersect.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {?Vector3} The intersection point.
*/
intersectPlane(plane, target) {
const t6 = this.distanceToPlane(plane);
if (t6 === null) {
return null;
}
return this.at(t6, target);
}
/**
* Returns `true` if this ray intersects with the given plane.
*
* @param {Plane} plane - The plane to intersect.
* @return {boolean} Whether this ray intersects with the given plane or not.
*/
intersectsPlane(plane) {
const distToPoint = plane.distanceToPoint(this.origin);
if (distToPoint === 0) {
return true;
}
const denominator = plane.normal.dot(this.direction);
if (denominator * distToPoint < 0) {
return true;
}
return false;
}
/**
* Intersects this ray with the given bounding box, returning the intersection
* point or `null` if there is no intersection.
*
* @param {Box3} box - The box to intersect.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {?Vector3} The intersection point.
*/
intersectBox(box, target) {
let tmin, tmax, tymin, tymax, tzmin, tzmax;
const invdirx = 1 / this.direction.x, invdiry = 1 / this.direction.y, invdirz = 1 / this.direction.z;
const origin = this.origin;
if (invdirx >= 0) {
tmin = (box.min.x - origin.x) * invdirx;
tmax = (box.max.x - origin.x) * invdirx;
} else {
tmin = (box.max.x - origin.x) * invdirx;
tmax = (box.min.x - origin.x) * invdirx;
}
if (invdiry >= 0) {
tymin = (box.min.y - origin.y) * invdiry;
tymax = (box.max.y - origin.y) * invdiry;
} else {
tymin = (box.max.y - origin.y) * invdiry;
tymax = (box.min.y - origin.y) * invdiry;
}
if (tmin > tymax || tymin > tmax) return null;
if (tymin > tmin || isNaN(tmin)) tmin = tymin;
if (tymax < tmax || isNaN(tmax)) tmax = tymax;
if (invdirz >= 0) {
tzmin = (box.min.z - origin.z) * invdirz;
tzmax = (box.max.z - origin.z) * invdirz;
} else {
tzmin = (box.max.z - origin.z) * invdirz;
tzmax = (box.min.z - origin.z) * invdirz;
}
if (tmin > tzmax || tzmin > tmax) return null;
if (tzmin > tmin || tmin !== tmin) tmin = tzmin;
if (tzmax < tmax || tmax !== tmax) tmax = tzmax;
if (tmax < 0) return null;
return this.at(tmin >= 0 ? tmin : tmax, target);
}
/**
* Returns `true` if this ray intersects with the given box.
*
* @param {Box3} box - The box to intersect.
* @return {boolean} Whether this ray intersects with the given box or not.
*/
intersectsBox(box) {
return this.intersectBox(box, _vector$a) !== null;
}
/**
* Intersects this ray with the given triangle, returning the intersection
* point or `null` if there is no intersection.
*
* @param {Vector3} a - The first vertex of the triangle.
* @param {Vector3} b - The second vertex of the triangle.
* @param {Vector3} c - The third vertex of the triangle.
* @param {boolean} backfaceCulling - Whether to use backface culling or not.
* @param {Vector3} target - The target vector that is used to store the method's result.
* @return {?Vector3} The intersection point.
*/
intersectTriangle(a3, b3, c5, backfaceCulling, target) {
_edge1.subVectors(b3, a3);
_edge2.subVectors(c5, a3);
_normal$1.crossVectors(_edge1, _edge2);
let DdN = this.direction.dot(_normal$1);
let sign;
if (DdN > 0) {
if (backfaceCulling) return null;
sign = 1;
} else if (DdN < 0) {
sign = -1;
DdN = -DdN;
} else {
return null;
}
_diff.subVectors(this.origin, a3);
const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2));
if (DdQxE2 < 0) {
return null;
}
const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff));
if (DdE1xQ < 0) {
return null;
}
if (DdQxE2 + DdE1xQ > DdN) {
return null;
}
const QdN = -sign * _diff.dot(_normal$1);
if (QdN < 0) {
return null;
}
return this.at(QdN / DdN, target);
}
/**
* Transforms this ray with the given 4x4 transformation matrix.
*
* @param {Matrix4} matrix4 - The transformation matrix.
* @return {Ray} A reference to this ray.
*/
applyMatrix4(matrix4) {
this.origin.applyMatrix4(matrix4);
this.direction.transformDirection(matrix4);
return this;
}
/**
* Returns `true` if this ray is equal with the given one.
*
* @param {Ray} ray - The ray to test for equality.
* @return {boolean} Whether this ray is equal with the given one.
*/
equals(ray) {
return ray.origin.equals(this.origin) && ray.direction.equals(this.direction);
}
/**
* Returns a new ray with copied values from this instance.
*
* @return {Ray} A clone of this instance.
*/
clone() {
return new this.constructor().copy(this);
}
};
var Matrix4 = class _Matrix4 {
/**
* Constructs a new 4x4 matrix. The arguments are supposed to be
* in row-major order. If no arguments are provided, the constructor
* initializes the matrix as an identity matrix.
*
* @param {number} [n11] - 1-1 matrix element.
* @param {number} [n12] - 1-2 matrix element.
* @param {number} [n13] - 1-3 matrix element.
* @param {number} [n14] - 1-4 matrix element.
* @param {number} [n21] - 2-1 matrix element.
* @param {number} [n22] - 2-2 matrix element.
* @param {number} [n23] - 2-3 matrix element.
* @param {number} [n24] - 2-4 matrix element.
* @param {number} [n31] - 3-1 matrix element.
* @param {number} [n32] - 3-2 matrix element.
* @param {number} [n33] - 3-3 matrix element.
* @param {number} [n34] - 3-4 matrix element.
* @param {number} [n41] - 4-1 matrix element.
* @param {number} [n42] - 4-2 matrix element.
* @param {number} [n43] - 4-3 matrix element.
* @param {number} [n44] - 4-4 matrix element.
*/
constructor(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
_Matrix4.prototype.isMatrix4 = true;
this.elements = [
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
];
if (n11 !== void 0) {
this.set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44);
}
}
/**
* Sets the elements of the matrix.The arguments are supposed to be
* in row-major order.
*
* @param {number} [n11] - 1-1 matrix element.
* @param {number} [n12] - 1-2 matrix element.
* @param {number} [n13] - 1-3 matrix element.
* @param {number} [n14] - 1-4 matrix element.
* @param {number} [n21] - 2-1 matrix element.
* @param {number} [n22] - 2-2 matrix element.
* @param {number} [n23] - 2-3 matrix element.
* @param {number} [n24] - 2-4 matrix element.
* @param {number} [n31] - 3-1 matrix element.
* @param {number} [n32] - 3-2 matrix element.
* @param {number} [n33] - 3-3 matrix element.
* @param {number} [n34] - 3-4 matrix element.
* @param {number} [n41] - 4-1 matrix element.
* @param {number} [n42] - 4-2 matrix element.
* @param {number} [n43] - 4-3 matrix element.
* @param {number} [n44] - 4-4 matrix element.
* @return {Matrix4} A reference to this matrix.
*/
set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
const te = this.elements;
te[0] = n11;
te[4] = n12;
te[8] = n13;
te[12] = n14;
te[1] = n21;
te[5] = n22;
te[9] = n23;
te[13] = n24;
te[2] = n31;
te[6] = n32;
te[10] = n33;
te[14] = n34;
te[3] = n41;
te[7] = n42;
te[11] = n43;
te[15] = n44;
return this;
}
/**
* Sets this matrix to the 4x4 identity matrix.
*
* @return {Matrix4} A reference to this matrix.
*/
identity() {
this.set(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
return this;
}
/**
* Returns a matrix with copied values from this instance.
*
* @return {Matrix4} A clone of this instance.
*/
clone() {
return new _Matrix4().fromArray(this.elements);
}
/**
* Copies the values of the given matrix to this instance.
*
* @param {Matrix4} m - The matrix to copy.
* @return {Matrix4} A reference to this matrix.
*/
copy(m2) {
const te = this.elements;
const me = m2.elements;
te[0] = me[0];
te[1] = me[1];
te[2] = me[2];
te[3] = me[3];
te[4] = me[4];
te[5] = me[5];
te[6] = me[6];
te[7] = me[7];
te[8] = me[8];
te[9] = me[9];
te[10] = me[10];
te[11] = me[11];
te[12] = me[12];
te[13] = me[13];
te[14] = me[14];
te[15] = me[15];
return this;
}
/**
* Copies the translation component of the given matrix
* into this matrix's translation component.
*
* @param {Matrix4} m - The matrix to copy the translation component.
* @return {Matrix4} A reference to this matrix.
*/
copyPosition(m2) {
const te = this.elements, me = m2.elements;
te[12] = me[12];
te[13] = me[13];
te[14] = me[14];
return this;
}
/**
* Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix.
*
* @param {Matrix3} m - The 3x3 matrix.
* @return {Matrix4} A reference to this matrix.
*/
setFromMatrix3(m2) {
const me = m2.elements;
this.set(
me[0],
me[3],
me[6],
0,
me[1],
me[4],
me[7],
0,
me[2],
me[5],
me[8],
0,
0,
0,
0,
1
);
return this;
}
/**
* Extracts the basis of this matrix into the three axis vectors provided.
*
* @param {Vector3} xAxis - The basis's x axis.
* @param {Vector3} yAxis - The basis's y axis.
* @param {Vector3} zAxis - The basis's z axis.
* @return {Matrix4} A reference to this matrix.
*/
extractBasis(xAxis, yAxis, zAxis) {
xAxis.setFromMatrixColumn(this, 0);
yAxis.setFromMatrixColumn(this, 1);
zAxis.setFromMatrixColumn(this, 2);
return this;
}
/**
* Sets the given basis vectors to this matrix.
*
* @param {Vector3} xAxis - The basis's x axis.
* @param {Vector3} yAxis - The basis's y axis.
* @param {Vector3} zAxis - The basis's z axis.
* @return {Matrix4} A reference to this matrix.
*/
makeBasis(xAxis, yAxis, zAxis) {
this.set(
xAxis.x,
yAxis.x,
zAxis.x,
0,
xAxis.y,
yAxis.y,
zAxis.y,
0,
xAxis.z,
yAxis.z,
zAxis.z,
0,
0,
0,
0,
1
);
return this;
}
/**
* Extracts the rotation component of the given matrix
* into this matrix's rotation component.
*
* Note: This method does not support reflection matrices.
*
* @param {Matrix4} m - The matrix.
* @return {Matrix4} A reference to this matrix.
*/
extractRotation(m2) {
const te = this.elements;
const me = m2.elements;
const scaleX = 1 / _v1$5.setFromMatrixColumn(m2, 0).length();
const scaleY = 1 / _v1$5.setFromMatrixColumn(m2, 1).length();
const scaleZ = 1 / _v1$5.setFromMatrixColumn(m2, 2).length();
te[0] = me[0] * scaleX;
te[1] = me[1] * scaleX;
te[2] = me[2] * scaleX;
te[3] = 0;
te[4] = me[4] * scaleY;
te[5] = me[5] * scaleY;
te[6] = me[6] * scaleY;
te[7] = 0;
te[8] = me[8] * scaleZ;
te[9] = me[9] * scaleZ;
te[10] = me[10] * scaleZ;
te[11] = 0;
te[12] = 0;
te[13] = 0;
te[14] = 0;
te[15] = 1;
return this;
}
/**
* Sets the rotation component (the upper left 3x3 matrix) of this matrix to
* the rotation specified by the given Euler angles. The rest of
* the matrix is set to the identity. Depending on the {@link Euler#order},
* there are six possible outcomes. See [this page]{@link https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix}
* for a complete list.
*
* @param {Euler} euler - The Euler angles.
* @return {Matrix4} A reference to this matrix.
*/
makeRotationFromEuler(euler) {
const te = this.elements;
const x2 = euler.x, y3 = euler.y, z2 = euler.z;
const a3 = Math.cos(x2), b3 = Math.sin(x2);
const c5 = Math.cos(y3), d3 = Math.sin(y3);
const e8 = Math.cos(z2), f4 = Math.sin(z2);
if (euler.order === "XYZ") {
const ae = a3 * e8, af = a3 * f4, be = b3 * e8, bf = b3 * f4;
te[0] = c5 * e8;
te[4] = -c5 * f4;
te[8] = d3;
te[1] = af + be * d3;
te[5] = ae - bf * d3;
te[9] = -b3 * c5;
te[2] = bf - ae * d3;
te[6] = be + af * d3;
te[10] = a3 * c5;
} else if (euler.order === "YXZ") {
const ce = c5 * e8, cf = c5 * f4, de = d3 * e8, df = d3 * f4;
te[0] = ce + df * b3;
te[4] = de * b3 - cf;
te[8] = a3 * d3;
te[1] = a3 * f4;
te[5] = a3 * e8;
te[9] = -b3;
te[2] = cf * b3 - de;
te[6] = df + ce * b3;
te[10] = a3 * c5;
} else if (euler.order === "ZXY") {
const ce = c5 * e8, cf = c5 * f4, de = d3 * e8, df = d3 * f4;
te[0] = ce - df * b3;
te[4] = -a3 * f4;
te[8] = de + cf * b3;
te[1] = cf + de * b3;
te[5] = a3 * e8;
te[9] = df - ce * b3;
te[2] = -a3 * d3;
te[6] = b3;
te[10] = a3 * c5;
} else if (euler.order === "ZYX") {
const ae = a3 * e8, af = a3 * f4, be = b3 * e8, bf = b3 * f4;
te[0] = c5 * e8;
te[4] = be * d3 - af;
te[8] = ae * d3 + bf;
te[1] = c5 * f4;
te[5] = bf * d3 + ae;
te[9] = af * d3 - be;
te[2] = -d3;
te[6] = b3 * c5;
te[10] = a3 * c5;
} else if (euler.order === "YZX") {
const ac = a3 * c5, ad = a3 * d3, bc = b3 * c5, bd = b3 * d3;
te[0] = c5 * e8;
te[4] = bd - ac * f4;
te[8] = bc * f4 + ad;
te[1] = f4;
te[5] = a3 * e8;
te[9] = -b3 * e8;
te[2] = -d3 * e8;
te[6] = ad * f4 + bc;
te[10] = ac - bd * f4;
} else if (euler.order === "XZY") {
const ac = a3 * c5, ad = a3 * d3, bc = b3 * c5, bd = b3 * d3;
te[0] = c5 * e8;
te[4] = -f4;
te[8] = d3 * e8;
te[1] = ac * f4 + bd;
te[5] = a3 * e8;
te[9] = ad * f4 - bc;
te[2] = bc * f4 - ad;
te[6] = b3 * e8;
te[10] = bd * f4 + ac;
}
te[3] = 0;
te[7] = 0;
te[11] = 0;
te[12] = 0;
te[13] = 0;
te[14] = 0;
te[15] = 1;
return this;
}
/**
* Sets the rotation component of this matrix to the rotation specified by
* the given Quaternion as outlined [here]{@link https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion}
* The rest of the matrix is set to the identity.
*
* @param {Quaternion} q - The Quaternion.
* @return {Matrix4} A reference to this matrix.
*/
makeRotationFromQuaternion(q) {
return this.compose(_zero, q, _one);
}
/**
* Sets the rotation component of the transformation matrix, looking from `eye` towards
* `target`, and oriented by the up-direction.
*
* @param {Vector3} eye - The eye vector.
* @param {Vector3} target - The target vector.
* @param {Vector3} up - The up vector.
* @return {Matrix4} A reference to this matrix.
*/
lookAt(eye, target, up) {
const te = this.elements;
_z.subVectors(eye, target);
if (_z.lengthSq() === 0) {
_z.z = 1;
}
_z.normalize();
_x.crossVectors(up, _z);
if (_x.lengthSq() === 0) {
if (Math.abs(up.z) === 1) {
_z.x += 1e-4;
} else {
_z.z += 1e-4;
}
_z.normalize();
_x.crossVectors(up, _z);
}
_x.normalize();
_y.crossVectors(_z, _x);
te[0] = _x.x;
te[4] = _y.x;
te[8] = _z.x;
te[1] = _x.y;
te[5] = _y.y;
te[9] = _z.y;
te[2] = _x.z;
te[6] = _y.z;
te[10] = _z.z;
return this;
}
/**
* Post-multiplies this matrix by the given 4x4 matrix.
*
* @param {Matrix4} m - The matrix to multiply with.
* @return {Matrix4} A reference to this matrix.
*/
multiply(m2) {
return this.multiplyMatrices(this, m2);
}
/**
* Pre-multiplies this matrix by the given 4x4 matrix.
*
* @param {Matrix4} m - The matrix to multiply with.
* @return {Matrix4} A reference to this matrix.
*/
premultiply(m2) {
return this.multiplyMatrices(m2, this);
}
/**
* Multiples the given 4x4 matrices and stores the result
* in this matrix.
*
* @param {Matrix4} a - The first matrix.
* @param {Matrix4} b - The second matrix.
* @return {Matrix4} A reference to this matrix.
*/
multiplyMatrices(a3, b3) {
const ae = a3.elements;
const be = b3.elements;
const te = this.elements;
const a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
const a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
const a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
const a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
const b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
const b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
const b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
const b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
return this;
}
/**
* Multiplies every component of the matrix by the given scalar.
*
* @param {number} s - The scalar.
* @return {Matrix4} A reference to this matrix.
*/
multiplyScalar(s5) {
const te = this.elements;
te[0] *= s5;
te[4] *= s5;
te[8] *= s5;
te[12] *= s5;
te[1] *= s5;
te[5] *= s5;
te[9] *= s5;
te[13] *= s5;
te[2] *= s5;
te[6] *= s5;
te[10] *= s5;
te[14] *= s5;
te[3] *= s5;
te[7] *= s5;
te[11] *= s5;
te[15] *= s5;
return this;
}
/**
* Computes and returns the determinant of this matrix.
*
* Based on the method outlined [here]{@link http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html}.
*
* @return {number} The determinant.
*/
determinant() {
const te = this.elements;
const n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12];
const n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13];
const n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14];
const n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15];
return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31);
}
/**
* Transposes this matrix in place.
*
* @return {Matrix4} A reference to this matrix.
*/
transpose() {
const te = this.elements;
let tmp;
tmp = te[1];
te[1] = te[4];
te[4] = tmp;
tmp = te[2];
te[2] = te[8];
te[8] = tmp;
tmp = te[6];
te[6] = te[9];
te[9] = tmp;
tmp = te[3];
te[3] = te[12];
te[12] = tmp;
tmp = te[7];
te[7] = te[13];
te[13] = tmp;
tmp = te[11];
te[11] = te[14];
te[14] = tmp;
return this;
}
/**
* Sets the position component for this matrix from the given vector,
* without affecting the rest of the matrix.
*
* @param {number|Vector3} x - The x component of the vector or alternatively the vector object.
* @param {number} y - The y component of the vector.
* @param {number} z - The z component of the vector.
* @return {Matrix4} A reference to this matrix.
*/
setPosition(x2, y3, z2) {
const te = this.elements;
if (x2.isVector3) {
te[12] = x2.x;
te[13] = x2.y;
te[14] = x2.z;
} else {
te[12] = x2;
te[13] = y3;
te[14] = z2;
}
return this;
}
/**
* Inverts this matrix, using the [analytic method]{@link https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution}.
* You can not invert with a determinant of zero. If you attempt this, the method produces
* a zero matrix instead.
*
* @return {Matrix4} A reference to this matrix.
*/
invert() {
const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n41 = te[3], n12 = te[4], n22 = te[5], n32 = te[6], n42 = te[7], n13 = te[8], n23 = te[9], n33 = te[10], n43 = te[11], n14 = te[12], n24 = te[13], n34 = te[14], n44 = te[15], t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
const detInv = 1 / det;
te[0] = t11 * detInv;
te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv;
te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv;
te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv;
te[4] = t12 * detInv;
te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv;
te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv;
te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv;
te[8] = t13 * detInv;
te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv;
te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv;
te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv;
te[12] = t14 * detInv;
te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv;
te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv;
te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv;
return this;
}
/**
* Multiplies the columns of this matrix by the given vector.
*
* @param {Vector3} v - The scale vector.
* @return {Matrix4} A reference to this matrix.
*/
scale(v2) {
const te = this.elements;
const x2 = v2.x, y3 = v2.y, z2 = v2.z;
te[0] *= x2;
te[4] *= y3;
te[8] *= z2;
te[1] *= x2;
te[5] *= y3;
te[9] *= z2;
te[2] *= x2;
te[6] *= y3;
te[10] *= z2;
te[3] *= x2;
te[7] *= y3;
te[11] *= z2;
return this;
}
/**
* Gets the maximum scale value of the three axes.
*
* @return {number} The maximum scale.
*/
getMaxScaleOnAxis() {
const te = this.elements;
const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
}
/**
* Sets this matrix as a translation transform from the given vector.
*
* @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector.
* @param {number} y - The amount to translate in the Y axis.
* @param {number} z - The amount to translate in the z axis.
* @return {Matrix4} A reference to this matrix.
*/
makeTranslation(x2, y3, z2) {
if (x2.isVector3) {
this.set(
1,
0,
0,
x2.x,
0,
1,
0,
x2.y,
0,
0,
1,
x2.z,
0,
0,
0,
1
);
} else {
this.set(
1,
0,
0,
x2,
0,
1,
0,
y3,
0,
0,
1,
z2,
0,
0,
0,
1
);
}
return this;
}
/**
* Sets this matrix as a rotational transformation around the X axis by
* the given angle.
*
* @param {number} theta - The rotation in radians.
* @return {Matrix4} A reference to this matrix.
*/
makeRotationX(theta) {
const c5 = Math.cos(theta), s5 = Math.sin(theta);
this.set(
1,
0,
0,
0,
0,
c5,
-s5,
0,
0,
s5,
c5,
0,
0,
0,
0,
1
);
return this;
}
/**
* Sets this matrix as a rotational transformation around the Y axis by
* the given angle.
*
* @param {number} theta - The rotation in radians.
* @return {Matrix4} A reference to this matrix.
*/
makeRotationY(theta) {
const c5 = Math.cos(theta), s5 = Math.sin(theta);
this.set(
c5,
0,
s5,
0,
0,
1,
0,
0,
-s5,
0,
c5,
0,
0,
0,
0,
1
);
return this;
}
/**
* Sets this matrix as a rotational transformation around the Z axis by
* the given angle.
*
* @param {number} theta - The rotation in radians.
* @return {Matrix4} A reference to this matrix.
*/
makeRotationZ(theta) {
const c5 = Math.cos(theta), s5 = Math.sin(theta);
this.set(
c5,
-s5,
0,
0,
s5,
c5,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
return this;
}
/**
* Sets this matrix as a rotational transformation around the given axis by
* the given angle.
*
* This is a somewhat controversial but mathematically sound alternative to
* rotating via Quaternions. See the discussion [here]{@link https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199}.
*
* @param {Vector3} axis - The normalized rotation axis.
* @param {number} angle - The rotation in radians.
* @return {Matrix4} A reference to this matrix.
*/
makeRotationAxis(axis, angle) {
const c5 = Math.cos(angle);
const s5 = Math.sin(angle);
const t6 = 1 - c5;
const x2 = axis.x, y3 = axis.y, z2 = axis.z;
const tx = t6 * x2, ty = t6 * y3;
this.set(
tx * x2 + c5,
tx * y3 - s5 * z2,
tx * z2 + s5 * y3,
0,
tx * y3 + s5 * z2,
ty * y3 + c5,
ty * z2 - s5 * x2,
0,
tx * z2 - s5 * y3,
ty * z2 + s5 * x2,
t6 * z2 * z2 + c5,
0,
0,
0,
0,
1
);
return this;
}
/**
* Sets this matrix as a scale transformation.
*
* @param {number} x - The amount to scale in the X axis.
* @param {number} y - The amount to scale in the Y axis.
* @param {number} z - The amount to scale in the Z axis.
* @return {Matrix4} A reference to this matrix.
*/
makeScale(x2, y3, z2) {
this.set(
x2,
0,
0,
0,
0,
y3,
0,
0,
0,
0,
z2,
0,
0,
0,
0,
1
);
return this;
}
/**
* Sets this matrix as a shear transformation.
*
* @param {number} xy - The amount to shear X by Y.
* @param {number} xz - The amount to shear X by Z.
* @param {number} yx - The amount to shear Y by X.
* @param {number} yz - The amount to shear Y by Z.
* @param {number} zx - The amount to shear Z by X.
* @param {number} zy - The amount to shear Z by Y.
* @return {Matrix4} A reference to this matrix.
*/
makeShear(xy, xz, yx, yz, zx, zy) {
this.set(
1,
yx,
zx,
0,
xy,
1,
zy,
0,
xz,
yz,
1,
0,
0,
0,
0,
1
);
return this;
}
/**
* Sets this matrix to the transformation composed of the given position,
* rotation (Quaternion) and scale.
*
* @param {Vector3} position - The position vector.
* @param {Quaternion} quaternion - The rotation as a Quaternion.
* @param {Vector3} scale - The scale vector.
* @return {Matrix4} A reference to this matrix.
*/
compose(position, quaternion, scale) {
const te = this.elements;
const x2 = quaternion._x, y3 = quaternion._y, z2 = quaternion._z, w2 = quaternion._w;
const x22 = x2 + x2, y22 = y3 + y3, z22 = z2 + z2;
const xx = x2 * x22, xy = x2 * y22, xz = x2 * z22;
const yy = y3 * y22, yz = y3 * z22, zz = z2 * z22;
const wx = w2 * x22, wy = w2 * y22, wz = w2 * z22;
const sx = scale.x, sy = scale.y, sz = scale.z;
te[0] = (1 - (yy + zz)) * sx;
te[1] = (xy + wz) * sx;
te[2] = (xz - wy) * sx;
te[3] = 0;
te[4] = (xy - wz) * sy;
te[5] = (1 - (xx + zz)) * sy;
te[6] = (yz + wx) * sy;
te[7] = 0;
te[8] = (xz + wy) * sz;
te[9] = (yz - wx) * sz;
te[10] = (1 - (xx + yy)) * sz;
te[11] = 0;
te[12] = position.x;
te[13] = position.y;
te[14] = position.z;
te[15] = 1;
return this;
}
/**
* Decomposes this matrix into its position, rotation and scale components
* and provides the result in the given objects.
*
* Note: Not all matrices are decomposable in this way. For example, if an
* object has a non-uniformly scaled parent, then the object's world matrix
* may not be decomposable, and this method may not be appropriate.
*
* @param {Vector3} position - The position vector.
* @param {Quaternion} quaternion - The rotation as a Quaternion.
* @param {Vector3} scale - The scale vector.
* @return {Matrix4} A reference to this matrix.
*/
decompose(position, quaternion, scale) {
const te = this.elements;
let sx = _v1$5.set(te[0], te[1], te[2]).length();
const sy = _v1$5.set(te[4], te[5], te[6]).length();
const sz = _v1$5.set(te[8], te[9], te[10]).length();
const det = this.determinant();
if (det < 0) sx = -sx;
position.x = te[12];
position.y = te[13];
position.z = te[14];
_m1$2.copy(this);
const invSX = 1 / sx;
const invSY = 1 / sy;
const invSZ = 1 / sz;
_m1$2.elements[0] *= invSX;
_m1$2.elements[1] *= invSX;
_m1$2.elements[2] *= invSX;
_m1$2.elements[4] *= invSY;
_m1$2.elements[5] *= invSY;
_m1$2.elements[6] *= invSY;
_m1$2.elements[8] *= invSZ;
_m1$2.elements[9] *= invSZ;
_m1$2.elements[10] *= invSZ;
quaternion.setFromRotationMatrix(_m1$2);
scale.x = sx;
scale.y = sy;
scale.z = sz;
return this;
}
/**
* Creates a perspective projection matrix. This is used internally by
* {@link PerspectiveCamera#updateProjectionMatrix}.
* @param {number} left - Left boundary of the viewing frustum at the near plane.
* @param {number} right - Right boundary of the viewing frustum at the near plane.
* @param {number} top - Top boundary of the viewing frustum at the near plane.
* @param {number} bottom - Bottom boundary of the viewing frustum at the near plane.
* @param {number} near - The distance from the camera to the near plane.
* @param {number} far - The distance from the camera to the far plane.
* @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system.
* @param {boolean} [reversedDepth=false] - Whether to use a reversed depth.
* @return {Matrix4} A reference to this matrix.
*/
makePerspective(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false) {
const te = this.elements;
const x2 = 2 * near / (right - left);
const y3 = 2 * near / (top - bottom);
const a3 = (right + left) / (right - left);
const b3 = (top + bottom) / (top - bottom);
let c5, d3;
if (reversedDepth) {
c5 = near / (far - near);
d3 = far * near / (far - near);
} else {
if (coordinateSystem === WebGLCoordinateSystem) {
c5 = -(far + near) / (far - near);
d3 = -2 * far * near / (far - near);
} else if (coordinateSystem === WebGPUCoordinateSystem) {
c5 = -far / (far - near);
d3 = -far * near / (far - near);
} else {
throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + coordinateSystem);
}
}
te[0] = x2;
te[4] = 0;
te[8] = a3;
te[12] = 0;
te[1] = 0;
te[5] = y3;
te[9] = b3;
te[13] = 0;
te[2] = 0;
te[6] = 0;
te[10] = c5;
te[14] = d3;
te[3] = 0;
te[7] = 0;
te[11] = -1;
te[15] = 0;
return this;
}
/**
* Creates a orthographic projection matrix. This is used internally by
* {@link OrthographicCamera#updateProjectionMatrix}.
* @param {number} left - Left boundary of the viewing frustum at the near plane.
* @param {number} right - Right boundary of the viewing frustum at the near plane.
* @param {number} top - Top boundary of the viewing frustum at the near plane.
* @param {number} bottom - Bottom boundary of the viewing frustum at the near plane.
* @param {number} near - The distance from the camera to the near plane.
* @param {number} far - The distance from the camera to the far plane.
* @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system.
* @param {boolean} [reversedDepth=false] - Whether to use a reversed depth.
* @return {Matrix4} A reference to this matrix.
*/
makeOrthographic(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false) {
const te = this.elements;
const x2 = 2 / (right - left);
const y3 = 2 / (top - bottom);
const a3 = -(right + left) / (right - left);
const b3 = -(top + bottom) / (top - bottom);
let c5, d3;
if (reversedDepth) {
c5 = 1 / (far - near);
d3 = far / (far - near);
} else {
if (coordinateSystem === WebGLCoordinateSystem) {
c5 = -2 / (far - near);
d3 = -(far + near) / (far - near);
} else if (coordinateSystem === WebGPUCoordinateSystem) {
c5 = -1 / (far - near);
d3 = -near / (far - near);
} else {
throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: " + coordinateSystem);
}
}
te[0] = x2;
te[4] = 0;
te[8] = 0;
te[12] = a3;
te[1] = 0;
te[5] = y3;
te[9] = 0;
te[13] = b3;
te[2] = 0;
te[6] = 0;
te[10] = c5;
te[14] = d3;
te[3] = 0;
te[7] = 0;
te[11] = 0;
te[15] = 1;
return this;
}
/**
* Returns `true` if this matrix is equal with the given one.
*
* @param {Matrix4} matrix - The matrix to test for equality.
* @return {boolean} Whether this matrix is equal with the given one.
*/
equals(matrix) {
const te = this.elements;
const me = matrix.elements;
for (let i6 = 0; i6 < 16; i6++) {
if (te[i6] !== me[i6]) return false;
}
return true;
}
/**
* Sets the elements of the matrix from the given array.
*
* @param {Array} array - The matrix elements in column-major order.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Matrix4} A reference to this matrix.
*/
fromArray(array, offset = 0) {
for (let i6 = 0; i6 < 16; i6++) {
this.elements[i6] = array[i6 + offset];
}
return this;
}
/**
* Writes the elements of this matrix to the given array. If no array is provided,
* the method returns a new instance.
*
* @param {Array} [array=[]] - The target array holding the matrix elements in column-major order.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Array} The matrix elements in column-major order.
*/
toArray(array = [], offset = 0) {
const te = this.elements;
array[offset] = te[0];
array[offset + 1] = te[1];
array[offset + 2] = te[2];
array[offset + 3] = te[3];
array[offset + 4] = te[4];
array[offset + 5] = te[5];
array[offset + 6] = te[6];
array[offset + 7] = te[7];
array[offset + 8] = te[8];
array[offset + 9] = te[9];
array[offset + 10] = te[10];
array[offset + 11] = te[11];
array[offset + 12] = te[12];
array[offset + 13] = te[13];
array[offset + 14] = te[14];
array[offset + 15] = te[15];
return array;
}
};
var _v1$5 = /* @__PURE__ */ new Vector3();
var _m1$2 = /* @__PURE__ */ new Matrix4();
var _zero = /* @__PURE__ */ new Vector3(0, 0, 0);
var _one = /* @__PURE__ */ new Vector3(1, 1, 1);
var _x = /* @__PURE__ */ new Vector3();
var _y = /* @__PURE__ */ new Vector3();
var _z = /* @__PURE__ */ new Vector3();
var _matrix$2 = /* @__PURE__ */ new Matrix4();
var _quaternion$3 = /* @__PURE__ */ new Quaternion();
var Euler = class _Euler {
/**
* Constructs a new euler instance.
*
* @param {number} [x=0] - The angle of the x axis in radians.
* @param {number} [y=0] - The angle of the y axis in radians.
* @param {number} [z=0] - The angle of the z axis in radians.
* @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied.
*/
constructor(x2 = 0, y3 = 0, z2 = 0, order = _Euler.DEFAULT_ORDER) {
this.isEuler = true;
this._x = x2;
this._y = y3;
this._z = z2;
this._order = order;
}
/**
* The angle of the x axis in radians.
*
* @type {number}
* @default 0
*/
get x() {
return this._x;
}
set x(value) {
this._x = value;
this._onChangeCallback();
}
/**
* The angle of the y axis in radians.
*
* @type {number}
* @default 0
*/
get y() {
return this._y;
}
set y(value) {
this._y = value;
this._onChangeCallback();
}
/**
* The angle of the z axis in radians.
*
* @type {number}
* @default 0
*/
get z() {
return this._z;
}
set z(value) {
this._z = value;
this._onChangeCallback();
}
/**
* A string representing the order that the rotations are applied.
*
* @type {string}
* @default 'XYZ'
*/
get order() {
return this._order;
}
set order(value) {
this._order = value;
this._onChangeCallback();
}
/**
* Sets the Euler components.
*
* @param {number} x - The angle of the x axis in radians.
* @param {number} y - The angle of the y axis in radians.
* @param {number} z - The angle of the z axis in radians.
* @param {string} [order] - A string representing the order that the rotations are applied.
* @return {Euler} A reference to this Euler instance.
*/
set(x2, y3, z2, order = this._order) {
this._x = x2;
this._y = y3;
this._z = z2;
this._order = order;
this._onChangeCallback();
return this;
}
/**
* Returns a new Euler instance with copied values from this instance.
*
* @return {Euler} A clone of this instance.
*/
clone() {
return new this.constructor(this._x, this._y, this._z, this._order);
}
/**
* Copies the values of the given Euler instance to this instance.
*
* @param {Euler} euler - The Euler instance to copy.
* @return {Euler} A reference to this Euler instance.
*/
copy(euler) {
this._x = euler._x;
this._y = euler._y;
this._z = euler._z;
this._order = euler._order;
this._onChangeCallback();
return this;
}
/**
* Sets the angles of this Euler instance from a pure rotation matrix.
*
* @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
* @param {string} [order] - A string representing the order that the rotations are applied.
* @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
* @return {Euler} A reference to this Euler instance.
*/
setFromRotationMatrix(m2, order = this._order, update = true) {
const te = m2.elements;
const m11 = te[0], m12 = te[4], m13 = te[8];
const m21 = te[1], m22 = te[5], m23 = te[9];
const m31 = te[2], m32 = te[6], m33 = te[10];
switch (order) {
case "XYZ":
this._y = Math.asin(clamp(m13, -1, 1));
if (Math.abs(m13) < 0.9999999) {
this._x = Math.atan2(-m23, m33);
this._z = Math.atan2(-m12, m11);
} else {
this._x = Math.atan2(m32, m22);
this._z = 0;
}
break;
case "YXZ":
this._x = Math.asin(-clamp(m23, -1, 1));
if (Math.abs(m23) < 0.9999999) {
this._y = Math.atan2(m13, m33);
this._z = Math.atan2(m21, m22);
} else {
this._y = Math.atan2(-m31, m11);
this._z = 0;
}
break;
case "ZXY":
this._x = Math.asin(clamp(m32, -1, 1));
if (Math.abs(m32) < 0.9999999) {
this._y = Math.atan2(-m31, m33);
this._z = Math.atan2(-m12, m22);
} else {
this._y = 0;
this._z = Math.atan2(m21, m11);
}
break;
case "ZYX":
this._y = Math.asin(-clamp(m31, -1, 1));
if (Math.abs(m31) < 0.9999999) {
this._x = Math.atan2(m32, m33);
this._z = Math.atan2(m21, m11);
} else {
this._x = 0;
this._z = Math.atan2(-m12, m22);
}
break;
case "YZX":
this._z = Math.asin(clamp(m21, -1, 1));
if (Math.abs(m21) < 0.9999999) {
this._x = Math.atan2(-m23, m22);
this._y = Math.atan2(-m31, m11);
} else {
this._x = 0;
this._y = Math.atan2(m13, m33);
}
break;
case "XZY":
this._z = Math.asin(-clamp(m12, -1, 1));
if (Math.abs(m12) < 0.9999999) {
this._x = Math.atan2(m32, m22);
this._y = Math.atan2(m13, m11);
} else {
this._x = Math.atan2(-m23, m33);
this._y = 0;
}
break;
default:
console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: " + order);
}
this._order = order;
if (update === true) this._onChangeCallback();
return this;
}
/**
* Sets the angles of this Euler instance from a normalized quaternion.
*
* @param {Quaternion} q - A normalized Quaternion.
* @param {string} [order] - A string representing the order that the rotations are applied.
* @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
* @return {Euler} A reference to this Euler instance.
*/
setFromQuaternion(q, order, update) {
_matrix$2.makeRotationFromQuaternion(q);
return this.setFromRotationMatrix(_matrix$2, order, update);
}
/**
* Sets the angles of this Euler instance from the given vector.
*
* @param {Vector3} v - The vector.
* @param {string} [order] - A string representing the order that the rotations are applied.
* @return {Euler} A reference to this Euler instance.
*/
setFromVector3(v2, order = this._order) {
return this.set(v2.x, v2.y, v2.z, order);
}
/**
* Resets the euler angle with a new order by creating a quaternion from this
* euler angle and then setting this euler angle with the quaternion and the
* new order.
*
* Warning: This discards revolution information.
*
* @param {string} [newOrder] - A string representing the new order that the rotations are applied.
* @return {Euler} A reference to this Euler instance.
*/
reorder(newOrder) {
_quaternion$3.setFromEuler(this);
return this.setFromQuaternion(_quaternion$3, newOrder);
}
/**
* Returns `true` if this Euler instance is equal with the given one.
*
* @param {Euler} euler - The Euler instance to test for equality.
* @return {boolean} Whether this Euler instance is equal with the given one.
*/
equals(euler) {
return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order;
}
/**
* Sets this Euler instance's components to values from the given array. The first three
* entries of the array are assign to the x,y and z components. An optional fourth entry
* defines the Euler order.
*
* @param {Array} array - An array holding the Euler component values.
* @return {Euler} A reference to this Euler instance.
*/
fromArray(array) {
this._x = array[0];
this._y = array[1];
this._z = array[2];
if (array[3] !== void 0) this._order = array[3];
this._onChangeCallback();
return this;
}
/**
* Writes the components of this Euler instance to the given array. If no array is provided,
* the method returns a new instance.
*
* @param {Array} [array=[]] - The target array holding the Euler components.
* @param {number} [offset=0] - Index of the first element in the array.
* @return {Array} The Euler components.
*/
toArray(array = [], offset = 0) {
array[offset] = this._x;
array[offset + 1] = this._y;
array[offset + 2] = this._z;
array[offset + 3] = this._order;
return array;
}
_onChange(callback) {
this._onChangeCallback = callback;
return this;
}
_onChangeCallback() {
}
*[Symbol.iterator]() {
yield this._x;
yield this._y;
yield this._z;
yield this._order;
}
};
Euler.DEFAULT_ORDER = "XYZ";
var Layers = class {
/**
* Constructs a new layers instance, with membership
* initially set to layer `0`.
*/
constructor() {
this.mask = 1 | 0;
}
/**
* Sets membership to the given layer, and remove membership all other layers.
*
* @param {number} layer - The layer to set.
*/
set(layer) {
this.mask = (1 << layer | 0) >>> 0;
}
/**
* Adds membership of the given layer.
*
* @param {number} layer - The layer to enable.
*/
enable(layer) {
this.mask |= 1 << layer | 0;
}
/**
* Adds membership to all layers.
*/
enableAll() {
this.mask = 4294967295 | 0;
}
/**
* Toggles the membership of the given layer.
*
* @param {number} layer - The layer to toggle.
*/
toggle(layer) {
this.mask ^= 1 << layer | 0;
}
/**
* Removes membership of the given layer.
*
* @param {number} layer - The layer to enable.
*/
disable(layer) {
this.mask &= ~(1 << layer | 0);
}
/**
* Removes the membership from all layers.
*/
disableAll() {
this.mask = 0;
}
/**
* Returns `true` if this and the given layers object have at least one
* layer in common.
*
* @param {Layers} layers - The layers to test.
* @return {boolean } Whether this and the given layers object have at least one layer in common or not.
*/
test(layers) {
return (this.mask & layers.mask) !== 0;
}
/**
* Returns `true` if the given layer is enabled.
*
* @param {number} layer - The layer to test.
* @return {boolean } Whether the given layer is enabled or not.
*/
isEnabled(layer) {
return (this.mask & (1 << layer | 0)) !== 0;
}
};
var _object3DId = 0;
var _v1$4 = /* @__PURE__ */ new Vector3();
var _q1 = /* @__PURE__ */ new Quaternion();
var _m1$1 = /* @__PURE__ */ new Matrix4();
var _target = /* @__PURE__ */ new Vector3();
var _position$3 = /* @__PURE__ */ new Vector3();
var _scale$2 = /* @__PURE__ */ new Vector3();
var _quaternion$2 = /* @__PURE__ */ new Quaternion();
var _xAxis = /* @__PURE__ */ new Vector3(1, 0, 0);
var _yAxis = /* @__PURE__ */ new Vector3(0, 1, 0);
var _zAxis = /* @__PURE__ */ new Vector3(0, 0, 1);
var _addedEvent = { type: "added" };
var _removedEvent = { type: "removed" };
var _childaddedEvent = { type: "childadded", child: null };
var _childremovedEvent = { type: "childremoved", child: null };
var Object3D = class _Object3D extends EventDispatcher {
/**
* Constructs a new 3D object.
*/
constructor() {
super();
this.isObject3D = true;
Object.defineProperty(this, "id", { value: _object3DId++ });
this.uuid = generateUUID();
this.name = "";
this.type = "Object3D";
this.parent = null;
this.children = [];
this.up = _Object3D.DEFAULT_UP.clone();
const position = new Vector3();
const rotation = new Euler();
const quaternion = new Quaternion();
const scale = new Vector3(1, 1, 1);
function onRotationChange() {
quaternion.setFromEuler(rotation, false);
}
function onQuaternionChange() {
rotation.setFromQuaternion(quaternion, void 0, false);
}
rotation._onChange(onRotationChange);
quaternion._onChange(onQuaternionChange);
Object.defineProperties(this, {
/**
* Represents the object's local position.
*
* @name Object3D#position
* @type {Vector3}
* @default (0,0,0)
*/
position: {
configurable: true,
enumerable: true,
value: position
},
/**
* Represents the object's local rotation as Euler angles, in radians.
*
* @name Object3D#rotation
* @type {Euler}
* @default (0,0,0)
*/
rotation: {
configurable: true,
enumerable: true,
value: rotation
},
/**
* Represents the object's local rotation as Quaternions.
*
* @name Object3D#quaternion
* @type {Quaternion}
*/
quaternion: {
configurable: true,
enumerable: true,
value: quaternion
},
/**
* Represents the object's local scale.
*
* @name Object3D#scale
* @type {Vector3}
* @default (1,1,1)
*/
scale: {
configurable: true,
enumerable: true,
value: scale
},
/**
* Represents the object's model-view matrix.
*
* @name Object3D#modelViewMatrix
* @type {Matrix4}
*/
modelViewMatrix: {
value: new Matrix4()
},
/**
* Represents the object's normal matrix.
*
* @name Object3D#normalMatrix
* @type {Matrix3}
*/
normalMatrix: {
value: new Matrix3()
}
});
this.matrix = new Matrix4();
this.matrixWorld = new Matrix4();
this.matrixAutoUpdate = _Object3D.DEFAULT_MATRIX_AUTO_UPDATE;
this.matrixWorldAutoUpdate = _Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE;
this.matrixWorldNeedsUpdate = false;
this.layers = new Layers();
this.visible = true;
this.castShadow = false;
this.receiveShadow = false;
this.frustumCulled = true;
this.renderOrder = 0;
this.animations = [];
this.customDepthMaterial = void 0;
this.customDistanceMaterial = void 0;
this.userData = {};
}
/**
* A callback that is executed immediately before a 3D object is rendered to a shadow map.
*
* @param {Renderer|WebGLRenderer} renderer - The renderer.
* @param {Object3D} object - The 3D object.
* @param {Camera} camera - The camera that is used to render the scene.
* @param {Camera} shadowCamera - The shadow camera.
* @param {BufferGeometry} geometry - The 3D object's geometry.
* @param {Material} depthMaterial - The depth material.
* @param {Object} group - The geometry group data.
*/
onBeforeShadow() {
}
/**
* A callback that is executed immediately after a 3D object is rendered to a shadow map.
*
* @param {Renderer|WebGLRenderer} renderer - The renderer.
* @param {Object3D} object - The 3D object.
* @param {Camera} camera - The camera that is used to render the scene.
* @param {Camera} shadowCamera - The shadow camera.
* @param {BufferGeometry} geometry - The 3D object's geometry.
* @param {Material} depthMaterial - The depth material.
* @param {Object} group - The geometry group data.
*/
onAfterShadow() {
}
/**
* A callback that is executed immediately before a 3D object is rendered.
*
* @param {Renderer|WebGLRenderer} renderer - The renderer.
* @param {Object3D} object - The 3D object.
* @param {Camera} camera - The camera that is used to render the scene.
* @param {BufferGeometry} geometry - The 3D object's geometry.
* @param {Material} material - The 3D object's material.
* @param {Object} group - The geometry group data.
*/
onBeforeRender() {
}
/**
* A callback that is executed immediately after a 3D object is rendered.
*
* @param {Renderer|WebGLRenderer} renderer - The renderer.
* @param {Object3D} object - The 3D object.
* @param {Camera} camera - The camera that is used to render the scene.
* @param {BufferGeometry} geometry - The 3D object's geometry.
* @param {Material} material - The 3D object's material.
* @param {Object} group - The geometry group data.
*/
onAfterRender() {
}
/**
* Applies the given transformation matrix to the object and updates the object's position,
* rotation and scale.
*
* @param {Matrix4} matrix - The transformation matrix.
*/
applyMatrix4(matrix) {
if (this.matrixAutoUpdate) this.updateMatrix();
this.matrix.premultiply(matrix);
this.matrix.decompose(this.position, this.quaternion, this.scale);
}
/**
* Applies a rotation represented by given the quaternion to the 3D object.
*
* @param {Quaternion} q - The quaternion.
* @return {Object3D} A reference to this instance.
*/
applyQuaternion(q) {
this.quaternion.premultiply(q);
return this;
}
/**
* Sets the given rotation represented as an axis/angle couple to the 3D object.
*
* @param {Vector3} axis - The (normalized) axis vector.
* @param {number} angle - The angle in radians.
*/
setRotationFromAxisAngle(axis, angle) {
this.quaternion.setFromAxisAngle(axis, angle);
}
/**
* Sets the given rotation represented as Euler angles to the 3D object.
*
* @param {Euler} euler - The Euler angles.
*/
setRotationFromEuler(euler) {
this.quaternion.setFromEuler(euler, true);
}
/**
* Sets the given rotation represented as rotation matrix to the 3D object.
*
* @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be
* a pure rotation matrix (i.e, unscaled).
*/
setRotationFromMatrix(m2) {
this.quaternion.setFromRotationMatrix(m2);
}
/**
* Sets the given rotation represented as a Quaternion to the 3D object.
*
* @param {Quaternion} q - The Quaternion
*/
setRotationFromQuaternion(q) {
this.quaternion.copy(q);
}
/**
* Rotates the 3D object along an axis in local space.
*
* @param {Vector3} axis - The (normalized) axis vector.
* @param {number} angle - The angle in radians.
* @return {Object3D} A reference to this instance.
*/
rotateOnAxis(axis, angle) {
_q1.setFromAxisAngle(axis, angle);
this.quaternion.multiply(_q1);
return this;
}
/**
* Rotates the 3D object along an axis in world space.
*
* @param {Vector3} axis - The (normalized) axis vector.
* @param {number} angle - The angle in radians.
* @return {Object3D} A reference to this instance.
*/
rotateOnWorldAxis(axis, angle) {
_q1.setFromAxisAngle(axis, angle);
this.quaternion.premultiply(_q1);
return this;
}
/**
* Rotates the 3D object around its X axis in local space.
*
* @param {number} angle - The angle in radians.
* @return {Object3D} A reference to this instance.
*/
rotateX(angle) {
return this.rotateOnAxis(_xAxis, angle);
}
/**
* Rotates the 3D object around its Y axis in local space.
*
* @param {number} angle - The angle in radians.
* @return {Object3D} A reference to this instance.
*/
rotateY(angle) {
return this.rotateOnAxis(_yAxis, angle);
}
/**
* Rotates the 3D object around its Z axis in local space.
*
* @param {number} angle - The angle in radians.
* @return {Object3D} A reference to this instance.
*/
rotateZ(angle) {
return this.rotateOnAxis(_zAxis, angle);
}
/**
* Translate the 3D object by a distance along the given axis in local space.
*
* @param {Vector3} axis - The (normalized) axis vector.
* @param {number} distance - The distance in world units.
* @return {Object3D} A reference to this instance.
*/
translateOnAxis(axis, distance) {
_v1$4.copy(axis).applyQuaternion(this.quaternion);
this.position.add(_v1$4.multiplyScalar(distance));
return this;
}
/**
* Translate the 3D object by a distance along its X-axis in local space.
*
* @param {number} distance - The distance in world units.
* @return {Object3D} A reference to this instance.
*/
translateX(distance) {
return this.translateOnAxis(_xAxis, distance);
}
/**
* Translate the 3D object by a distance along its Y-axis in local space.
*
* @param {number} distance - The distance in world units.
* @return {Object3D} A reference to this instance.
*/
translateY(distance) {
return this.translateOnAxis(_yAxis, distance);
}
/**
* Translate the 3D object by a distance along its Z-axis in local space.
*
* @param {number} distance - The distance in world units.
* @return {Object3D} A reference to this instance.
*/
translateZ(distance) {
return this.translateOnAxis(_zAxis, distance);
}
/**
* Converts the given vector from this 3D object's local space to world space.
*
* @param {Vector3} vector - The vector to convert.
* @return {Vector3} The converted vector.
*/
localToWorld(vector) {
this.updateWorldMatrix(true, false);
return vector.applyMatrix4(this.matrixWorld);
}
/**
* Converts the given vector from this 3D object's word space to local space.
*
* @param {Vector3} vector - The vector to convert.
* @return {Vector3} The converted vector.
*/
worldToLocal(vector) {
this.updateWorldMatrix(true, false);
return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert());
}
/**
* Rotates the object to face a point in world space.
*
* This method does not support objects having non-uniformly-scaled parent(s).
*
* @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space
* @param {number} [y] - The y coordinate in world space.
* @param {number} [z] - The z coordinate in world space.
*/
lookAt(x2, y3, z2) {
if (x2.isVector3) {
_target.copy(x2);
} else {
_target.set(x2, y3, z2);
}
const parent = this.parent;
this.updateWorldMatrix(true, false);
_position$3.setFromMatrixPosition(this.matrixWorld);
if (this.isCamera || this.isLight) {
_m1$1.lookAt(_position$3, _target, this.up);
} else {
_m1$1.lookAt(_target, _position$3, this.up);
}
this.quaternion.setFromRotationMatrix(_m1$1);
if (parent) {
_m1$1.extractRotation(parent.matrixWorld);
_q1.setFromRotationMatrix(_m1$1);
this.quaternion.premultiply(_q1.invert());
}
}
/**
* Adds the given 3D object as a child to this 3D object. An arbitrary number of
* objects may be added. Any current parent on an object passed in here will be
* removed, since an object can have at most one parent.
*
* @fires Object3D#added
* @fires Object3D#childadded
* @param {Object3D} object - The 3D object to add.
* @return {Object3D} A reference to this instance.
*/
add(object) {
if (arguments.length > 1) {
for (let i6 = 0; i6 < arguments.length; i6++) {
this.add(arguments[i6]);
}
return this;
}
if (object === this) {
console.error("THREE.Object3D.add: object can't be added as a child of itself.", object);
return this;
}
if (object && object.isObject3D) {
object.removeFromParent();
object.parent = this;
this.children.push(object);
object.dispatchEvent(_addedEvent);
_childaddedEvent.child = object;
this.dispatchEvent(_childaddedEvent);
_childaddedEvent.child = null;
} else {
console.error("THREE.Object3D.add: object not an instance of THREE.Object3D.", object);
}
return this;
}
/**
* Removes the given 3D object as child from this 3D object.
* An arbitrary number of objects may be removed.
*
* @fires Object3D#removed
* @fires Object3D#childremoved
* @param {Object3D} object - The 3D object to remove.
* @return {Object3D} A reference to this instance.
*/
remove(object) {
if (arguments.length > 1) {
for (let i6 = 0; i6 < arguments.length; i6++) {
this.remove(arguments[i6]);
}
return this;
}
const index = this.children.indexOf(object);
if (index !== -1) {
object.parent = null;
this.children.splice(index, 1);
object.dispatchEvent(_removedEvent);
_childremovedEvent.child = object;
this.dispatchEvent(_childremovedEvent);
_childremovedEvent.child = null;
}
return this;
}
/**
* Removes this 3D object from its current parent.
*
* @fires Object3D#removed
* @fires Object3D#childremoved
* @return {Object3D} A reference to this instance.
*/
removeFromParent() {
const parent = this.parent;
if (parent !== null) {
parent.remove(this);
}
return this;
}
/**
* Removes all child objects.
*
* @fires Object3D#removed
* @fires Object3D#childremoved
* @return {Object3D} A reference to this instance.
*/
clear() {
return this.remove(...this.children);
}
/**
* Adds the given 3D object as a child of this 3D object, while maintaining the object's world
* transform. This method does not support scene graphs having non-uniformly-scaled nodes(s).
*
* @fires Object3D#added
* @fires Object3D#childadded
* @param {Object3D} object - The 3D object to attach.
* @return {Object3D} A reference to this instance.
*/
attach(object) {
this.updateWorldMatrix(true, false);
_m1$1.copy(this.matrixWorld).invert();
if (object.parent !== null) {
object.parent.updateWorldMatrix(true, false);
_m1$1.multiply(object.parent.matrixWorld);
}
object.applyMatrix4(_m1$1);
object.removeFromParent();
object.parent = this;
this.children.push(object);
object.updateWorldMatrix(false, true);
object.dispatchEvent(_addedEvent);
_childaddedEvent.child = object;
this.dispatchEvent(_childaddedEvent);
_childaddedEvent.child = null;
return this;
}
/**
* Searches through the 3D object and its children, starting with the 3D object
* itself, and returns the first with a matching ID.
*
* @param {number} id - The id.
* @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
*/
getObjectById(id) {
return this.getObjectByProperty("id", id);
}
/**
* Searches through the 3D object and its children, starting with the 3D object
* itself, and returns the first with a matching name.
*
* @param {string} name - The name.
* @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
*/
getObjectByName(name) {
return this.getObjectByProperty("name", name);
}
/**
* Searches through the 3D object and its children, starting with the 3D object
* itself, and returns the first with a matching property value.
*
* @param {string} name - The name of the property.
* @param {any} value - The value.
* @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
*/
getObjectByProperty(name, value) {
if (this[name] === value) return this;
for (let i6 = 0, l3 = this.children.length; i6 < l3; i6++) {
const child = this.children[i6];
const object = child.getObjectByProperty(name, value);
if (object !== void 0) {
return object;
}
}
return void 0;
}
/**
* Searches through the 3D object and its children, starting with the 3D object
* itself, and returns all 3D objects with a matching property value.
*
* @param {string} name - The name of the property.
* @param {any} value - The value.
* @param {Array} result - The method stores the result in this array.
* @return {Array} The found 3D objects.
*/
getObjectsByProperty(name, value, result = []) {
if (this[name] === value) result.push(this);
const children = this.children;
for (let i6 = 0, l3 = children.length; i6 < l3; i6++) {
children[i6].getObjectsByProperty(name, value, result);
}
return result;
}
/**
* Returns a vector representing the position of the 3D object in world space.
*
* @param {Vector3} target - The target vector the result is stored to.
* @return {Vector3} The 3D object's position in world space.
*/
getWorldPosition(target) {
this.updateWorldMatrix(true, false);
return target.setFromMatrixPosition(this.matrixWorld);
}
/**
* Returns a Quaternion representing the position of the 3D object in world space.
*
* @param {Quaternion} target - The target Quaternion the result is stored to.
* @return {Quaternion} The 3D object's rotation in world space.
*/
getWorldQuaternion(target) {
this.updateWorldMatrix(true, false);
this.matrixWorld.decompose(_position$3, target, _scale$2);
return target;
}
/**
* Returns a vector representing the scale of the 3D object in world space.
*
* @param {Vector3} target - The target vector the result is stored to.
* @return {Vector3} The 3D object's scale in world space.
*/
getWorldScale(target) {
this.updateWorldMatrix(true, false);
this.matrixWorld.decompose(_position$3, _quaternion$2, target);
return target;
}
/**
* Returns a vector representing the ("look") direction of the 3D object in world space.
*
* @param {Vector3} target - The target vector the result is stored to.
* @return {Vector3} The 3D object's direction in world space.
*/
getWorldDirection(target) {
this.updateWorldMatrix(true, false);
const e8 = this.matrixWorld.elements;
return target.set(e8[8], e8[9], e8[10]).normalize();
}
/**
* Abstract method to get intersections between a casted ray and this
* 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points}
* implement this method in order to use raycasting.
*
* @abstract
* @param {Raycaster} raycaster - The raycaster.
* @param {Array