@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
1,363 lines (1,352 loc) • 1.96 MB
JavaScript
import { createLoaders as Fg, LODsManager as or, NEEDLE_progressive as He, getRaycastMesh as P0, calculateMeshLODLevel as hC, getLODColor as dC, addDracoAndKTX2Loaders as uC, configureLoader as fC, setKTX2TranscoderLocation as pC, setDracoDecoderLocation as mC } from "./gltf-progressive-CH7aqHHr.js";
import { Vector2 as Z, Vector3 as v, Vector4 as ye, Quaternion as U, Box3 as si, ShadowMaterial as k0, Euler as Ge, PlaneGeometry as An, WebGLRenderer as Wr, PerspectiveCamera as fe, OrthographicCamera as Vu, Scene as ji, Mesh as H, Texture as Se, Uniform$1 as tn, Color as se, ShaderMaterial as ts, MeshStandardMaterial as wt, Box3Helper as gC, GridHelper as O0, Object3D as M, Material as be, Matrix3 as E0, Matrix4 as J, Layers as Mo, PropertyBinding as Wa, AnimationClip as Vt, KeyframeTrack as yC, FileLoader as T0, BufferGeometry as En, TextureLoader as Ir, MeshBasicMaterial as Oe, DoubleSide as Bi, Group as Rs, CylinderGeometry as M0, SphereGeometry as zg, BoxGeometry as Va, SpriteMaterial as _C, Sprite as bC, Shape as vC, ExtrudeGeometry as wC, Ray as Fs, CubeUVReflectionMapping as sn, LinearSRGBColorSpace as zs, ShaderChunk as ii, Sphere as Hu, DataTexture as Ug, RGBAFormat as Gu, EquirectangularReflectionMapping as As, SRGBColorSpace as Us, Clock as xC, NeutralToneMapping as Ha, AgXToneMapping as qu, ACESFilmicToneMapping as Xu, NoToneMapping as ru, AxesHelper as Di, MathUtils as Is, Fog as R0, DirectionalLight as gm, PointLight as Ng, PCFSoftShadowMap$1 as SC, BasicNodeLibrary as CC, WebGLRenderTarget as is, DepthTexture as A0, NearestFilter as au, EdgesGeometry as PC, LineSegments as ym, LineBasicMaterial as lu, Line as $c, BufferAttribute as st, Raycaster as $g, ArrayCamera as kC, Plane as rl, SkinnedMesh as Co, InterleavedBufferAttribute as I0, Skeleton as OC, Bone as EC, WebGLCubeRenderTarget as TC, CubeCamera as MC, LoopRepeat as RC, LoopOnce as _m, AnimationMixer as Wg, InterpolateLinear as AC, InterpolateDiscrete as IC, InterpolateSmooth as LC, QuaternionKeyframeTrack as rc, BooleanKeyframeTrack as L_, VectorKeyframeTrack as ac, ColorKeyframeTrack as D_, NumberKeyframeTrack as tp, AudioContext as DC, CompressedTexture as jC, FrontSide as Ro, Camera as BC, Frustum as j_, AudioListener as FC, PositionalAudio as zC, AudioLoader as bm, Audio as UC, BackSide as Qu, PMREMGenerator$1 as NC, EquirectangularRefractionMapping as Vg, CubeTexture as Hg, CompressedCubeTexture as L0, MeshDepthMaterial as $C, CustomBlending as WC, MaxEquation as VC, AlwaysStencilFunc as HC, GreaterEqualStencilFunc as GC, NotEqualStencilFunc as qC, GreaterStencilFunc as XC, LessEqualStencilFunc as QC, EqualStencilFunc as YC, LessStencilFunc as KC, NeverStencilFunc as B_, InvertStencilOp as ZC, DecrementWrapStencilOp as JC, IncrementWrapStencilOp as e1, DecrementStencilOp as t1, IncrementStencilOp as i1, ReplaceStencilOp as n1, ZeroStencilOp as s1, KeepStencilOp as o1, AmbientLight as r1, HemisphereLight as a1, Loader as l1, GLSL3 as c1, AlwaysDepth as h1, GreaterEqualDepth as d1, GreaterDepth as u1, LessEqualDepth as f1, LessDepth as p1, NotEqualDepth as m1, EqualDepth as g1, RawShaderMaterial as D0, BatchedMesh as F_, LinearFilter as cu, UnsignedByteType as y1, MeshPhysicalMaterial as z_, RingGeometry as _1, Line3 as b1, AdditiveBlending as j0, BoxHelper as v1, SpotLight as w1, DirectionalLightHelper as x1, CameraHelper as S1, LOD as C1, Triangle as P1, NormalBlending as k1, ReinhardToneMapping as Gg, LinearToneMapping as qg, EventDispatcher as Xg, VideoTexture as O1, CatmullRomCurve3 as E1, MirroredRepeatWrapping as U_, ShaderLib as hu, UniformsUtils as B0, MeshNormalMaterial as T1, HalfFloatType as ip, Source as M1 } from "./three.js";
import { GroundedSkybox as Ga, Font as R1, TextGeometry as A1, FontLoader as I1, GLTFLoader as Ao, EXRLoader as Qg, RGBELoader as F0, Stats as L1, nodeFrame as N_, TransformControlsGizmo as $_, OrbitControls as D1, PositionalAudioHelper as j1, HorizontalBlurShader as B1, VerticalBlurShader as F1, GLTFExporter as z0, strToU8 as U0, zipSync as z1, XRControllerModelFactory as U1, XRHandMeshModel as N1, Line2 as $1, LineGeometry as W1, LineMaterial as V1, TransformControls as H1, InteractiveGroup as G1, HTMLMesh as q1, VertexNormalsHelper as X1, OBJLoader as Yg, FBXLoader as N0, mergeVertices as Q1 } from "./three-examples.js";
import { v5 as vm, ByteBuffer as Y1, fetchProfile as K1, MotionController as Z1, SIZE_PREFIX_LENGTH as $0, Builder as Kg, createNoise4D as J1, Matrix4 as np, BatchedParticleRenderer as eP, ParticleSystem as tP, RenderMode as bs, ConstantColor as iP, Vector4 as nP, ConstantValue as sP, TrailParticle as W_, WorkerBase as oP, MeshBVH as rP } from "./vendor-DkWSNjMV.js";
import { __webpack_exports__default as Pe, __webpack_exports__Text as W0, __webpack_exports__update as aP, __webpack_exports__Block as V0, SimpleStateBehavior as lP, __webpack_exports__Inline as sp, __webpack_exports__FontLibrary as V_, ThreeMeshUI as H_ } from "./three-mesh-ui-B-lqrZWj.js";
const G_ = typeof window < "u" ? window.location.search.includes("debugcontext") : !1;
var ue = /* @__PURE__ */ ((s) => (s.ContextRegistered = "ContextRegistered", s.ContextCreationStart = "ContextCreationStart", s.ContextCreated = "ContextCreated", s.ContextFirstFrameRendered = "ContextFirstFrameRendered", s.ContextDestroying = "ContextDestroying", s.ContextDestroyed = "ContextDestroyed", s.MissingCamera = "MissingCamera", s.ContextClearing = "ContextClearing", s.ContextCleared = "ContextCleared", s))(ue || {});
class de {
/** The currently active (rendering) Needle Engine context */
static get Current() {
return globalThis["NeedleEngine.Context.Current"];
}
/** @internal */
static set Current(e) {
globalThis["NeedleEngine.Context.Current"] = e;
}
/** Returns the array of all registered Needle Engine contexts. Do not modify */
static get All() {
return this.Registered;
}
/** All currently registered Needle Engine contexts. Do not modify */
static Registered = [];
/** @internal Internal use only */
static register(e) {
this.Registered.indexOf(e) === -1 && (G_ && console.warn("Registering context"), this.Registered.push(e), this.dispatchCallback("ContextRegistered", e));
}
/** @internal Internal use only */
static unregister(e) {
const t = this.Registered.indexOf(e);
t !== -1 && (G_ && console.warn("Unregistering context"), this.Registered.splice(t, 1));
}
static _callbacks = {};
/**
* Register a callback to be called when the given event occurs
*/
static registerCallback(e, t) {
return this._callbacks[e] || (this._callbacks[e] = []), this._callbacks[e].indexOf(t) !== -1 ? () => this.unregisterCallback(e, t) : (this._callbacks[e].push(t), () => this.unregisterCallback(e, t));
}
/** Unregister a callback */
static unregisterCallback(e, t) {
if (!this._callbacks[e]) return;
const i = this._callbacks[e].indexOf(t);
i !== -1 && this._callbacks[e].splice(i, 1);
}
/** @internal */
static dispatchCallback(e, t, i) {
if (!this._callbacks[e]) return !0;
const n = { event: e, context: t };
if (i)
for (const r in i)
n[r] = i[r];
const o = new Array();
return this._callbacks[e].forEach((r) => {
const a = r(n);
a instanceof Promise && o.push(a);
}), Promise.all(o);
}
/**
* Register a callback to be called when a context is created
*/
static addContextCreatedCallback(e) {
this.registerCallback("ContextCreated", e);
}
/**
* Register a callback to be called when a context is registered
*/
static addContextDestroyedCallback(e) {
this.registerCallback("ContextDestroyed", e);
}
}
const op = /* @__PURE__ */ new Map();
function on(s = globalThis.location?.hostname) {
if (op.has(s)) return op.get(s);
const e = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(s);
return op.set(s, e), e === !0;
}
function cP() {
return window.location.hostname.includes("glitch.me");
}
const hP = () => (s) => s;
function D3(s) {
return hP()(s);
}
function j3() {
return !!x("debug");
}
class rn {
_factory;
_cache = [];
_maxSize;
_index = 0;
constructor(e, t) {
this._factory = e, this._maxSize = t;
}
get() {
const e = this._index % this._maxSize;
return this._index++, this._cache.length <= e && (this._cache[e] = this._factory()), this._cache[e];
}
}
let _r = !1;
const wm = new Array();
typeof window < "u" && setTimeout(() => {
if (_r) {
const s = {}, e = new URL(window.location.href), t = new URL(e);
t.searchParams.append("console", "");
const i = t.toString().replace(/=$|=(?=&)/g, "");
for (const o of wm) {
const r = new URL(e);
r.searchParams.append(o, ""), s[o] = r.toString().replace(/=$|=(?=&)/g, "");
}
console.log(
`🌵 ?help: Debug Options for Needle Engine.
Append any of these parameters to the URL to enable specific debug options.
Example: ${i} will show an onscreen console window.`
);
const n = _r === !0 ? "" : ` (containing "${_r}")`;
console.group("Available URL parameters:" + n);
for (const o of Object.keys(s).sort())
typeof _r == "string" && !o.toLowerCase().includes(_r.toLowerCase()) || (console.groupCollapsed(o), console.log("Reload with this flag enabled:"), console.log(s[o]), console.groupEnd());
console.groupEnd();
}
}, 100);
function Yu() {
return new URLSearchParams(globalThis.location?.search);
}
function x(s) {
_r && !wm.includes(s) && wm.push(s);
const e = Yu();
if (e.has(s)) {
const t = e.get(s);
if (t) {
const i = Number(t);
return isNaN(i) ? t : i;
} else return !0;
}
return !1;
}
_r = x("help");
function B3(s, e) {
const t = Yu();
t.has(s) ? t.set(s, e) : t.append(s, e), document.location.search = t.toString();
}
function du(s, e, t = !0) {
const i = Yu();
i.has(s) ? e === null ? i.delete(s) : i.set(s, e) : e !== null && i.append(s, e), t ? dP(s, i) : H0(s, i);
}
function q_(s, e, t) {
s.has(e) ? s.set(e, t.toString()) : s.append(e, t.toString());
}
function dP(s, e, t) {
window.history.pushState(t, s, "?" + e.toString() + window.location.hash);
}
function H0(s, e, t) {
window.history.replaceState(t, s, "?" + e.toString() + window.location.hash);
}
function F3(s) {
for (var e = "", t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", i = t.length, n = 0; n < s; n++)
e += t.charAt(Math.floor(Math.random() * i));
return e;
}
function z3(s, e) {
return Math.floor(Math.random() * (e - s + 1)) + s;
}
const X_ = ["smol", "tiny", "giant", "interesting", "smart", "bright", "dull", "extreme", "beautiful", "pretty", "dark", "epic", "salty", "silly", "funny", "lame", "lazy", "loud", "lucky", "mad", "mean", "mighty", "mysterious", "nasty", "odd", "old", "powerful", "quiet", "rapid", "scary", "shiny", "shy", "silly", "smooth", "sour", "spicy", "stupid", "sweet", "tasty", "terrible", "ugly", "unusual", "vast", "wet", "wild", "witty", "wrong", "zany", "zealous", "zippy", "zombie", "zorro"], Q_ = ["cat", "dog", "mouse", "pig", "cow", "horse", "sheep", "chicken", "duck", "goat", "panda", "tiger", "lion", "elephant", "monkey", "bird", "fish", "snake", "frog", "turtle", "hamster", "penguin", "kangaroo", "whale", "dolphin", "crocodile", "snail", "ant", "bee", "beetle", "butterfly", "dragon", "eagle", "fish", "giraffe", "lizard", "panda", "penguin", "rabbit", "snake", "spider", "tiger", "zebra"];
function uP() {
const s = X_[Math.floor(Math.random() * X_.length)], e = Q_[Math.floor(Math.random() * Q_.length)];
return s + "_" + e;
}
function fP(s) {
return s = s.replace(/[^a-z0-9áéÃóúñü \.,_-]/gim, ""), s.trim();
}
function uu(s, e, t = !0, i = !1) {
if (e == null) return null;
if (e.userData && e.userData.guid === s) return e;
if (e.guid == s) return e;
if (i && e.userData?.components) {
for (const n of e.userData.components)
if (n.guid === s) return n;
}
if (t) {
if (e.scenes)
for (const n in e.scenes) {
const o = e.scenes[n], r = uu(s, o, t, i);
if (r) return r;
}
if (e.children)
for (const n in e.children) {
const o = e.children[n], r = uu(s, o, t, i);
if (r) return r;
}
}
}
function pP(s) {
return !!(typeof EventTarget < "u" && s instanceof EventTarget || s instanceof Date || s instanceof RegExp || s instanceof Map || s instanceof Set || s instanceof WeakMap || s instanceof WeakSet || s instanceof Promise || typeof ArrayBuffer < "u" && s instanceof ArrayBuffer || ArrayBuffer.isView(s));
}
function Ku(s, e, t) {
if (s != null && typeof s == "object") {
if (t || (t = /* @__PURE__ */ new WeakSet()), t.has(s) || (t.add(s), pP(s))) return s;
let i;
if (Array.isArray(s)) i = [];
else {
i = Object.create(Object.getPrototypeOf(s));
const n = Object.getOwnPropertyDescriptors(s);
for (const o in n) {
const r = n[o];
if (r.set || r.writable !== !1)
try {
i[o] = s[o];
} catch {
}
}
}
for (const n of Object.keys(s)) {
const o = s[n];
e && !e(s, n, o) ? i[n] = o : o?.clone !== void 0 && typeof o.clone == "function" ? i[n] = o.clone() : i[n] = Ku(o, e, t);
}
return i;
}
return s;
}
function Io(s) {
return new Promise((e, t) => {
setTimeout(e, s);
});
}
function Zg(s, e) {
if (s <= 0) return Promise.resolve();
if (e || (e = de.Current), !e) return Promise.reject("No context");
const t = e.time.frameCount + s;
return new Promise((i, n) => {
if (!e) return n("No context");
const o = () => {
e.time.frameCount >= t && (e.pre_update_callbacks.splice(e.pre_update_callbacks.indexOf(o), 1), i());
};
e.pre_update_callbacks.push(o);
});
}
const Hh = x("debugresolveurl"), mP = "rel:";
function U3(s, e) {
return Ws(s, e);
}
function Ws(s, e) {
if (e === void 0)
return Hh && console.warn("getPath: uri is undefined, returning uri", e), e;
if (e.startsWith("./"))
return e;
if (e.startsWith("http"))
return Hh && console.warn("getPath: uri is absolute, returning uri", e), e;
if (s === void 0)
return Hh && console.warn("getPath: source is undefined, returning uri", e), e;
e.startsWith(mP) && (e = e.substring(4));
const t = s.lastIndexOf("/");
if (t >= 0) {
const i = s.substring(0, t + 1);
for (; i.endsWith("/") && e.startsWith("/"); ) e = e.substring(1);
const n = i + e;
return Hh && console.log("source:", s, `changed uri
from`, e, `
to `, n, `
basePath: ` + i), n;
}
return e;
}
function gP(s) {
if (s)
return s = s.trim(), s = s.split("?")[0]?.split("#")[0], s;
}
class yP {
subscribeWrite(e) {
this.writeCallbacks.push(e);
}
unsubscribeWrite(e) {
const t = this.writeCallbacks.indexOf(e);
t !== -1 && this.writeCallbacks.splice(t, 1);
}
writeCallbacks = [];
constructor(e, t) {
this._object = e, this._prop = t, this._wrapperProp = /* @__PURE__ */ Symbol("$" + t), this.apply();
}
_applied = !1;
_object;
_prop;
_wrapperProp;
apply() {
if (this._applied || !this._object) return;
const e = this._object, t = this._prop;
if (e[t] === void 0) return;
this._applied = !0, e[this._wrapperProp] !== void 0 && console.warn("Watcher is being applied to an object that already has a wrapper property. This is not (yet) supported");
const i = e[t];
e[this._wrapperProp] = i, Object.defineProperty(e, t, {
get: () => e[this._wrapperProp],
set: (r) => {
e[this._wrapperProp] = r;
for (const a of this.writeCallbacks)
a(r, this._prop);
}
});
}
revoke() {
if (!this._applied || !this._object) return;
this._applied = !1;
const e = this._object, t = this._prop;
Reflect.deleteProperty(e, t);
const i = e[this._wrapperProp];
e[t] = i, Reflect.deleteProperty(e, this._wrapperProp);
}
dispose() {
this.revoke(), this.writeCallbacks.length = 0, this._object = null;
}
}
class Po {
_watches = [];
constructor(e, t) {
if (Array.isArray(t))
for (const i of t)
this._watches.push(new Po(e, i));
else
this._watches.push(new yP(e, t));
}
subscribeWrite(e) {
for (const t of this._watches)
t.subscribeWrite(e);
}
unsubscribeWrite(e) {
for (const t of this._watches)
t.unsubscribeWrite(e);
}
apply() {
for (const e of this._watches)
e.apply();
}
revoke() {
for (const e of this._watches)
e.revoke();
}
dispose() {
for (const e of this._watches)
e.dispose();
this._watches.length = 0;
}
}
const fa = /* @__PURE__ */ Symbol("needle:watches");
function Jg(s, e) {
if (!s[fa])
if (s instanceof Z)
s[fa] = new Po(s, ["x", "y"]);
else if (s instanceof v)
s[fa] = new Po(s, ["x", "y", "z"]);
else if (s instanceof ye || s instanceof U)
s[fa] = new Po(s, ["x", "y", "z", "w"]);
else
return !1;
return s[fa].subscribeWrite(e), !0;
}
function G0(s, e) {
if (!s) return;
const t = s[fa];
t && t.unsubscribeWrite(e);
}
var D;
((s) => {
let e;
function t() {
if (e !== void 0) return e;
if (typeof window > "u") return e = !1;
const ee = window.navigator.userAgent, Te = /Windows|MacOS|Mac OS/.test(ee), fi = /Windows NT/.test(ee) && /Edg/.test(ee) && !/Win64/.test(ee);
return e = Te && !fi && !O();
}
s.isDesktop = t;
let i;
function n() {
return i !== void 0 ? i : typeof window.orientation < "u" || navigator.userAgent.indexOf("IEMobile") !== -1 ? i = !0 : i = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent);
}
s.isMobileDevice = n;
function o() {
return a();
}
s.isIPad = o;
let r;
function a() {
if (r !== void 0) return r;
const ee = navigator.userAgent.toLowerCase();
return r = /iPad/.test(navigator.userAgent) || ee.includes("macintosh") && "ontouchend" in document;
}
s.isiPad = a;
let l;
function c() {
return l !== void 0 ? l : l = /Android/.test(navigator.userAgent);
}
s.isAndroidDevice = c;
let h;
function d() {
return h !== void 0 ? h : h = /WebXRViewer\//i.test(navigator.userAgent);
}
s.isMozillaXR = d;
let u;
function p() {
return u !== void 0 ? u : u = /NeedleAppClip\//i.test(navigator.userAgent);
}
s.isNeedleAppClip = p;
let m;
function _() {
if (m !== void 0) return m;
if (O() || a()) return m = !1;
const ee = navigator.userAgent.toLowerCase();
return navigator.userAgentData ? m = navigator.userAgentData.platform === "macOS" : m = ee.includes("mac os x") || ee.includes("macintosh");
}
s.isMacOS = _;
let g;
function y() {
return g !== void 0 ? g : g = a() && "xr" in navigator && Q();
}
s.isVisionOS = y;
let b;
const w = ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"];
function O() {
return b !== void 0 ? b : b = w.includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
}
s.isiOS = O;
let P;
function E() {
return P !== void 0 || (P = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)), P;
}
s.isSafari = E;
let L;
function j() {
return L !== void 0 ? L : L = navigator.userAgent.includes("OculusBrowser");
}
s.isQuest = j;
let N;
function Q() {
return N !== void 0 || (N = document.createElement("a").relList.supports("ar")), N;
}
s.supportsQuickLookAR = Q;
async function q() {
try {
return (await navigator.permissions.query({ name: "microphone" })).state !== "denied";
} catch (ee) {
return console.error("Error querying `microphone` permissions.", ee), !1;
}
}
s.microphonePermissionsGranted = q;
let T;
function V() {
if (T !== void 0) return T;
const ee = navigator.userAgent.match(/iPhone OS (\d+_\d+)/);
if (ee && (T = ee[1].replace("_", ".")), !T) {
const Te = navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/);
Te && (T = Te[1]);
}
return T || (T = null), T;
}
s.getiOSVersion = V;
let G;
function oe() {
if (G !== void 0) return G;
const ee = navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/);
return ee ? G = ee[1].replace("_", ".") : G = null, G;
}
s.getChromeVersion = oe;
let re;
function pe() {
if (re !== void 0) return re;
const ee = navigator.userAgent.match(/Version\/(\d+\.\d+)/);
return ee && E() ? re = ee[1] : re = null, re;
}
s.getSafariVersion = pe;
})(D || (D = {}));
function N3() {
return D.isDesktop();
}
function $3() {
return D.isMobileDevice();
}
function W3() {
return D.isiPad();
}
function V3() {
return D.isiPad();
}
function H3() {
return D.isAndroidDevice();
}
function G3() {
return D.isMozillaXR();
}
function q3() {
return D.isMacOS();
}
function X3() {
return D.isiOS();
}
function Q3() {
return D.isSafari();
}
function Y3() {
return D.isQuest();
}
async function K3() {
return D.microphonePermissionsGranted();
}
const bo = /* @__PURE__ */ new WeakMap();
function xm(s, e, t) {
if (!bo.get(s)) {
const o = new MutationObserver((r) => {
bP(s, r);
});
bo.set(s, {
observer: o,
attributeChangedListeners: /* @__PURE__ */ new Map()
}), o.observe(s, { attributes: !0 });
}
const i = bo.get(s).attributeChangedListeners;
i.has(e) || i.set(e, []);
const n = i.get(e);
return n.includes(t) || n.push(t), () => {
_P(s, e, t);
};
}
function _P(s, e, t) {
if (!bo.get(s)) return;
const i = bo.get(s).attributeChangedListeners;
if (!i.has(e)) return;
const n = i.get(e), o = n.indexOf(t);
o !== -1 && (n.splice(o, 1), n.length <= 0 && (i.delete(e), bo.get(s)?.observer.disconnect(), bo.delete(s)));
}
function bP(s, e) {
const t = bo.get(s).attributeChangedListeners;
for (const i of e)
if (i.type === "attributes") {
const n = i.attributeName, o = s.getAttribute(n);
if (t.has(n))
for (const r of t.get(n))
r(o);
}
}
class Y_ {
reason;
constructor(e) {
this.reason = e;
}
}
async function q0(s) {
const e = await Promise.allSettled(s).catch((n) => [
new Y_(n.message)
]);
let t = !1;
const i = e.map((n) => "value" in n ? n.value : (t = !0, new Y_(n.reason)));
return {
anyFailed: t,
results: i
};
}
const vP = x("debugdebug");
let ey = !1;
(x("noerrors") || x("nooverlaymessages")) && (ey = !0);
const rp = "needle_engine_global_error_container";
var nn = /* @__PURE__ */ ((s) => (s[s.Log = 0] = "Log", s[s.Warn = 1] = "Warn", s[s.Error = 2] = "Error", s))(nn || {});
function X0() {
return Y0;
}
const Sm = new Array();
function wP(s) {
Sm.push(s);
}
let ap = !1;
function xP(...s) {
if (!ap) {
ap = !0;
try {
for (let e = 0; e < Sm.length; e++)
Sm[e](...s);
} catch (e) {
console.error(e);
}
ap = !1;
}
}
const Q0 = console.error, SP = function(...s) {
Q0.apply(console, s), kP(s), wr(2, s, {}), PP(...s);
};
function CP(s) {
ey = !s, s ? console.error = SP : console.error = Q0;
}
function Z3(s) {
return CP(s);
}
let Y0 = 0;
function PP(...s) {
Y0 += 1, xP(...s);
}
function kP(s) {
if (Array.isArray(s))
for (let e = 0; e < s.length; e++) {
const t = s[e];
typeof t == "string" && t.startsWith("THREE.PropertyBinding: Trying to update node for track:") && (s[e] = "Some animated objects couldn't be found: see console for details");
}
}
const K_ = /* @__PURE__ */ new Set();
function wr(s, e, t = {}, i, n) {
if (ey) return;
if (t.once === !0) {
let a = "";
if (Array.isArray(e))
for (let l = 0; l < e.length; l++) {
let c = e[l];
c instanceof Error && (c = c.message), typeof c != "object" && (l > 0 && (a += " "), a += c);
}
else typeof e == "string" && (a = e);
if (K_.has(a)) return;
K_.add(a);
}
const o = de.Current;
let r = o?.domElement ?? document.querySelector("needle-engine");
if (o?.isInAR && (r = o.arOverlayElement), !!r) {
if (Array.isArray(e)) {
let a = "";
for (let l = 0; l < e.length; l++) {
let c = e[l];
c instanceof Error && (c = c.message), typeof c != "object" && (l > 0 && (a += " "), a += c);
}
e = a;
}
!e || e.length <= 0 || OP(s, r, e, t);
}
}
const Sa = /* @__PURE__ */ new Map(), Z_ = 0.2;
function OP(s, e, t, i = {}) {
if (t == null) return;
const n = TP(e);
if (n.childElementCount >= 20) {
const c = n.lastElementChild;
J_(c);
}
t.length > 400 && (t = t.substring(0, 400) + "...");
const o = i.key ?? t;
if (Sa.has(o)) {
Sa.get(o)?.update(t, i);
return;
}
const r = MP(s, t);
n.prepend(r);
const a = () => {
Sa.delete(o), J_(r);
};
let l = setTimeout(a, Math.max(Z_, i.duration ?? 10) * 1e3);
Sa.set(o, {
update: (c, h) => {
c.length > 400 && (c = c.substring(0, 400) + "..."), r.innerHTML = c, h.duration && (clearTimeout(l), l = setTimeout(a, Math.max(Z_, h.duration) * 1e3));
},
removeFunction: a
});
}
function J3() {
vP && console.log("Clearing messages");
for (const s of Sa.values())
s?.removeFunction.call(s);
Sa.clear();
}
const EP = `
@import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap');
div[data-needle_engine_debug_overlay] {
font-family: 'Roboto Flex', sans-serif;
font-weight: 400;
font-size: 16px;
}
div[data-needle_engine_debug_overlay] strong {
font-weight: 700;
}
div[data-needle_engine_debug_overlay] a {
color: white;
text-decoration: none;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
div[data-needle_engine_debug_overlay] a:hover {
text-decoration: none;
border: none;
}
div[data-needle_engine_debug_overlay] .log strong {
color: rgba(200,200,200,.9);
}
div[data-needle_engine_debug_overlay] .warn strong {
color: rgba(255,255,230, 1);
}
div[data-needle_engine_debug_overlay] .error strong {
color: rgba(255,100,120, 1);
}
`;
function TP(s) {
globalThis[rp] || (globalThis[rp] = /* @__PURE__ */ new Map());
const e = globalThis[rp];
if (e.has(s))
return e.get(s);
{
const t = document.createElement("div");
e.set(s, t), t.setAttribute("data-needle_engine_debug_overlay", ""), t.classList.add("debug-container"), t.style.cssText = `
position: absolute;
top: 0;
right: 5px;
padding-top: env(safe-area-inset-top, 0px);
max-width: 70%;
max-height: calc(100% - 105px);
z-index: 100000;
pointer-events: scroll;
display: flex;
align-items: end;
flex-direction: column;
color: white;
overflow: auto;
word-break: break-word;
`, D.isNeedleAppClip() && (t.style.left = "5px", t.style.right = "unset");
const i = document.querySelector('meta[name="viewport"]');
i && !i.getAttribute("content")?.includes("viewport-fit=") && i.setAttribute("content", i.getAttribute("content") + ",viewport-fit=cover"), s.shadowRoot ? s.shadowRoot.appendChild(t) : s.appendChild(t);
const n = document.createElement("style");
return n.innerHTML = EP, t.appendChild(n), t;
}
}
const K0 = /* @__PURE__ */ Symbol("logtype"), fu = /* @__PURE__ */ new Map();
function J_(s) {
s.remove();
const e = s[K0], t = fu.get(e) ?? [];
t.push(s), fu.set(e, t);
}
function MP(s, e) {
if (fu.has(s)) {
const i = fu.get(s);
if (i.length > 0) {
const n = i.pop();
return n.innerHTML = e, n;
}
}
const t = document.createElement("div");
switch (t.setAttribute("data-id", "__needle_engine_debug_overlay"), t.style.marginRight = "5px", t.style.padding = ".5em", t.style.backgroundColor = "rgba(0,0,0,.9)", t.style.marginTop = "5px", t.style.marginBottom = "3px", t.style.borderRadius = "8px", t.style.pointerEvents = "all", t.style.userSelect = "text", t.style.maxWidth = "250px", t.style.whiteSpace = "pre-wrap", t.style["backdrop-filter"] = "blur(10px)", t.style["-webkit-backdrop-filter"] = "blur(10px)", t.style.backgroundColor = "rgba(20,20,20,.8)", t.style.boxShadow = "inset 0 0 80px rgba(0,0,0,.2), 0 0 5px rgba(0,0,0,.2)", t.style.border = "1px solid rgba(160,160,160,.2)", t[K0] = s, s) {
case 0:
t.classList.add("log"), t.style.color = "rgba(200,200,200,.7)", t.style.backgroundColor = "rgba(40,40,40,.7)";
break;
case 1:
t.classList.add("warn"), t.style.color = "rgb(255, 255, 150)", t.style.backgroundColor = "rgba(50,50,20,.8)";
break;
case 2:
t.classList.add("error"), t.style.color = "rgb(255, 50, 50", t.style.backgroundColor = "rgba(50,20,20,.8)";
break;
}
return t.title = "Open the browser console (F12) for more information", t.innerHTML = e, t;
}
const RP = x("nodevlogs");
let Cm, lp;
function R() {
if (RP) return !1;
if (Cm !== void 0) return Cm;
if (lp !== void 0) return lp;
let s = on();
return s || (s = typeof window < "u" && window.location.hostname.endsWith(".local-credentialless.webcontainer.io")), lp = s, s;
}
function ej(s) {
Cm = s;
}
class AP {
random(e, t) {
return Array.isArray(e) ? e.length <= 0 ? null : e[Math.floor(Math.random() * e.length)] : e !== void 0 && t !== void 0 ? Math.random() * (t - e) + e : Math.random();
}
/**
* Fills a Vector3 with random values.
* @param target Vector3 to fill with random values
* @param min Minimum value for each component
* @param max Maximum value for each component
*/
randomVector3(e, t = 0, i = 1) {
e.x = this.random(t, i), e.y = this.random(t, i), e.z = this.random(t, i);
}
/**
* Clamps a value between min and max.
* @param value Value to clamp
* @param min Minimum bound
* @param max Maximum bound
* @returns Clamped value
*/
clamp(e, t, i) {
return e < t ? t : e > i ? i : e;
}
/**
* Clamps a value between 0 and 1.
* @param value Value to clamp
* @returns Value clamped to [0, 1]
*/
clamp01(e) {
return this.clamp(e, 0, 1);
}
/**
* Linearly interpolates between two values.
* @param value1 Start value (returned when t=0)
* @param value2 End value (returned when t=1)
* @param t Interpolation factor, clamped to [0, 1]
* @returns Interpolated value
*/
lerp(e, t, i) {
return i = i < 0 ? 0 : i, i = i > 1 ? 1 : i, e + (t - e) * i;
}
/**
* Calculates the linear interpolation parameter that produces the given value.
* Inverse of lerp: if `lerp(a, b, t) = v`, then `inverseLerp(a, b, v) = t`
* @param value1 Start value
* @param value2 End value
* @param t The value to find the parameter for
* @returns The interpolation parameter (may be outside [0,1] if t is outside [value1, value2])
*/
inverseLerp(e, t, i) {
return (i - e) / (t - e);
}
/**
* Remaps a value from one range to another.
* @param value The value to remap.
* @param min1 The minimum value of the current range.
* @param max1 The maximum value of the current range.
* @param min2 The minimum value of the target range.
* @param max2 The maximum value of the target range.
*/
remap(e, t, i, n, o) {
return n + (o - n) * (e - t) / (i - t);
}
/**
* Moves a value towards a target by a maximum step amount.
* Useful for smooth following or gradual value changes.
* @param value1 Current value
* @param value2 Target value
* @param amount Maximum step to move (positive moves toward target)
* @returns New value moved toward target, never overshooting
*/
moveTowards(e, t, i) {
return e += i, (i < 0 && e < t || i > 0 && e > t) && (e = t), e;
}
Rad2Deg = 180 / Math.PI;
Deg2Rad = Math.PI / 180;
Epsilon = 1e-5;
/**
* Converts radians to degrees
*/
toDegrees(e) {
return e * 180 / Math.PI;
}
/**
* Converts degrees to radians
*/
toRadians(e) {
return e * Math.PI / 180;
}
tan(e) {
return Math.tan(e);
}
gammaToLinear(e) {
return Math.pow(e, 2.2);
}
linearToGamma(e) {
return Math.pow(e, 1 / 2.2);
}
/**
* Checks if two vectors are approximately equal within epsilon tolerance.
* Works with Vector2, Vector3, Vector4, and Quaternion.
* @param v1 First vector
* @param v2 Second vector
* @param epsilon Tolerance for comparison (default: Number.EPSILON)
* @returns True if all components are within epsilon of each other
*/
approximately(e, t, i = Number.EPSILON) {
for (const n of IP) {
const o = e[n], r = t[n];
if (o === void 0 || r === void 0) break;
if (Math.abs(o - r) > i)
return !1;
}
return !0;
}
/**
* Easing function: slow start, fast middle, slow end (cubic).
* @param x Input value from 0 to 1
* @returns Eased value from 0 to 1
*/
easeInOutCubic(e) {
return e < 0.5 ? 4 * e * e * e : 1 - Math.pow(-2 * e + 2, 3) / 2;
}
}
const IP = ["x", "y", "z", "w"], B = new AP();
class eb {
y;
s;
alpha = 0;
constructor(e) {
this.setAlpha(e), this.y = null, this.s = null;
}
setAlpha(e) {
if (e <= 0 || e > 1)
throw new Error();
this.alpha = e;
}
filter(e, t) {
t && this.setAlpha(t);
let i;
return this.y ? i = this.alpha * e + (1 - this.alpha) * this.s : i = e, this.y = e, this.s = i, i;
}
lastValue() {
return this.y;
}
reset(e) {
this.y = e, this.s = e;
}
}
class cp {
/**
* An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available.
*/
freq;
/**
* Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter.
*/
minCutOff;
/**
* Parameter to reduce latency (> 0). Higher values make the filter react faster to changes.
*/
beta;
/**
* Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing.
*/
dCutOff;
/**
* The low-pass filter for the signal.
*/
x;
/**
* The low-pass filter for the derivates.
*/
dx;
/**
* The last time the filter was called.
*/
lasttime;
/** Create a new OneEuroFilter
* @param freq - An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available.
* @param minCutOff - Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter.
* @param beta - Parameter to reduce latency (> 0). Higher values make the filter react faster to changes.
* @param dCutOff - Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing.
*/
constructor(e, t = 1, i = 0, n = 1) {
if (e <= 0 || t <= 0 || n <= 0)
throw new Error();
this.freq = e, this.minCutOff = t, this.beta = i, this.dCutOff = n, this.x = new eb(this.alpha(this.minCutOff)), this.dx = new eb(this.alpha(this.dCutOff)), this.lasttime = null;
}
alpha(e) {
const t = 1 / this.freq;
return 1 / (1 + 1 / (2 * Math.PI * e) / t);
}
/** Filter your value: call with your value and the current timestamp (e.g. from this.context.time.time) */
filter(e, t = null) {
this.lasttime && t && (this.freq = 1 / (t - this.lasttime)), this.lasttime = t;
const i = this.x.lastValue(), n = i ? (e - i) * this.freq : 0, o = this.dx.filter(n, this.alpha(this.dCutOff)), r = this.minCutOff + this.beta * Math.abs(o);
return this.x.filter(e, this.alpha(r));
}
reset(e) {
e != null && this.x.reset(e), this.x.alpha = this.alpha(this.minCutOff), this.dx.alpha = this.alpha(this.dCutOff), this.lasttime = null;
}
}
class Z0 {
x;
y;
z;
/** Create a new OneEuroFilter
* @param freq - An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available.
* @param minCutOff - Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter.
* @param beta - Parameter to reduce latency (> 0). Higher values make the filter react faster to changes.
* @param dCutOff - Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing.
*/
constructor(e, t = 1, i = 0, n = 1) {
this.x = new cp(e, t, i, n), this.y = new cp(e, t, i, n), this.z = new cp(e, t, i, n);
}
filter(e, t, i = null) {
t.x = this.x.filter(e.x, i), t.y = this.y.filter(e.y, i), t.z = this.z.filter(e.z, i);
}
reset(e) {
this.x.reset(e?.x), this.y.reset(e?.y), this.z.reset(e?.z);
}
}
const jd = "needle:cameraController";
function LP(s) {
return s[jd];
}
function tb(s, e, t) {
t ? s[jd] = e : s[jd] === e && (s[jd] = null);
}
const Pm = "needle:autofit";
function DP(s) {
return s[Pm] === void 0 ? !0 : s[Pm] !== !1;
}
function km(s, e) {
s[Pm] = e;
}
let yn;
const jP = { x: 0, y: 0, width: 0, height: 0 }, BP = x("debugfocusrect");
function FP(s, e, t, i, n) {
s instanceof Element && (BP && s instanceof HTMLElement && (s.style.outline = "2px dashed rgba(255, 150, 0, .8)"), s = s.getBoundingClientRect()), yn = n.domElement.getBoundingClientRect();
const o = jP;
o.x = s.x, o.y = s.y, o.width = s.width, o.height = s.height, o.x -= yn.x, o.y -= yn.y;
const r = yn.width, a = yn.height, l = i.view, c = e.zoom;
let h = l?.offsetX || 0, d = l?.offsetY || 0, u = yn.width, p = yn.height;
u /= c, p /= c, h = u * (c - 1) * 0.5, d = p * (c - 1) * 0.5;
const m = o.x + o.width * 0.5, _ = o.y + o.height * 0.5, g = yn.width * 0.5, y = yn.height * 0.5, b = m - g, w = _ - y;
h -= b / c, d -= w / c, e.offsetX !== void 0 && (h += e.offsetX * (yn.width * 0.5)), e.offsetY !== void 0 && (d -= e.offsetY * (yn.height * 0.5));
const O = l?.offsetX || h, P = l?.offsetY || d;
h = B.lerp(O, h, t), d = B.lerp(P, d, t);
const E = l?.width || r, L = l?.height || a;
u = B.lerp(E, u, t), p = B.lerp(L, p, t), i.setViewOffset(r, a, h, d, u, p), i.updateProjectionMatrix(), e.damping > 0 && (e.damping *= 1 - t, e.damping < 0.01 && (e.damping = 0), e.damping = Math.max(0, e.damping));
}
function zP(s, e, t) {
const i = s.length(), n = e.length(), o = B.lerp(i, n, t);
return s.lerp(e, t).normalize().multiplyScalar(o);
}
const hp = new U(), J0 = new U().setFromAxisAngle(new v(0, 1, 0), Math.PI);
function tj(s, e) {
s.lookAt(e), s.quaternion.multiply(J0);
}
function Zu(s, e, t = !0, i = !1) {
if (s === e) return;
hp.copy(s.quaternion);
const n = ae(e), o = ae(s);
if (i) {
if (ns(s, xe(e)), t) {
const r = o.y, a = o.sub(XP(s));
a.y = r, s.lookAt(a), s.quaternion.multiply(J0);
}
Number.isNaN(s.quaternion.x) && s.quaternion.copy(hp);
return;
}
t && (n.y = o.y), s.lookAt(n), Number.isNaN(s.quaternion.x) && s.quaternion.copy(hp);
}
function ij(s, e, t, i = 1) {
if (t) {
const n = F(0, 0, 0), o = e.x / window.innerWidth * 2 - 1, r = -(e.y / window.innerHeight) * 2 + 1;
n.set(
o,
r,
0
), n.unproject(t);
const a = t.worldPosition, l = s.worldPosition.distanceTo(a), c = n.sub(a);
c.multiplyScalar(i * 3.6 * l);
const h = t.worldPosition.add(c);
return s.lookAt(h), h;
}
return null;
}
const UP = new rn(() => new v(), 100);
function F(s, e, t) {
const i = UP.get();
return i.set(0, 0, 0), s instanceof v ? i.copy(s) : Array.isArray(s) ? i.set(s[0], s[1], s[2]) : s instanceof DOMPointReadOnly ? i.set(s.x, s.y, s.z) : typeof s == "number" ? (i.x = s, i.y = e !== void 0 ? e : i.x, i.z = t !== void 0 ? t : i.x) : typeof s == "object" && (i.x = s.x, i.y = s.y, i.z = s.z), i;
}
const NP = new rn(() => new se(), 30);
function $P(s) {
const e = NP.get();
return s ? e.copy(s) : e.set(0, 0, 0), e;
}
const WP = new rn(() => new U(), 100);
function ki(s, e, t, i) {
const n = WP.get();
return n.identity(), s instanceof U ? n.copy(s) : s instanceof DOMPointReadOnly ? n.set(s.x, s.y, s.z, s.w) : typeof s == "number" && e !== void 0 && t !== void 0 && i !== void 0 ? n.set(s, e, t, i) : typeof s == "object" && "x" in s && "y" in s && "z" in s && "w" in s && n.set(s.x, s.y, s.z, s.w), n;
}
const ty = new rn(() => new v(), 100), ib = /* @__PURE__ */ Symbol("lastMatrixWorldUpdateKey");
function ae(s, e = null, t = !0) {
const i = e ?? ty.get();
return s ? s.parent ? (t && s.updateWorldMatrix(!0, !1), s.matrixWorldNeedsUpdate && s[ib] !== Date.now() && (s[ib] = Date.now(), s.updateMatrixWorld()), i.setFromMatrixPosition(s.matrixWorld), i) : i.copy(s.position) : i.set(0, 0, 0);
}
function an(s, e) {
if (!s) return s;
const t = ty.get();
return e !== t && t.copy(e), s.parent !== null && s.parent.worldToLocal(t), s.position.set(t.x, t.y, t.z), s;
}
function qa(s, e, t, i) {
const n = ty.get();
return n.set(e, t, i), an(s, n), s;
}
const pu = new rn(() => new U(), 100), Pr = new U(), dp = new U();
function xe(s, e = null) {
if (!s) return pu.get().identity();
const t = e ?? pu.get();
return s.parent ? (s.getWorldQuaternion(t), t) : t.copy(s.quaternion);
}
function ns(s, e) {
if (!s) return;
e !== Pr && Pr.copy(e);
const t = Pr;
s?.parent?.getWorldQuaternion(dp), dp.invert();
const n = dp.multiply(t);
s.quaternion.set(n.x, n.y, n.z, n.w);
}
function ew(s, e, t, i, n) {
Pr.set(e, t, i, n), ns(s, Pr);
}
const VP = new rn(() => new v(), 100), HP = new v();
function Ke(s, e = null) {
return e || (e = VP.get()), s ? s.parent ? (s.getWorldScale(e), e) : e.copy(s.scale) : e.set(0, 0, 0);
}
function Wc(s, e) {
if (!s) return;
if (!s.parent) {
s.scale.copy(e);
return;
}
const t = HP;
s.parent.getWorldScale(t), s.scale.copy(e), s.scale.divide(t);
}
const GP = new v(), nb = new U();
function nj(s) {
return xe(s, nb), GP.set(0, 0, 1).applyQuaternion(nb);
}
const qP = new rn(() => new v(), 100), sb = new U();
function XP(s, e) {
return e || (e = qP.get().set(0, 0, 1)), xe(s, sb), e.applyQuaternion(sb);
}
const ob = new Ge(), rb = new Ge(), QP = new v();
function tw(s) {
const e = pu.get();
return s.getWorldQuaternion(e), rb.setFromQuaternion(e), rb;
}
function iw(s, e) {
const t = pu.get();
ns(s, t.setFromEuler(e));
}
function iy(s) {
const e = tw(s), t = QP;
return t.set(e.x, e.y, e.z), t.x = B.toDegrees(t.x), t.y = B.toDegrees(t.y), t.z = B.toDegrees(t.z), t;
}
function YP(s, e) {
Ju(s, e.x, e.y, e.z, !0);
}
function Ju(s, e, t, i, n = !0) {
n && (e = B.toRadians(e), t = B.toRadians(t), i = B.toRadians(i)), ob.set(e, t, i), Pr.setFromEuler(ob), ns(s, Pr);
}
function Om(s, e = !0) {
s && (e ? (function t(i) {
console.groupCollapsed((i.name ? i.name : "(no name : " + i.type + ")") + " %o", i), i.children.forEach(t), console.groupEnd();
})(s) : s.traverse(function(t) {
for (var i = "|___", n = t; n.parent !== null; )
i = " " + i, n = n.parent;
console.log(i + t.name + " <" + t.type + ">");
}));
}
function sj(s) {
let e = s?.name || "";
if (!s) return e;
let t = s.parent;
for (; t; )
e = t.name + "/" + e, t = t.parent;
return e;
}
function KP(s) {
if (s) {
const e = s;
return e.blendMode !== void 0 && e.clampWhenFinished !== void 0 && e.enabled !== void 0 && e.fadeIn !== void 0 && e.getClip !== void 0;
}
return !1;
}
class mu extends ts {
static vertex = `
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = vec4(position.xy, 0., 1.0);
}`;
constructor() {
super({
vertexShader: mu.vertex,
uniforms: {
map: new tn(null),
flipY: new tn(!0),
writeDepth: new tn(!1),
depthTexture: new tn(null)
},
fragmentShader: `
uniform sampler2D map;
uniform bool flipY;
uniform bool writeDepth;
uniform sampler2D depthTexture;
varying vec2 vUv;
void main(){
vec2 uv = vUv;
if (flipY) uv.y = 1.0 - uv.y;
gl_FragColor = texture2D(map, uv);
if (writeDepth) {
float depth = texture2D(depthTexture, uv).r;
gl_FragDepth = depth;
// float linearDepth = (depth - 0.99) * 100.0; // Enhance near 1.0 values
// gl_FragColor = vec4(linearDepth, linearDepth, linearDepth, 1.0);
}
}`
});
}
reset() {
this.uniforms.map.value = null, this.uniforms.flipY.value = !0, this.uniforms.writeDepth.value = !1, this.uniforms.depthTexture.value = null, this.needsUpdate = !0, this.uniformsNeedUpdate = !0;
}
}
class Lr {
static _planeGeometry;
static _renderer;
static _perspectiveCam;
static _orthographicCam;
static _scene;
static _blitMaterial;
static _mesh;
static get planeGeometry() {
return this._planeGeometry ??= new An(2, 2, 1, 1);
}
static get renderer() {
return this._renderer ??= new Wr({ antialias: !1, alpha: !0 });
}
static get perspectiveCam() {
return this._perspectiveCam ??= new fe();
}
static get orthographicCam() {
return this._orthographicCam ??= new Vu();
}
static get scene() {
return this._scene ??= new ji();
}
static get blitMaterial() {
return this._blitMaterial ??= new mu();
}
static get mesh() {
return this._mesh ??= new H(Lr.planeGeometry, Lr.blitMaterial);
}
/**
* Copy a texture to a new texture
* @param texture the texture to copy
* @param blitMaterial the material to use for copying (optional)
* @returns the newly created, copied texture
*/
static copyTexture(e, t) {
t || (t = this.blitMaterial), this.blitMaterial.reset();
const i = t || this.blitMaterial;
i.uniforms.map.value = e, i.needsUpdate = !0, i.uniformsNeedUpdate = !0;
const n = i.vertexShader;
i.vertexShader = mu.vertex;
const o = this.mesh;
o.material = i, o.frustumCulled = !1, this.scene.children.length = 0, this.scene.add(o), this.renderer.setSize(e.image.width, e.image.height), this.renderer.clear(), this.renderer.render(this.scene, this.perspectiveCam);
const r = new Se(this.renderer.domElement);
return r.name = "Copy", r.needsUpdate = !0, i.vertexShader = n, r;
}
static blit(e, t, i) {
const {
renderer: n = this.renderer,
blitMaterial: o = this.blitMaterial,
flipY: r = !1,
depthTexture: a = null,
depthTest: l = !0,
depthWrite: c = !0
} = i || {};
this.blitMaterial.reset(), o.uniforms.map && (o.uniforms.map.value = e), o.uniforms.flipY && (o.uniforms.flipY.value = r), a ? (o.uniforms.writeDepth = new tn(!0), o.uniforms.depthTexture.value = a) : (o.uniforms.writeDepth = new tn(!1), o.uniforms.depthTexture.value = null), o.needsUpdate = !0, o.uniformsNeedUpdate = !0;
const h = this.mesh;
h.material = o, h.frustumCulled = !1, this.scene.children.length = 0, this.scene.add(h);
const d = n.getRenderTarget(), u = n.getContext();
l ? u.enable(u.DEPTH_TEST) : u.disable(u.DEPTH_TEST), n.state.buffers.depth.setMask(c), n.setClearColor(new se(0, 0, 0), 0), n.setRenderTarget(t), n.clear(), n.render(this.scene, this.perspectiveCam), n.setRenderTarget(d), u.enable(u.DEPTH_TEST), n.state.buffers.depth.setMask(!0);
}
/**
* Copy a texture to a HTMLCanvasElement
* @param texture the texture convert
* @param force if true the texture will be copied to a new texture before converting
* @returns the HTMLCanvasElement with the texture or null if the texture could not be copied
*/
static textureToCanvas(e, t = !1) {
if (!e)
return null;
(t === !0 || e.isCompressedTexture === !0) && (e = ZP(e));
const i = e.image;
if (JP(i)) {
const n = document.createElement("canvas");
n.width = i.width, n.height = i.height;
const o = n.getContext("2d");
return o ? (o.drawImage(i, 0, 0, i.width, i.height, 0, 0, n.width, n.height), n) : (console.error("Failed getting canvas 2d context"), null);
}
return null;
}
}
function ZP(s) {
return Lr.copyTexture(s);
}
function oj(s, e = !1) {
return Lr.textureToCanvas(s, e);
}
function JP(s) {
return typeof HTMLImageElement < "u" && s instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && s instanceof HTMLCanvasElement || typeof OffscreenCanvas < "u" && s instanceof OffscreenCanvas || typeof ImageBitmap < "u" && s instanceof ImageBitmap;
}
function ek(s) {
const e = s.type;
return e === "Mesh" || e === "SkinnedMesh";
}
function nw(s, e) {
e ? s["needle:rendercustomshadow"] = !0 : s["needle:rendercustomshadow"] = !1;
}
function tk(s) {
if (s) {
if (s["needle:rendercustomshadow"] === !0)
return !0;
if (s["needle:rendercustomshadow"] == null)
return !0;
}
return !1;
}
function Fi(s, e = void 0, t = void 0, i = void 0) {
const n = i || new si();
n.makeEmpty();
const o = [];
function r(l) {
let c = !0;
if (l.visible && DP(l) !== !1 && !(l.type === "TransformControlsGizmo" || l.type === "TransformControlsPlane")) {
if (e) {
if (Array.isArray(e)) {
if (e.includes(l)) return;
} else if (typeof e == "function" && e(l) === !0)
return;
}
if (l instanceof gC && (c = !1), l instanceof O0 && (c = !1), l instanceof Ga && (c = !1), l.isGizmo === !0 && (c = !1), l.material instanceof k0 && (c = !1), ek(l) || (c = !1), t && l.layers.test(t) === !1 && (c = !1), l.isUI !== !0) {
if (c) {
const h = l.children;
l.children = o;
const d = l.position, u = l.scale;
if (Number.isNaN(d.x) || Number.isNaN(d.y) || Number.isNaN(d.z)) {
console.warn(`Object "${l.name}" has NaN values in position or scale.... will ignore it`, d, u);
return;
}
l.geometry === null && (l.geometry = void 0), n.expandByObject(l, !0), l.children = h;
}
for (const h of l.children)
r(h);
}
}
}
let a = !1;
Array.isArray(s) || (s = [s]);
for (const l of s)
l && (a = !0, l.updateMatrixWorld(), r(l));
return a || console.warn("No objects to fit camera to..."), n;
}
function ik(s, e, t) {
const i = Fi([s], t?.ignore), n = new v();
i.getSize(n);
const o = new v();
i.getCenter(o);
const r = new v();
e.getSize(r);
const a = new v();
e.getCenter(a);
const l = new v();
l.set(r.x / n.x, r.y / n.y, r.z / n.z);
const c = Math.min(l.x, l.y, l.z), h = t?.scale !== !1;
if (h && Wc(s, Ke(s).multiplyScalar(c)), t?.position !== !1) {
const d = new v();
i.getCenter(d