@google/model-viewer
Version:
Easily display interactive 3D models on the web and in AR!
1,898 lines (1,894 loc) • 2.71 MB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ModelViewerElement = {}));
})(this, (function (exports) { 'use strict';
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/ const t$2 = globalThis, e$2 = t$2.ShadowRoot && (void 0 === t$2.ShadyCSS || t$2.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, s$2 = Symbol(), o$4 = new WeakMap;
let n$4 = class n {
get styleSheet() {
let t = this.o;
const s = this.t;
if (e$2 && void 0 === t) {
const e = void 0 !== s && 1 === s.length;
e && (t = o$4.get(s)), void 0 === t && ((this.o = t = new CSSStyleSheet).replaceSync(this.cssText), e && o$4.set(s, t));
}
return t;
}
toString() {
return this.cssText;
}
constructor(t, e, o){
if (this._$cssResult$ = true, o !== s$2) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
this.cssText = t, this.t = e;
}
};
const r$3 = (t)=>new n$4("string" == typeof t ? t : t + "", void 0, s$2), S$2 = (s, o)=>{
if (e$2) s.adoptedStyleSheets = o.map((t)=>t instanceof CSSStyleSheet ? t : t.styleSheet);
else for (const e of o){
const o = document.createElement("style"), n = t$2.litNonce;
void 0 !== n && o.setAttribute("nonce", n), o.textContent = e.cssText, s.appendChild(o);
}
}, c$3 = e$2 ? (t)=>t : (t)=>t instanceof CSSStyleSheet ? ((t)=>{
let e = "";
for (const s of t.cssRules)e += s.cssText;
return r$3(e);
})(t) : t;
var _Symbol, _a$a, _a1;
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/ const { is: i$3, defineProperty: e$1, getOwnPropertyDescriptor: h$1, getOwnPropertyNames: r$2, getOwnPropertySymbols: o$3, getPrototypeOf: n$3 } = Object, a$2 = globalThis, c$2 = a$2.trustedTypes, l$1 = c$2 ? c$2.emptyScript : "", p$1 = a$2.reactiveElementPolyfillSupport, d$1 = (t, s)=>t, u$2 = {
toAttribute (t, s) {
switch(s){
case Boolean:
t = t ? l$1 : null;
break;
case Object:
case Array:
t = null == t ? t : JSON.stringify(t);
}
return t;
},
fromAttribute (t, s) {
let i = t;
switch(s){
case Boolean:
i = null !== t;
break;
case Number:
i = null === t ? null : Number(t);
break;
case Object:
case Array:
try {
i = JSON.parse(t);
} catch (t) {
i = null;
}
}
return i;
}
}, f$1 = (t, s)=>!i$3(t, s), b$2 = {
attribute: true,
type: String,
converter: u$2,
reflect: false,
useDefault: false,
hasChanged: f$1
};
(_Symbol = Symbol).metadata ?? (_Symbol.metadata = Symbol("metadata")), (_a$a = a$2).litPropertyMetadata ?? (_a$a.litPropertyMetadata = new WeakMap);
let y$2 = class y extends HTMLElement {
static addInitializer(t) {
this._$Ei(), (this.l ?? (this.l = [])).push(t);
}
static get observedAttributes() {
return this.finalize(), this._$Eh && [
...this._$Eh.keys()
];
}
static createProperty(t, s = b$2) {
if (s.state && (s.attribute = false), this._$Ei(), this.prototype.hasOwnProperty(t) && ((s = Object.create(s)).wrapped = true), this.elementProperties.set(t, s), !s.noAccessor) {
const i = Symbol(), h = this.getPropertyDescriptor(t, i, s);
void 0 !== h && e$1(this.prototype, t, h);
}
}
static getPropertyDescriptor(t, s, i) {
const { get: e, set: r } = h$1(this.prototype, t) ?? {
get () {
return this[s];
},
set (t) {
this[s] = t;
}
};
return {
get: e,
set (s) {
const h = e?.call(this);
r?.call(this, s), this.requestUpdate(t, h, i);
},
configurable: true,
enumerable: true
};
}
static getPropertyOptions(t) {
return this.elementProperties.get(t) ?? b$2;
}
static _$Ei() {
if (this.hasOwnProperty(d$1("elementProperties"))) return;
const t = n$3(this);
t.finalize(), void 0 !== t.l && (this.l = [
...t.l
]), this.elementProperties = new Map(t.elementProperties);
}
static finalize() {
if (this.hasOwnProperty(d$1("finalized"))) return;
if (this.finalized = true, this._$Ei(), this.hasOwnProperty(d$1("properties"))) {
const t = this.properties, s = [
...r$2(t),
...o$3(t)
];
for (const i of s)this.createProperty(i, t[i]);
}
const t = this[Symbol.metadata];
if (null !== t) {
const s = litPropertyMetadata.get(t);
if (void 0 !== s) for (const [t, i] of s)this.elementProperties.set(t, i);
}
this._$Eh = new Map;
for (const [t, s] of this.elementProperties){
const i = this._$Eu(t, s);
void 0 !== i && this._$Eh.set(i, t);
}
this.elementStyles = this.finalizeStyles(this.styles);
}
static finalizeStyles(s) {
const i = [];
if (Array.isArray(s)) {
const e = new Set(s.flat(1 / 0).reverse());
for (const s of e)i.unshift(c$3(s));
} else void 0 !== s && i.push(c$3(s));
return i;
}
static _$Eu(t, s) {
const i = s.attribute;
return false === i ? void 0 : "string" == typeof i ? i : "string" == typeof t ? t.toLowerCase() : void 0;
}
_$Ev() {
this._$ES = new Promise((t)=>this.enableUpdating = t), this._$AL = new Map, this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t)=>t(this));
}
addController(t) {
(this._$EO ?? (this._$EO = new Set)).add(t), void 0 !== this.renderRoot && this.isConnected && t.hostConnected?.();
}
removeController(t) {
this._$EO?.delete(t);
}
_$E_() {
const t = new Map, s = this.constructor.elementProperties;
for (const i of s.keys())this.hasOwnProperty(i) && (t.set(i, this[i]), delete this[i]);
t.size > 0 && (this._$Ep = t);
}
createRenderRoot() {
const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
return S$2(t, this.constructor.elementStyles), t;
}
connectedCallback() {
this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this.enableUpdating(true), this._$EO?.forEach((t)=>t.hostConnected?.());
}
enableUpdating(t) {}
disconnectedCallback() {
this._$EO?.forEach((t)=>t.hostDisconnected?.());
}
attributeChangedCallback(t, s, i) {
this._$AK(t, i);
}
_$ET(t, s) {
const i = this.constructor.elementProperties.get(t), e = this.constructor._$Eu(t, i);
if (void 0 !== e && true === i.reflect) {
const h = (void 0 !== i.converter?.toAttribute ? i.converter : u$2).toAttribute(s, i.type);
this._$Em = t, null == h ? this.removeAttribute(e) : this.setAttribute(e, h), this._$Em = null;
}
}
_$AK(t, s) {
const i = this.constructor, e = i._$Eh.get(t);
if (void 0 !== e && this._$Em !== e) {
const t = i.getPropertyOptions(e), h = "function" == typeof t.converter ? {
fromAttribute: t.converter
} : void 0 !== t.converter?.fromAttribute ? t.converter : u$2;
this._$Em = e;
const r = h.fromAttribute(s, t.type);
this[e] = r ?? this._$Ej?.get(e) ?? r, this._$Em = null;
}
}
requestUpdate(t, s, i, e = false, h) {
if (void 0 !== t) {
const r = this.constructor;
if (false === e && (h = this[t]), i ?? (i = r.getPropertyOptions(t)), !((i.hasChanged ?? f$1)(h, s) || i.useDefault && i.reflect && h === this._$Ej?.get(t) && !this.hasAttribute(r._$Eu(t, i)))) return;
this.C(t, s, i);
}
false === this.isUpdatePending && (this._$ES = this._$EP());
}
C(t, s, { useDefault: i, reflect: e, wrapped: h }, r) {
i && !(this._$Ej ?? (this._$Ej = new Map)).has(t) && (this._$Ej.set(t, r ?? s ?? this[t]), true !== h || void 0 !== r) || (this._$AL.has(t) || (this.hasUpdated || i || (s = void 0), this._$AL.set(t, s)), true === e && this._$Em !== t && (this._$Eq ?? (this._$Eq = new Set)).add(t));
}
async _$EP() {
this.isUpdatePending = true;
try {
await this._$ES;
} catch (t) {
Promise.reject(t);
}
const t = this.scheduleUpdate();
return null != t && await t, !this.isUpdatePending;
}
scheduleUpdate() {
return this.performUpdate();
}
performUpdate() {
if (!this.isUpdatePending) return;
if (!this.hasUpdated) {
if (this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this._$Ep) {
for (const [t, s] of this._$Ep)this[t] = s;
this._$Ep = void 0;
}
const t = this.constructor.elementProperties;
if (t.size > 0) for (const [s, i] of t){
const { wrapped: t } = i, e = this[s];
true !== t || this._$AL.has(s) || void 0 === e || this.C(s, void 0, i, e);
}
}
let t = false;
const s = this._$AL;
try {
t = this.shouldUpdate(s), t ? (this.willUpdate(s), this._$EO?.forEach((t)=>t.hostUpdate?.()), this.update(s)) : this._$EM();
} catch (s) {
throw t = false, this._$EM(), s;
}
t && this._$AE(s);
}
willUpdate(t) {}
_$AE(t) {
this._$EO?.forEach((t)=>t.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t)), this.updated(t);
}
_$EM() {
this._$AL = new Map, this.isUpdatePending = false;
}
get updateComplete() {
return this.getUpdateComplete();
}
getUpdateComplete() {
return this._$ES;
}
shouldUpdate(t) {
return true;
}
update(t) {
this._$Eq && (this._$Eq = this._$Eq.forEach((t)=>this._$ET(t, this[t]))), this._$EM();
}
updated(t) {}
firstUpdated(t) {}
constructor(){
super(), this._$Ep = void 0, this.isUpdatePending = false, this.hasUpdated = false, this._$Em = null, this._$Ev();
}
};
y$2.elementStyles = [], y$2.shadowRootOptions = {
mode: "open"
}, y$2[d$1("elementProperties")] = new Map, y$2[d$1("finalized")] = new Map, p$1?.({
ReactiveElement: y$2
}), ((_a1 = a$2).reactiveElementVersions ?? (_a1.reactiveElementVersions = [])).push("2.1.2");
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/ const o$2 = {
attribute: true,
type: String,
converter: u$2,
reflect: false,
hasChanged: f$1
}, r$1 = (t = o$2, e, r)=>{
const { kind: n, metadata: i } = r;
let s = globalThis.litPropertyMetadata.get(i);
if (void 0 === s && globalThis.litPropertyMetadata.set(i, s = new Map), "setter" === n && ((t = Object.create(t)).wrapped = true), s.set(r.name, t), "accessor" === n) {
const { name: o } = r;
return {
set (r) {
const n = e.get.call(this);
e.set.call(this, r), this.requestUpdate(o, n, t, true, r);
},
init (e) {
return void 0 !== e && this.C(o, void 0, t, e), e;
}
};
}
if ("setter" === n) {
const { name: o } = r;
return function(r) {
const n = this[o];
e.call(this, r), this.requestUpdate(o, n, t, true, r);
};
}
throw Error("Unsupported decorator location: " + n);
};
function n$2(t) {
return (e, o)=>"object" == typeof o ? r$1(t, e, o) : ((t, e, o)=>{
const r = e.hasOwnProperty(o);
return e.constructor.createProperty(o, t), r ? Object.getOwnPropertyDescriptor(e, o) : void 0;
})(t, e, o);
}
/**
* @license
* Copyright 2010-2025 Three.js Authors
* SPDX-License-Identifier: MIT
*/ const REVISION = '182';
/**
* Disables face culling.
*
* @type {number}
* @constant
*/ const CullFaceNone = 0;
/**
* Culls back faces.
*
* @type {number}
* @constant
*/ const CullFaceBack = 1;
/**
* Culls front faces.
*
* @type {number}
* @constant
*/ const CullFaceFront = 2;
/**
* Filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm.
*
* @type {number}
* @constant
*/ const PCFShadowMap = 1;
/**
* Filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm with
* better soft shadows especially when using low-resolution shadow maps.
*
* @type {number}
* @constant
*/ const PCFSoftShadowMap = 2;
/**
* Filters shadow maps using the Variance Shadow Map (VSM) algorithm.
* When using VSMShadowMap all shadow receivers will also cast shadows.
*
* @type {number}
* @constant
*/ const VSMShadowMap = 3;
/**
* Only front faces are rendered.
*
* @type {number}
* @constant
*/ const FrontSide = 0;
/**
* Only back faces are rendered.
*
* @type {number}
* @constant
*/ const BackSide = 1;
/**
* Both front and back faces are rendered.
*
* @type {number}
* @constant
*/ const DoubleSide = 2;
/**
* No blending is performed which effectively disables
* alpha transparency.
*
* @type {number}
* @constant
*/ const NoBlending = 0;
/**
* The default blending.
*
* @type {number}
* @constant
*/ const NormalBlending = 1;
/**
* Represents additive blending.
*
* @type {number}
* @constant
*/ const AdditiveBlending = 2;
/**
* Represents subtractive blending.
*
* @type {number}
* @constant
*/ const SubtractiveBlending = 3;
/**
* Represents multiply blending.
*
* @type {number}
* @constant
*/ const MultiplyBlending = 4;
/**
* Represents custom blending.
*
* @type {number}
* @constant
*/ const CustomBlending = 5;
/**
* A `source + destination` blending equation.
*
* @type {number}
* @constant
*/ const AddEquation = 100;
/**
* A `source - destination` blending equation.
*
* @type {number}
* @constant
*/ const SubtractEquation = 101;
/**
* A `destination - source` blending equation.
*
* @type {number}
* @constant
*/ const ReverseSubtractEquation = 102;
/**
* A blend equation that uses the minimum of source and destination.
*
* @type {number}
* @constant
*/ const MinEquation = 103;
/**
* A blend equation that uses the maximum of source and destination.
*
* @type {number}
* @constant
*/ const MaxEquation = 104;
/**
* Multiplies all colors by `0`.
*
* @type {number}
* @constant
*/ const ZeroFactor = 200;
/**
* Multiplies all colors by `1`.
*
* @type {number}
* @constant
*/ const OneFactor = 201;
/**
* Multiplies all colors by the source colors.
*
* @type {number}
* @constant
*/ const SrcColorFactor = 202;
/**
* Multiplies all colors by `1` minus each source color.
*
* @type {number}
* @constant
*/ const OneMinusSrcColorFactor = 203;
/**
* Multiplies all colors by the source alpha value.
*
* @type {number}
* @constant
*/ const SrcAlphaFactor = 204;
/**
* Multiplies all colors by 1 minus the source alpha value.
*
* @type {number}
* @constant
*/ const OneMinusSrcAlphaFactor = 205;
/**
* Multiplies all colors by the destination alpha value.
*
* @type {number}
* @constant
*/ const DstAlphaFactor = 206;
/**
* Multiplies all colors by `1` minus the destination alpha value.
*
* @type {number}
* @constant
*/ const OneMinusDstAlphaFactor = 207;
/**
* Multiplies all colors by the destination color.
*
* @type {number}
* @constant
*/ const DstColorFactor = 208;
/**
* Multiplies all colors by `1` minus each destination color.
*
* @type {number}
* @constant
*/ const OneMinusDstColorFactor = 209;
/**
* Multiplies the RGB colors by the smaller of either the source alpha
* value or the value of `1` minus the destination alpha value. The alpha
* value is multiplied by `1`.
*
* @type {number}
* @constant
*/ const SrcAlphaSaturateFactor = 210;
/**
* Multiplies all colors by a constant color.
*
* @type {number}
* @constant
*/ const ConstantColorFactor = 211;
/**
* Multiplies all colors by `1` minus a constant color.
*
* @type {number}
* @constant
*/ const OneMinusConstantColorFactor = 212;
/**
* Multiplies all colors by a constant alpha value.
*
* @type {number}
* @constant
*/ const ConstantAlphaFactor = 213;
/**
* Multiplies all colors by 1 minus a constant alpha value.
*
* @type {number}
* @constant
*/ const OneMinusConstantAlphaFactor = 214;
/**
* Never pass.
*
* @type {number}
* @constant
*/ const NeverDepth = 0;
/**
* Always pass.
*
* @type {number}
* @constant
*/ const AlwaysDepth = 1;
/**
* Pass if the incoming value is less than the depth buffer value.
*
* @type {number}
* @constant
*/ const LessDepth = 2;
/**
* Pass if the incoming value is less than or equal to the depth buffer value.
*
* @type {number}
* @constant
*/ const LessEqualDepth = 3;
/**
* Pass if the incoming value equals the depth buffer value.
*
* @type {number}
* @constant
*/ const EqualDepth = 4;
/**
* Pass if the incoming value is greater than or equal to the depth buffer value.
*
* @type {number}
* @constant
*/ const GreaterEqualDepth = 5;
/**
* Pass if the incoming value is greater than the depth buffer value.
*
* @type {number}
* @constant
*/ const GreaterDepth = 6;
/**
* Pass if the incoming value is not equal to the depth buffer value.
*
* @type {number}
* @constant
*/ const NotEqualDepth = 7;
/**
* Multiplies the environment map color with the surface color.
*
* @type {number}
* @constant
*/ const MultiplyOperation = 0;
/**
* Uses reflectivity to blend between the two colors.
*
* @type {number}
* @constant
*/ const MixOperation = 1;
/**
* Adds the two colors.
*
* @type {number}
* @constant
*/ const AddOperation = 2;
/**
* No tone mapping is applied.
*
* @type {number}
* @constant
*/ const NoToneMapping = 0;
/**
* Linear tone mapping.
*
* @type {number}
* @constant
*/ const LinearToneMapping = 1;
/**
* Reinhard tone mapping.
*
* @type {number}
* @constant
*/ const ReinhardToneMapping = 2;
/**
* Cineon tone mapping.
*
* @type {number}
* @constant
*/ const CineonToneMapping = 3;
/**
* ACES Filmic tone mapping.
*
* @type {number}
* @constant
*/ const ACESFilmicToneMapping = 4;
/**
* Custom tone mapping.
*
* Expects a custom implementation by modifying shader code of the material's fragment shader.
*
* @type {number}
* @constant
*/ const CustomToneMapping = 5;
/**
* AgX tone mapping.
*
* @type {number}
* @constant
*/ const AgXToneMapping = 6;
/**
* Neutral tone mapping.
*
* Implementation based on the Khronos 3D Commerce Group standard tone mapping.
*
* @type {number}
* @constant
*/ const NeutralToneMapping = 7;
/**
* The skinned mesh shares the same world space as the skeleton.
*
* @type {string}
* @constant
*/ const AttachedBindMode = 'attached';
/**
* The skinned mesh does not share the same world space as the skeleton.
* This is useful when a skeleton is shared across multiple skinned meshes.
*
* @type {string}
* @constant
*/ const DetachedBindMode = 'detached';
/**
* Maps textures using the geometry's UV coordinates.
*
* @type {number}
* @constant
*/ const UVMapping = 300;
/**
* Reflection mapping for cube textures.
*
* @type {number}
* @constant
*/ const CubeReflectionMapping = 301;
/**
* Refraction mapping for cube textures.
*
* @type {number}
* @constant
*/ const CubeRefractionMapping = 302;
/**
* Reflection mapping for equirectangular textures.
*
* @type {number}
* @constant
*/ const EquirectangularReflectionMapping = 303;
/**
* Refraction mapping for equirectangular textures.
*
* @type {number}
* @constant
*/ const EquirectangularRefractionMapping = 304;
/**
* Reflection mapping for PMREM textures.
*
* @type {number}
* @constant
*/ const CubeUVReflectionMapping = 306;
/**
* The texture will simply repeat to infinity.
*
* @type {number}
* @constant
*/ const RepeatWrapping = 1000;
/**
* The last pixel of the texture stretches to the edge of the mesh.
*
* @type {number}
* @constant
*/ const ClampToEdgeWrapping = 1001;
/**
* The texture will repeats to infinity, mirroring on each repeat.
*
* @type {number}
* @constant
*/ const MirroredRepeatWrapping = 1002;
/**
* Returns the value of the texture element that is nearest (in Manhattan distance)
* to the specified texture coordinates.
*
* @type {number}
* @constant
*/ const NearestFilter = 1003;
/**
* Chooses the mipmap that most closely matches the size of the pixel being textured
* and uses the `NearestFilter` criterion (the texel nearest to the center of the pixel)
* to produce a texture value.
*
* @type {number}
* @constant
*/ const NearestMipmapNearestFilter = 1004;
/**
* Chooses the two mipmaps that most closely match the size of the pixel being textured and
* uses the `NearestFilter` criterion to produce a texture value from each mipmap.
* The final texture value is a weighted average of those two values.
*
* @type {number}
* @constant
*/ const NearestMipmapLinearFilter = 1005;
/**
* Returns the weighted average of the four texture elements that are closest to the specified
* texture coordinates, and can include items wrapped or repeated from other parts of a texture,
* depending on the values of `wrapS` and `wrapT`, and on the exact mapping.
*
* @type {number}
* @constant
*/ const LinearFilter = 1006;
/**
* Chooses the mipmap that most closely matches the size of the pixel being textured and uses
* the `LinearFilter` criterion (a weighted average of the four texels that are closest to the
* center of the pixel) to produce a texture value.
*
* @type {number}
* @constant
*/ const LinearMipmapNearestFilter = 1007;
/**
* Chooses the two mipmaps that most closely match the size of the pixel being textured and uses
* the `LinearFilter` criterion to produce a texture value from each mipmap. The final texture value
* is a weighted average of those two values.
*
* @type {number}
* @constant
*/ const LinearMipmapLinearFilter = 1008;
const LinearMipMapLinearFilter = 1008; // legacy
/**
* An unsigned byte data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedByteType = 1009;
/**
* A byte data type for textures.
*
* @type {number}
* @constant
*/ const ByteType = 1010;
/**
* A short data type for textures.
*
* @type {number}
* @constant
*/ const ShortType = 1011;
/**
* An unsigned short data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedShortType = 1012;
/**
* An int data type for textures.
*
* @type {number}
* @constant
*/ const IntType = 1013;
/**
* An unsigned int data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedIntType = 1014;
/**
* A float data type for textures.
*
* @type {number}
* @constant
*/ const FloatType = 1015;
/**
* A half float data type for textures.
*
* @type {number}
* @constant
*/ const HalfFloatType = 1016;
/**
* An unsigned short 4_4_4_4 (packed) data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedShort4444Type = 1017;
/**
* An unsigned short 5_5_5_1 (packed) data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedShort5551Type = 1018;
/**
* An unsigned int 24_8 data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedInt248Type = 1020;
/**
* An unsigned int 5_9_9_9 (packed) data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedInt5999Type = 35902;
/**
* An unsigned int 10_11_11 (packed) data type for textures.
*
* @type {number}
* @constant
*/ const UnsignedInt101111Type = 35899;
/**
* Discards the red, green and blue components and reads just the alpha component.
*
* @type {number}
* @constant
*/ const AlphaFormat = 1021;
/**
* Discards the alpha component and reads the red, green and blue component.
*
* @type {number}
* @constant
*/ const RGBFormat = 1022;
/**
* Reads the red, green, blue and alpha components.
*
* @type {number}
* @constant
*/ const RGBAFormat = 1023;
/**
* Reads each element as a single depth value, converts it to floating point, and clamps to the range `[0,1]`.
*
* @type {number}
* @constant
*/ const DepthFormat = 1026;
/**
* Reads each element is a pair of depth and stencil values. The depth component of the pair is interpreted as
* in `DepthFormat`. The stencil component is interpreted based on the depth + stencil internal format.
*
* @type {number}
* @constant
*/ const DepthStencilFormat = 1027;
/**
* Discards the green, blue and alpha components and reads just the red component.
*
* @type {number}
* @constant
*/ const RedFormat = 1028;
/**
* Discards the green, blue and alpha components and reads just the red component. The texels are read as integers instead of floating point.
*
* @type {number}
* @constant
*/ const RedIntegerFormat = 1029;
/**
* Discards the alpha, and blue components and reads the red, and green components.
*
* @type {number}
* @constant
*/ const RGFormat = 1030;
/**
* Discards the alpha, and blue components and reads the red, and green components. The texels are read as integers instead of floating point.
*
* @type {number}
* @constant
*/ const RGIntegerFormat = 1031;
/**
* Reads the red, green, blue and alpha components. The texels are read as integers instead of floating point.
*
* @type {number}
* @constant
*/ const RGBAIntegerFormat = 1033;
/**
* A DXT1-compressed image in an RGB image format.
*
* @type {number}
* @constant
*/ const RGB_S3TC_DXT1_Format = 33776;
/**
* A DXT1-compressed image in an RGB image format with a simple on/off alpha value.
*
* @type {number}
* @constant
*/ const RGBA_S3TC_DXT1_Format = 33777;
/**
* A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression.
*
* @type {number}
* @constant
*/ const RGBA_S3TC_DXT3_Format = 33778;
/**
* A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3
* compression in how the alpha compression is done.
*
* @type {number}
* @constant
*/ const RGBA_S3TC_DXT5_Format = 33779;
/**
* PVRTC RGB compression in 4-bit mode. One block for each 4×4 pixels.
*
* @type {number}
* @constant
*/ const RGB_PVRTC_4BPPV1_Format = 35840;
/**
* PVRTC RGB compression in 2-bit mode. One block for each 8×4 pixels.
*
* @type {number}
* @constant
*/ const RGB_PVRTC_2BPPV1_Format = 35841;
/**
* PVRTC RGBA compression in 4-bit mode. One block for each 4×4 pixels.
*
* @type {number}
* @constant
*/ const RGBA_PVRTC_4BPPV1_Format = 35842;
/**
* PVRTC RGBA compression in 2-bit mode. One block for each 8×4 pixels.
*
* @type {number}
* @constant
*/ const RGBA_PVRTC_2BPPV1_Format = 35843;
/**
* ETC1 RGB format.
*
* @type {number}
* @constant
*/ const RGB_ETC1_Format = 36196;
/**
* ETC2 RGB format.
*
* @type {number}
* @constant
*/ const RGB_ETC2_Format = 37492;
/**
* ETC2 RGBA format.
*
* @type {number}
* @constant
*/ const RGBA_ETC2_EAC_Format = 37496;
/**
* EAC R11 UNORM format.
*
* @type {number}
* @constant
*/ const R11_EAC_Format = 37488; // 0x9270
/**
* EAC R11 SNORM format.
*
* @type {number}
* @constant
*/ const SIGNED_R11_EAC_Format = 37489; // 0x9271
/**
* EAC RG11 UNORM format.
*
* @type {number}
* @constant
*/ const RG11_EAC_Format = 37490; // 0x9272
/**
* EAC RG11 SNORM format.
*
* @type {number}
* @constant
*/ const SIGNED_RG11_EAC_Format = 37491; // 0x9273
/**
* ASTC RGBA 4x4 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_4x4_Format = 37808;
/**
* ASTC RGBA 5x4 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_5x4_Format = 37809;
/**
* ASTC RGBA 5x5 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_5x5_Format = 37810;
/**
* ASTC RGBA 6x5 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_6x5_Format = 37811;
/**
* ASTC RGBA 6x6 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_6x6_Format = 37812;
/**
* ASTC RGBA 8x5 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_8x5_Format = 37813;
/**
* ASTC RGBA 8x6 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_8x6_Format = 37814;
/**
* ASTC RGBA 8x8 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_8x8_Format = 37815;
/**
* ASTC RGBA 10x5 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_10x5_Format = 37816;
/**
* ASTC RGBA 10x6 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_10x6_Format = 37817;
/**
* ASTC RGBA 10x8 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_10x8_Format = 37818;
/**
* ASTC RGBA 10x10 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_10x10_Format = 37819;
/**
* ASTC RGBA 12x10 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_12x10_Format = 37820;
/**
* ASTC RGBA 12x12 format.
*
* @type {number}
* @constant
*/ const RGBA_ASTC_12x12_Format = 37821;
/**
* BPTC RGBA format.
*
* @type {number}
* @constant
*/ const RGBA_BPTC_Format = 36492;
/**
* BPTC Signed RGB format.
*
* @type {number}
* @constant
*/ const RGB_BPTC_SIGNED_Format = 36494;
/**
* BPTC Unsigned RGB format.
*
* @type {number}
* @constant
*/ const RGB_BPTC_UNSIGNED_Format = 36495;
/**
* RGTC1 Red format.
*
* @type {number}
* @constant
*/ const RED_RGTC1_Format = 36283;
/**
* RGTC1 Signed Red format.
*
* @type {number}
* @constant
*/ const SIGNED_RED_RGTC1_Format = 36284;
/**
* RGTC2 Red Green format.
*
* @type {number}
* @constant
*/ const RED_GREEN_RGTC2_Format = 36285;
/**
* RGTC2 Signed Red Green format.
*
* @type {number}
* @constant
*/ const SIGNED_RED_GREEN_RGTC2_Format = 36286;
/**
* Animations are played once.
*
* @type {number}
* @constant
*/ const LoopOnce = 2200;
/**
* Animations are played with a chosen number of repetitions, each time jumping from
* the end of the clip directly to its beginning.
*
* @type {number}
* @constant
*/ const LoopRepeat = 2201;
/**
* Animations are played with a chosen number of repetitions, alternately playing forward
* and backward.
*
* @type {number}
* @constant
*/ const LoopPingPong = 2202;
/**
* Discrete interpolation mode for keyframe tracks.
*
* @type {number}
* @constant
*/ const InterpolateDiscrete = 2300;
/**
* Linear interpolation mode for keyframe tracks.
*
* @type {number}
* @constant
*/ const InterpolateLinear = 2301;
/**
* Smooth interpolation mode for keyframe tracks.
*
* @type {number}
* @constant
*/ const InterpolateSmooth = 2302;
/**
* Zero curvature ending for animations.
*
* @type {number}
* @constant
*/ const ZeroCurvatureEnding = 2400;
/**
* Zero slope ending for animations.
*
* @type {number}
* @constant
*/ const ZeroSlopeEnding = 2401;
/**
* Wrap around ending for animations.
*
* @type {number}
* @constant
*/ const WrapAroundEnding = 2402;
/**
* Default animation blend mode.
*
* @type {number}
* @constant
*/ const NormalAnimationBlendMode = 2500;
/**
* Additive animation blend mode. Can be used to layer motions on top of
* each other to build complex performances from smaller re-usable assets.
*
* @type {number}
* @constant
*/ const AdditiveAnimationBlendMode = 2501;
/**
* For every three vertices draw a single triangle.
*
* @type {number}
* @constant
*/ const TrianglesDrawMode = 0;
/**
* For each vertex draw a triangle from the last three vertices.
*
* @type {number}
* @constant
*/ const TriangleStripDrawMode = 1;
/**
* For each vertex draw a triangle from the first vertex and the last two vertices.
*
* @type {number}
* @constant
*/ const TriangleFanDrawMode = 2;
/**
* The depth value is inverted (1.0 - z) for visualization purposes.
*
* @type {number}
* @constant
*/ const BasicDepthPacking = 3200;
/**
* Normal information is relative to the underlying surface.
*
* @type {number}
* @constant
*/ const TangentSpaceNormalMap = 0;
/**
* Normal information is relative to the object orientation.
*
* @type {number}
* @constant
*/ const ObjectSpaceNormalMap = 1;
// Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available.
/**
* No color space.
*
* @type {string}
* @constant
*/ const NoColorSpace = '';
/**
* sRGB color space.
*
* @type {string}
* @constant
*/ const SRGBColorSpace = 'srgb';
/**
* sRGB-linear color space.
*
* @type {string}
* @constant
*/ const LinearSRGBColorSpace = 'srgb-linear';
/**
* Linear transfer function.
*
* @type {string}
* @constant
*/ const LinearTransfer = 'linear';
/**
* sRGB transfer function.
*
* @type {string}
* @constant
*/ const SRGBTransfer = 'srgb';
/**
* Keeps the current value.
*
* @type {number}
* @constant
*/ const KeepStencilOp = 7680;
/**
* Will always return true.
*
* @type {number}
* @constant
*/ const AlwaysStencilFunc = 519;
/**
* Never pass.
*
* @type {number}
* @constant
*/ const NeverCompare = 512;
/**
* Pass if the incoming value is less than the texture value.
*
* @type {number}
* @constant
*/ const LessCompare = 513;
/**
* Pass if the incoming value equals the texture value.
*
* @type {number}
* @constant
*/ const EqualCompare = 514;
/**
* Pass if the incoming value is less than or equal to the texture value.
*
* @type {number}
* @constant
*/ const LessEqualCompare = 515;
/**
* Pass if the incoming value is greater than the texture value.
*
* @type {number}
* @constant
*/ const GreaterCompare = 516;
/**
* Pass if the incoming value is not equal to the texture value.
*
* @type {number}
* @constant
*/ const NotEqualCompare = 517;
/**
* Pass if the incoming value is greater than or equal to the texture value.
*
* @type {number}
* @constant
*/ const GreaterEqualCompare = 518;
/**
* Always pass.
*
* @type {number}
* @constant
*/ const AlwaysCompare = 519;
/**
* The contents are intended to be specified once by the application, and used many
* times as the source for drawing and image specification commands.
*
* @type {number}
* @constant
*/ const StaticDrawUsage = 35044;
/**
* GLSL 3 shader code.
*
* @type {string}
* @constant
*/ const GLSL3 = '300 es';
/**
* WebGL coordinate system.
*
* @type {number}
* @constant
*/ const WebGLCoordinateSystem = 2000;
/**
* WebGPU coordinate system.
*
* @type {number}
* @constant
*/ const WebGPUCoordinateSystem = 2001;
/**
* This type represents mouse buttons and interaction types in context of controls.
*
* @typedef {Object} ConstantsMouse
* @property {number} MIDDLE - The left mouse button.
* @property {number} LEFT - The middle mouse button.
* @property {number} RIGHT - The right mouse button.
* @property {number} ROTATE - A rotate interaction.
* @property {number} DOLLY - A dolly interaction.
* @property {number} PAN - A pan interaction.
**/ /**
* This type represents touch interaction types in context of controls.
*
* @typedef {Object} ConstantsTouch
* @property {number} ROTATE - A rotate interaction.
* @property {number} PAN - A pan interaction.
* @property {number} DOLLY_PAN - The dolly-pan interaction.
* @property {number} DOLLY_ROTATE - A dolly-rotate interaction.
**/ /**
* This type represents the different timestamp query types.
*
* @typedef {Object} ConstantsTimestampQuery
* @property {string} COMPUTE - A `compute` timestamp query.
* @property {string} RENDER - A `render` timestamp query.
**/ /**
* Represents the different interpolation sampling types.
*
* @typedef {Object} ConstantsInterpolationSamplingType
* @property {string} PERSPECTIVE - Perspective-correct interpolation.
* @property {string} LINEAR - Linear interpolation.
* @property {string} FLAT - Flat interpolation.
*/ /**
* Represents the different interpolation sampling modes.
*
* @typedef {Object} ConstantsInterpolationSamplingMode
* @property {string} NORMAL - Normal sampling mode.
* @property {string} CENTROID - Centroid sampling mode.
* @property {string} SAMPLE - Sample-specific sampling mode.
* @property {string} FIRST - Flat interpolation using the first vertex.
* @property {string} EITHER - Flat interpolation using either vertex.
*/ function arrayNeedsUint32(array) {
// assumes larger values usually on last
for(let i = array.length - 1; i >= 0; --i){
if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565
}
return false;
}
/**
* Returns `true` if the given object is a typed array.
*
* @param {any} array - The object to check.
* @return {boolean} Whether the given object is a typed array.
*/ function isTypedArray(array) {
return ArrayBuffer.isView(array) && !(array instanceof DataView);
}
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;
}
const _cache = {};
function log(...params) {
const message = 'THREE.' + params.shift();
{
console.log(message, ...params);
}
}
function warn(...params) {
const message = 'THREE.' + params.shift();
{
console.warn(message, ...params);
}
}
function error(...params) {
const message = 'THREE.' + params.shift();
{
console.error(message, ...params);
}
}
function warnOnce(...params) {
const message = params.join(' ');
if (message in _cache) return;
_cache[message] = true;
warn(...params);
}
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);
});
}
/**
* This modules allows to dispatch event objects on custom JavaScript objects.
*
* Main repository: [eventdispatcher.js](https://github.com/mrdoob/eventdispatcher.js/)
*
* Code Example:
* ```js
* class Car extends EventDispatcher {
* start() {
* this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } );
* }
*};
*
* // Using events with the custom object
* const car = new Car();
* car.addEventListener( 'start', function ( event ) {
* alert( event.message );
* } );
*
* car.start();
* ```
*/ class EventDispatcher {
/**
* 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 === undefined) this._listeners = {};
const listeners = this._listeners;
if (listeners[type] === undefined) {
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 === undefined) return false;
return listeners[type] !== undefined && 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 === undefined) return;
const listenerArray = listeners[type];
if (listenerArray !== undefined) {
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 === undefined) return;
const listenerArray = listeners[event.type];
if (listenerArray !== undefined) {
event.target = this;
// Make a copy, in case listeners are removed while iterating.
const array = listenerArray.slice(0);
for(let i = 0, l = array.length; i < l; i++){
array[i].call(this, event);
}
event.target = null;
}
}
}
const _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'
];
let _seed = 1234567;
const DEG2RAD = Math.PI / 180;
const RAD2DEG = 180 / Math.PI;
/**
* Generate a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier)
* (universally unique identifier).
*
* @return {string} The UUID.
*/ function generateUUID() {
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136
const d0 = Math.random() * 0xffffffff | 0;
const d1 = Math.random() * 0xffffffff | 0;
const d2 = Math.random() * 0xffffffff | 0;
const d3 = Math.random() * 0xffffffff | 0;
const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff];
// .toLowerCase() here flattens concatenated strings to save heap memory space.
return uuid.toLowerCase();
}
/**
* Clamps the given value between min and max.
*
* @param {number} value - The value to clamp.
* @param {number} min - The min value.
* @param {number} max - The max value.
* @return {number} The clamped value.
*/ function clamp$1(value, min, max) {
return Math.max(min, Math.min(max, value));
}
/**
* Computes the Euclidean modulo of the given parameters that
* is `( ( n % m ) + m ) % m`.
*
* @param {number} n - The first parameter.
* @param {number} m - The second parameter.
* @return {number} The Euclidean modulo.
*/ function euclideanModulo(n, m) {
// https://en.wikipedia.org/wiki/Modulo_operation
return (n % m + m) % m;
}
/**
* Performs a linear mapping from range `<a1, a2>` to range `<b1, b2>`
* for the given value.
*
* @param {number} x - The value to be mapped.
* @param {number} a1 - Minimum value for range A.
* @param {number} a2 - Maximum value for range A.
* @param {number} b1 - Minimum value for range B.
* @param {number} b2 - Maximum value for range B.
* @return {number} The mapped value.
*/ function mapLinear(x, a1, a2, b1, b2) {
return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
}
/**
* Returns the percentage in the closed interval `[0, 1]` of the given value
* between the start and end point.
*
* @param {number} x - The start point
* @param {number} y - The end point.
* @param {number} value - A value between start and end.
* @return {number} The interpolation factor.
*/ function inverseLerp(x, y, value) {
// https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/
if (x !== y) {
return (value - x) / (y - x);
} else {
return 0;
}
}
/**
* Returns a value linearly interpolated from two known points based on the given interval -
* `t = 0` will return `x` and `t = 1` will return `y`.
*
* @param {number} x - The start point
* @param {number} y - The end point.
* @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
* @return {number} The interpolated value.
*/ function lerp$1(x, y, t) {
return (1 - t) * x + t * y;
}
/**
* Smoothly interpolate a number from `x` to `y` in a spring-like manner using a delta
* time to maintain frame rate independent movement. For details, see
* [Frame rate independent damping using lerp](http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/).
*
* @param {number} x - The current point.
* @param {number} y - The target point.
* @param {number} lambda - A higher lambda value will make the movement more sudden,
* and a lower value will make the movement more gradual.
* @param {number} dt - Delta time in seconds.
* @return {number} The interpolated value.
*/ function damp(x, y, lambda, dt) {
return lerp$1(x, y, 1 - Math.exp(-lambda * dt));
}
/**
* Returns a value that alternates between `0` and the given `length` par